@knighted/duel 3.2.5 → 4.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,6 +6,9 @@
6
6
 
7
7
  Tool for building a Node.js [dual package](https://nodejs.org/api/packages.html#dual-commonjses-module-packages) with TypeScript. Supports CommonJS and ES module projects.
8
8
 
9
+ > [!NOTE]
10
+ > I wish this tool were unnecessary, but dual emit was declared out of scope by the TypeScript team, so `duel` exists to fill that gap.
11
+
9
12
  ## Features
10
13
 
11
14
  - Bidirectional ESM ↔️ CJS dual builds inferred from the package.json `type`.
@@ -60,8 +63,8 @@ It should work similarly for a CJS-first project. Except, your package.json file
60
63
  > [!IMPORTANT]
61
64
  > This works best if your CJS-first project uses file extensions in _relative_ specifiers. That is acceptable in CJS and [required in ESM](https://nodejs.org/api/esm.html#import-specifiers). `duel` does not rewrite bare specifiers or remap relative specifiers to directory indexes.
62
65
 
63
- > [!NOTE]
64
- > While `duel` runs it briefly swaps in a temporary package.json with the needed `type`; your original file is restored when the build finishes.
66
+ > [!TIP]
67
+ > `duel` creates a hash-named temp workspace (`_duel_<hash>_`) alongside your project during a build. It is automatically removed on success/failure unless `DUEL_KEEP_TEMP=1` is set. If one is ever left behind (e.g., abrupt kill), it is safe to delete.
65
68
 
66
69
  ### Build orientation
67
70
 
@@ -103,6 +106,15 @@ Assuming an `outDir` of `dist`, running the above will create `dist/esm` and `di
103
106
 
104
107
  When `--mode` is enabled, `duel` copies sources and runs [`@knighted/module`](https://github.com/knightedcodemonkey/module) **before** `tsc`, so TypeScript sees already-mitigated sources. That pre-`tsc` step is globals-only for `--mode globals` and full lowering for `--mode full`.
105
108
 
109
+ ### Dual package hazards
110
+
111
+ Mixed `import`/`require` of the same dual package (especially when conditional exports differ) can create two module instances. `duel` exposes the detector from `@knighted/module`:
112
+
113
+ - `--detect-dual-package-hazard [off|warn|error]` (default `warn`): emit diagnostics; `error` exits non-zero.
114
+ - `--dual-package-hazard-scope [file|project]` (default `file`): per-file checks or a project-wide pre-pass that aggregates package usage across all compiled sources before building.
115
+
116
+ Project scope is helpful in monorepos or hoisted installs where hazards surface only when looking across files.
117
+
106
118
  ## Options
107
119
 
108
120
  The available options are limited, because you should define most of them inside your project's `tsconfig.json` file.
@@ -112,6 +124,15 @@ The available options are limited, because you should define most of them inside
112
124
  - `--mode` Optional shorthand for the module transform mode: `none` (default), `globals` (globals-only), `full` (globals + full syntax lowering).
113
125
  - `--dirs, -d` Outputs both builds to directories inside of `outDir`. Defaults to `false`.
114
126
  - `--exports, -e` Generate `package.json` `exports` from build output. Values: `wildcard` | `dir` | `name`.
127
+ - `--exports-config` Provide a JSON file with `{ "entries": ["./dist/index.js", ...], "main": "./dist/index.js" }` to limit which outputs become exports.
128
+ - `--exports-validate` Dry-run exports generation/validation without writing package.json; combine with `--exports` or `--exports-config` to emit after validation.
129
+ - `--rewrite-policy [safe|warn|skip]` Control how specifier rewrites behave when a matching target is missing (`safe` warns and skips, `warn` rewrites and warns, `skip` leaves specifiers untouched).
130
+ - `--validate-specifiers` Validate that rewritten specifiers resolve to outputs; defaults to `true` when `--rewrite-policy` is `safe`.
131
+ - `--detect-dual-package-hazard [off|warn|error]` Flag mixed import/require usage of dual packages; `error` exits non-zero.
132
+ - `--dual-package-hazard-scope [file|project]` Run hazard checks per file (default) or aggregate across the project.
133
+ - `--copy-mode [sources|full]` Temp copy strategy. `sources` (default) copies only files participating in the build (plus configs); `full` mirrors the previous whole-project copy.
134
+ - `--verbose, -V` Verbose logging.
135
+ - `--help, -h` Print the help text.
115
136
 
116
137
  > [!NOTE]
117
138
  > Exports keys are extensionless by design; the target `import`/`require`/`types` entries keep explicit file extensions so Node resolution remains deterministic.