You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+21-7Lines changed: 21 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,14 +11,16 @@ Node.js utility for transforming a JavaScript or TypeScript file from an ES modu
11
11
12
12
Highlights
13
13
14
+
- ESM ➡️ CJS and CJS ➡️ ESM with one function call.
14
15
- Defaults to safe CommonJS output: strict live bindings, import.meta shims, and specifier preservation.
15
-
- Opt into stricter/looser behaviors: live binding enforcement, import.meta.main gating, and top-level await strategies.
16
-
- Can optionally rewrite relative specifiers and write transformed output to disk.
16
+
- Configurable lowering modes: full syntax transforms or globals-only.
17
+
- Specifier tools: add extensions, add directory indexes, or map with a custom callback.
18
+
- Output control: write to disk (`out`/`inPlace`) or return the transformed string.
17
19
18
20
> [!IMPORTANT]
19
21
> All parsing logic is applied under the assumption the code is in [strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode) which [modules run under by default](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#other_differences_between_modules_and_classic_scripts).
20
22
21
-
By default `@knighted/module` transforms the one-to-one [differences between ES modules and CommonJS](https://nodejs.org/api/esm.html#differences-between-es-modules-and-commonjs). Options let you control syntax rewriting, specifier updates, and output.
23
+
By default `@knighted/module` transforms the one-to-one [differences between ES modules and CommonJS](https://nodejs.org/api/esm.html#differences-between-es-modules-and-commonjs). Options let you control syntax rewriting (full vs globals-only), specifier updates, and output.
22
24
23
25
## Requirements
24
26
@@ -30,9 +32,9 @@ By default `@knighted/module` transforms the one-to-one [differences between ES
30
32
npm install @knighted/module
31
33
```
32
34
33
-
## Example
35
+
## Quick examples
34
36
35
-
Given an ES module:
37
+
ESM ➡️ CJS:
36
38
37
39
**file.js**
38
40
@@ -93,6 +95,17 @@ use@computer: $ node file.cjs
93
95
invoked directly by node
94
96
```
95
97
98
+
CJS ➡️ ESM:
99
+
100
+
```js
101
+
import { transform } from'@knighted/module'
102
+
103
+
awaittransform('./file.cjs', {
104
+
target:'module',
105
+
out:'./file.mjs',
106
+
})
107
+
```
108
+
96
109
## Options
97
110
98
111
```ts
@@ -124,20 +137,21 @@ type ModuleOptions = {
124
137
}
125
138
```
126
139
127
-
Behavior notes (defaults in parentheses)
140
+
### Behavior notes (defaults in parentheses)
128
141
129
142
- `target` (`commonjs`): output module system.
130
143
- `transformSyntax` (true): enable/disable the ESM↔CJS lowering pass; set to `'globals-only'` to rewrite module globals (`import.meta.*`, `__dirname`, `__filename`, `require.main` shims) while leaving import/export syntax untouched. In `'globals-only'`, no helpers are injected (e.g., `__requireResolve`), `require.resolve` rewrites to `import.meta.resolve`, and `idiomaticExports` is skipped. See [globals-only](#globals-only-scope).
131
144
- `liveBindings` (`strict`): getter-based live bindings, or snapshot (`loose`/`off`).
132
145
- `appendJsExtension` (`relative-only` when targeting ESM): append `.js` to relative specifiers; never touches bare specifiers.
133
146
- `appendDirectoryIndex` (`index.js`): when a relative specifier ends with a slash, append this index filename (set `false` to disable).
147
+
- `appenders` precedence: `rewriteSpecifier` runs first; if it returns a string, that result is used. If it returns `undefined` or `null`, `appendJsExtension` and `appendDirectoryIndex` still run. Bare specifiers are never modified by appenders.
134
148
- `dirFilename` (`inject`): inject `__dirname`/`__filename`, preserve existing, or throw.
135
149
- `importMeta` (`shim`): rewrite `import.meta.*` to CommonJS equivalents.
136
150
- `importMetaMain` (`shim`): gate `import.meta.main` with shimming/warning/error when Node support is too old.
137
151
- `requireMainStrategy` (`import-meta-main`): use `import.meta.main` or the realpath-based `pathToFileURL(realpathSync(process.argv[1])).href` check.
- `topLevelAwait` (`error`): throw, wrap, or preserve when TLA appears in CommonJS output.
140
-
- `rewriteSpecifier` (off): rewrite relative specifiers to a chosen extension or via a callback.
154
+
- `rewriteSpecifier` (off): rewrite relative specifiers to a chosen extension or via a callback. Precedence: the callback (if provided) runs first; if it returns a string, that wins. If it returns `undefined` or `null`, the appenders still apply.
141
155
- `requireSource` (`builtin`): whether `require` comes from Node or `createRequire`.
142
156
- `cjsDefault` (`auto`): bundler-style default interop vs direct `module.exports`.
143
157
- `out`/`inPlace`: write the transformed code to a file; otherwise the function returns the transformed string only.
Copy file name to clipboardExpand all lines: src/types.ts
+2-1Lines changed: 2 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -38,7 +38,8 @@ export type ModuleOptions = {
38
38
appendJsExtension?: 'off'|'relative-only'|'all'
39
39
/** Add directory index (e.g. /index.js) or disable. */
40
40
appendDirectoryIndex?: string|false
41
-
/** Control __dirname and __filename handling. */
41
+
/** Precedence: rewriteSpecifier runs first; if it returns a string that wins. If it returns undefined or null, appenders apply. Bare specifiers are never modified by appenders. */
42
+
/** Control __dirname/__filename handling (inject shims, preserve existing, or throw on use). */
0 commit comments