apex-dev-tools / apex-dev-tools/benchmarker

Migrate package to ESM (dual build), following apex-parser

Ouverte
#95 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
Langage dominant
TypeScript
Étoiles
5
Forks
10
Merge moyen
3 h 23 min
PR mergées (30 j)
3

Description

## Problem

`benchmarker` is published as CommonJS, and a growing part of its dependency tree has gone ESM-only. This is no longer a per-dependency annoyance — it is now blocking security and version updates outright.

Currently blocked Dependabot PRs, both failing for the same underlying reason:

- **#89 — chai stack.** The locked versions all declare `"type": "module"`: chai 6.2.2, chai-as-promised 8.0.2, sinon-chai 4.0.1. `npm run build` fails with widespread **TS1479** — CommonJS test files cannot statically import ESM-only packages. Compilation fails before any test runs.
- **#91 — puppeteer 22 → 25.** v23 and v24 are actually clean against this codebase. **v25** is ESM-only, and additionally raises Puppeteer's minimum Node to 22 while this package declares `"node": ">20.0.0"`. There is also an API rename to absorb: `PuppeteerNodeLaunchOptions` (imported by `src/shared/env.ts`) is now `LaunchOptions`.

Until this is resolved, both PRs are unmergeable and the repo stays pinned on older majors.

## Current state

```
package.json no "type" field → CommonJS
main dist/src/index.js
types dist/types/src/index.d.ts
exports "." and "./database", single "default" condition, no import/require split
engines node >20.0.0
tsconfig module: node16, target: es2020, outDir: ./dist
build tsc only (no bundler)
```

Worth noting the setup is already *partly* hybrid and inconsistent:

- `npm test` runs with `NODE_OPTIONS='--loader ts-node/esm --experimental-specifier-resolution=node'`
- `.mocharc.yml` requires `ts-node/register` (the CommonJS loader)
- `npm run test:system` uses neither

So the test path already has one foot in ESM while the package contract is CommonJS.

## Prior art: apex-parser

[`apex-parser`](https://github.com/apex-dev-tools/apex-parser) has already been through this and is the reference implementation. It went **dual-build rather than ESM-only**, so existing CommonJS consumers kept working.

Its `npm/package.json` now looks like:

```jsonc
{
"type": "module",
"main": "./dist/cjs/index.cjs",
"module": "./dist/esm/index.js",
"types": "./dist/types/index.d.ts",
"exports": {
".": {
"browser": { "types": "...", "default": "./dist/browser/apex-parser.mjs" },
"import": { "types": "./dist/types/index.d.ts", "default": "./dist/esm/index.js" },
"require": { "types": "./dist/types/index.d.cts", "default": "./dist/cjs/index.cjs" }
}
}
}
```

Dual output is produced by Rollup (`npm/rollup.config.js`) emitting both `format: "es"` → `dist/esm/*.js` and `format: "cjs"` → `dist/cjs/*.cjs` with `preserveModules: true`, plus separate `.d.ts` / `.d.cts` type outputs per condition.

Useful commits to follow:

- `ed23f8b` — update inner npm package for ESM and exports
- `802347a` — update src to ES modules, fix strict type errors (PR #79)
- `f375e4f` — add CJS and browser builds via Rollup
- `06949ca` — use dynamic `import()` in the check script for ESM compatibility (PR #106)

That last one is the pattern for reaching an ESM-only dependency from a CommonJS context, which is directly relevant to the Puppeteer situation.

## Scope

- Add `"type": "module"`; decide dual-build vs ESM-only (dual recommended, per apex-parser)
- Introduce a bundler for dual output, or an equivalent two-pass `tsc` setup
- Rework `exports` with proper `import` / `require` conditions and matching `.d.ts` / `.d.cts`
- Review `module` / `moduleResolution` in `tsconfig.json`
- Audit imports for explicit file extensions and CommonJS assumptions (`__dirname`, `require`, `module.exports`)
- Reconcile the test setup: `.mocharc.yml` `ts-node/register` vs the `ts-node/esm` loader in `npm test`, plus nyc
- Decide whether to raise `engines.node` to `>=22` (required if Puppeteer 25 becomes a production dependency)
- Check downstream consumers — this is a **package-level breaking change** to the published contract

## Related

- #89 — recommend closing and pinning the CommonJS stack (chai 4.x, chai-as-promised 7.x, sinon-chai 3.x) until this lands
- #91 — a separate PR will take Puppeteer to **v24**, which is the highest version compatible with CommonJS. v25 is deferred to this work.

Guide de contribution

Aucun guide de contribution indexé pour ce dépôt

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.