rolldown-plugin-require-cjs 0.3.2 → 0.4.0
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 +3 -10
- package/dist/index.d.mts +0 -7
- package/dist/index.mjs +20 -27
- package/package.json +31 -31
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ Transform ESM imports to CJS requires when the imported module is pure CJS.
|
|
|
8
8
|
|
|
9
9
|
## Why?
|
|
10
10
|
|
|
11
|
-
Some packages only provide CJS builds (e.g., [`typescript`](https://
|
|
11
|
+
Some packages only provide CJS builds (e.g., [`typescript`](https://npmx.dev/package/typescript), [`@babel/parser`](https://npmx.dev/package/@babel/parser)), and importing them using ESM syntax increases Node's `cjs-module-lexer` overhead. This plugin converts ESM imports to CJS requires for such pure CJS packages, allowing Node to skip the cjs-module-lexer step and improve performance.
|
|
12
12
|
|
|
13
13
|
If performance is insignificant for your project, please do not use this plugin, as it introduces additional complexity and maintenance overhead.
|
|
14
14
|
|
|
@@ -21,7 +21,7 @@ We encourage the JavaScript ecosystem to continue its transition toward ESM. If
|
|
|
21
21
|
## Install
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
-
npm i rolldown-plugin-require-cjs
|
|
24
|
+
npm i -D rolldown-plugin-require-cjs
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
## Options
|
|
@@ -37,13 +37,6 @@ export interface Options {
|
|
|
37
37
|
* or `undefined` to let the plugin decide automatically.
|
|
38
38
|
*/
|
|
39
39
|
shouldTransform?: string[] | TransformFn
|
|
40
|
-
/**
|
|
41
|
-
* Whether to transform Node.js built-in modules (e.g., `fs`, `path`)
|
|
42
|
-
* to `process.getBuiltinModule()` calls, which has the best performance.
|
|
43
|
-
*
|
|
44
|
-
* Note: `process.getBuiltinModule` is available since Node.js 20.16.0 and 22.3.0.
|
|
45
|
-
*/
|
|
46
|
-
builtinNodeModules?: boolean
|
|
47
40
|
}
|
|
48
41
|
|
|
49
42
|
/**
|
|
@@ -92,7 +85,7 @@ RequireCJS({
|
|
|
92
85
|
<!-- Badges -->
|
|
93
86
|
|
|
94
87
|
[npm-version-src]: https://img.shields.io/npm/v/rolldown-plugin-require-cjs.svg
|
|
95
|
-
[npm-version-href]: https://
|
|
88
|
+
[npm-version-href]: https://npmx.dev/package/rolldown-plugin-require-cjs
|
|
96
89
|
[npm-downloads-src]: https://img.shields.io/npm/dm/rolldown-plugin-require-cjs
|
|
97
90
|
[npm-downloads-href]: https://www.npmcharts.com/compare/rolldown-plugin-require-cjs?interval=30
|
|
98
91
|
[unit-test-src]: https://github.com/sxzz/rolldown-plugin-require-cjs/actions/workflows/unit-test.yml/badge.svg
|
package/dist/index.d.mts
CHANGED
|
@@ -18,13 +18,6 @@ interface Options {
|
|
|
18
18
|
* or `undefined` to let the plugin decide automatically.
|
|
19
19
|
*/
|
|
20
20
|
shouldTransform?: string[] | TransformFn;
|
|
21
|
-
/**
|
|
22
|
-
* Whether to transform Node.js built-in modules (e.g., `fs`, `path`)
|
|
23
|
-
* to `process.getBuiltinModule()` calls, which has the best performance.
|
|
24
|
-
*
|
|
25
|
-
* Note: `process.getBuiltinModule` is available since Node.js 20.16.0 and 22.3.0.
|
|
26
|
-
*/
|
|
27
|
-
builtinNodeModules?: boolean;
|
|
28
21
|
}
|
|
29
22
|
type Overwrite<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U;
|
|
30
23
|
type OptionsResolved = Overwrite<Required<Options>, Pick<Options, "order"> & {
|
package/dist/index.mjs
CHANGED
|
@@ -2,16 +2,15 @@ import { createRequire, isBuiltin } from "node:module";
|
|
|
2
2
|
import { readFile } from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import process from "node:process";
|
|
5
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5
6
|
import { init, parse } from "cjs-module-lexer";
|
|
6
7
|
import { up } from "empathic/package";
|
|
8
|
+
import { resolve } from "import-meta-resolve";
|
|
7
9
|
import { MagicStringAST, generateTransform } from "magic-string-ast";
|
|
8
|
-
import {
|
|
9
|
-
import { parseAst } from "rolldown/parseAst";
|
|
10
|
+
import { parseSync } from "rolldown/utils";
|
|
10
11
|
import { createFilter } from "unplugin-utils";
|
|
11
|
-
|
|
12
|
-
//#region rolldown:runtime
|
|
12
|
+
//#region \0rolldown/runtime.js
|
|
13
13
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
14
|
-
|
|
15
14
|
//#endregion
|
|
16
15
|
//#region src/options.ts
|
|
17
16
|
function resolveOptions(options) {
|
|
@@ -23,17 +22,15 @@ function resolveOptions(options) {
|
|
|
23
22
|
include: options.include || [/\.m?[jt]sx?$/],
|
|
24
23
|
exclude: options.exclude || [/node_modules/, /\.d\.[cm]?ts$/],
|
|
25
24
|
order: "order" in options ? options.order : "pre",
|
|
26
|
-
shouldTransform: options.shouldTransform
|
|
27
|
-
builtinNodeModules: !!options.builtinNodeModules
|
|
25
|
+
shouldTransform: options.shouldTransform
|
|
28
26
|
};
|
|
29
27
|
}
|
|
30
|
-
|
|
31
28
|
//#endregion
|
|
32
29
|
//#region src/index.ts
|
|
33
30
|
let initted = false;
|
|
34
31
|
const REQUIRE = `__cjs_require`;
|
|
35
32
|
function RequireCJS(userOptions = {}) {
|
|
36
|
-
const { include, exclude, order, shouldTransform
|
|
33
|
+
const { include, exclude, order, shouldTransform } = resolveOptions(userOptions);
|
|
37
34
|
const filter = createFilter(include, exclude);
|
|
38
35
|
let cwd;
|
|
39
36
|
return {
|
|
@@ -59,18 +56,17 @@ function RequireCJS(userOptions = {}) {
|
|
|
59
56
|
order,
|
|
60
57
|
async handler(code, { fileName }, { file, dir }) {
|
|
61
58
|
if (!filter(fileName)) return;
|
|
62
|
-
const {
|
|
59
|
+
const { program } = parseSync(fileName, code);
|
|
63
60
|
const s = new MagicStringAST(code);
|
|
64
61
|
let usingRequire = false;
|
|
65
|
-
for (const stmt of body) if (stmt.type === "ImportDeclaration") {
|
|
62
|
+
for (const stmt of program.body) if (stmt.type === "ImportDeclaration") {
|
|
66
63
|
if (stmt.importKind === "type") continue;
|
|
67
64
|
const source = stmt.source.value;
|
|
68
|
-
const isBuiltinModule = builtinNodeModules && isBuiltin(source);
|
|
69
65
|
const distFilename = file || (dir ? path.join(dir, fileName) : fileName);
|
|
70
66
|
const importer = cwd ? path.resolve(cwd, distFilename) : distFilename;
|
|
71
|
-
if (!(
|
|
67
|
+
if (!(await shouldTransform?.(source, importer) ?? await isPureCJS(source, importer))) continue;
|
|
72
68
|
if (stmt.specifiers.length === 0) {
|
|
73
|
-
if (
|
|
69
|
+
if (isBuiltin(source)) s.removeNode(stmt);
|
|
74
70
|
else {
|
|
75
71
|
s.overwriteNode(stmt, `${REQUIRE}(${JSON.stringify(source)});`);
|
|
76
72
|
usingRequire = true;
|
|
@@ -85,12 +81,8 @@ function RequireCJS(userOptions = {}) {
|
|
|
85
81
|
if (specifier.importKind === "type") continue;
|
|
86
82
|
mapping.push([s.sliceNode(specifier.imported), specifier.local.name]);
|
|
87
83
|
} else defaultId = specifier.local.name;
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
else {
|
|
91
|
-
requireCode = `__cjs_require(${JSON.stringify(source)})`;
|
|
92
|
-
usingRequire = true;
|
|
93
|
-
}
|
|
84
|
+
const requireCode = `__cjs_require(${JSON.stringify(source)})`;
|
|
85
|
+
usingRequire = true;
|
|
94
86
|
const codes = [];
|
|
95
87
|
if (namespaceId) defaultId ||= `_cjs_${namespaceId}_default`;
|
|
96
88
|
if (defaultId) codes.push(`const ${defaultId} = ${requireCode};`);
|
|
@@ -99,7 +91,7 @@ function RequireCJS(userOptions = {}) {
|
|
|
99
91
|
s.overwriteNode(stmt, codes.join("\n"));
|
|
100
92
|
}
|
|
101
93
|
if (usingRequire) {
|
|
102
|
-
const preamble =
|
|
94
|
+
const preamble = `import { createRequire as __cjs_createRequire } from "node:module";
|
|
103
95
|
const ${REQUIRE} = __cjs_createRequire(import.meta.url);\n`;
|
|
104
96
|
if (code[0] === "#") {
|
|
105
97
|
const firstNewLineIndex = code.indexOf("\n") + 1;
|
|
@@ -113,9 +105,11 @@ const ${REQUIRE} = __cjs_createRequire(import.meta.url);\n`;
|
|
|
113
105
|
}
|
|
114
106
|
async function isPureCJS(id, importer) {
|
|
115
107
|
if (!initted) await init();
|
|
116
|
-
if (id
|
|
108
|
+
if (isBuiltin(id)) return false;
|
|
117
109
|
try {
|
|
118
|
-
|
|
110
|
+
let importResolved = resolve(id, pathToFileURL(importer).href);
|
|
111
|
+
if (!importResolved.startsWith("file://")) return false;
|
|
112
|
+
importResolved = fileURLToPath(importResolved);
|
|
119
113
|
const requireResolved = __require.resolve(id, { paths: [importer] });
|
|
120
114
|
if (path.resolve(importResolved) !== path.resolve(requireResolved)) return false;
|
|
121
115
|
if (importResolved.endsWith(".cjs")) return true;
|
|
@@ -135,12 +129,11 @@ async function isPureCJS(id, importer) {
|
|
|
135
129
|
} catch {}
|
|
136
130
|
return false;
|
|
137
131
|
}
|
|
138
|
-
async function getPackageType(path
|
|
139
|
-
const contents = await readFile(path
|
|
132
|
+
async function getPackageType(path) {
|
|
133
|
+
const contents = await readFile(path, "utf8");
|
|
140
134
|
try {
|
|
141
135
|
return JSON.parse(contents).type;
|
|
142
136
|
} catch {}
|
|
143
137
|
}
|
|
144
|
-
|
|
145
138
|
//#endregion
|
|
146
|
-
export { RequireCJS, isPureCJS, resolveOptions };
|
|
139
|
+
export { RequireCJS, isPureCJS, resolveOptions };
|
package/package.json
CHANGED
|
@@ -1,59 +1,59 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rolldown-plugin-require-cjs",
|
|
3
|
-
"version": "0.3.2",
|
|
4
|
-
"description": "Transform ESM imports to CJS requires when the imported module is pure CJS.",
|
|
5
3
|
"type": "module",
|
|
4
|
+
"version": "0.4.0",
|
|
5
|
+
"description": "Transform ESM imports to CJS requires when the imported module is pure CJS.",
|
|
6
|
+
"author": "Kevin Deng <sxzz@sxzz.moe>",
|
|
6
7
|
"license": "MIT",
|
|
8
|
+
"funding": "https://github.com/sponsors/sxzz",
|
|
7
9
|
"homepage": "https://github.com/sxzz/rolldown-plugin-require-cjs#readme",
|
|
8
|
-
"bugs": {
|
|
9
|
-
"url": "https://github.com/sxzz/rolldown-plugin-require-cjs/issues"
|
|
10
|
-
},
|
|
11
10
|
"repository": {
|
|
12
11
|
"type": "git",
|
|
13
12
|
"url": "git+https://github.com/sxzz/rolldown-plugin-require-cjs.git"
|
|
14
13
|
},
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"dist"
|
|
19
|
-
],
|
|
20
|
-
"main": "./dist/index.mjs",
|
|
21
|
-
"module": "./dist/index.mjs",
|
|
22
|
-
"types": "./dist/index.d.mts",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/sxzz/rolldown-plugin-require-cjs/issues"
|
|
16
|
+
},
|
|
23
17
|
"exports": {
|
|
24
18
|
".": "./dist/index.mjs",
|
|
25
19
|
"./package.json": "./package.json"
|
|
26
20
|
},
|
|
21
|
+
"types": "./dist/index.d.mts",
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
27
25
|
"publishConfig": {
|
|
28
26
|
"access": "public"
|
|
29
27
|
},
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=20.19.0"
|
|
30
|
+
},
|
|
30
31
|
"peerDependencies": {
|
|
31
32
|
"rolldown": "*"
|
|
32
33
|
},
|
|
33
34
|
"dependencies": {
|
|
34
|
-
"cjs-module-lexer": "^2.
|
|
35
|
+
"cjs-module-lexer": "^2.2.0",
|
|
35
36
|
"empathic": "^2.0.0",
|
|
37
|
+
"import-meta-resolve": "^4.2.0",
|
|
36
38
|
"magic-string-ast": "^1.0.3",
|
|
37
|
-
"mlly": "^1.8.0",
|
|
38
39
|
"unplugin-utils": "^0.3.1"
|
|
39
40
|
},
|
|
40
41
|
"devDependencies": {
|
|
41
|
-
"@babel/parser": "^7.
|
|
42
|
-
"@sxzz/eslint-config": "^7.
|
|
43
|
-
"@sxzz/prettier-config": "^2.
|
|
44
|
-
"@sxzz/test-utils": "^0.5.
|
|
45
|
-
"@types/node": "^
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"eslint
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
42
|
+
"@babel/parser": "^7.29.0",
|
|
43
|
+
"@sxzz/eslint-config": "^7.8.3",
|
|
44
|
+
"@sxzz/prettier-config": "^2.3.1",
|
|
45
|
+
"@sxzz/test-utils": "^0.5.15",
|
|
46
|
+
"@types/node": "^25.4.0",
|
|
47
|
+
"@typescript/native-preview": "7.0.0-dev.20260311.1",
|
|
48
|
+
"bumpp": "^10.4.1",
|
|
49
|
+
"eslint": "^10.0.3",
|
|
50
|
+
"eslint-plugin-vue": "^10.8.0",
|
|
51
|
+
"prettier": "^3.8.1",
|
|
52
|
+
"rolldown": "1.0.0-rc.9",
|
|
53
|
+
"tsdown": "^0.21.1",
|
|
54
|
+
"tsdown-preset-sxzz": "^0.4.1",
|
|
52
55
|
"typescript": "^5.9.3",
|
|
53
|
-
"vitest": "^4.0.
|
|
54
|
-
},
|
|
55
|
-
"engines": {
|
|
56
|
-
"node": ">=20.19.0"
|
|
56
|
+
"vitest": "^4.0.18"
|
|
57
57
|
},
|
|
58
58
|
"prettier": "@sxzz/prettier-config",
|
|
59
59
|
"tsdown": {
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"build": "tsdown",
|
|
67
67
|
"dev": "tsdown --watch",
|
|
68
68
|
"test": "vitest",
|
|
69
|
-
"typecheck": "
|
|
69
|
+
"typecheck": "tsgo --noEmit",
|
|
70
70
|
"format": "prettier --cache --write .",
|
|
71
71
|
"release": "bumpp"
|
|
72
72
|
}
|