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 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://npmjs.com/package/typescript), [`@babel/parser`](https://npmjs.com/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.
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://npmjs.com/package/rolldown-plugin-require-cjs
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 { resolvePathSync } from "mlly";
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, builtinNodeModules } = resolveOptions(userOptions);
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 { body } = parseAst(code, { lang: void 0 }, fileName);
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 (!(isBuiltinModule || (await shouldTransform?.(source, importer) ?? await isPureCJS(source, importer)))) continue;
67
+ if (!(await shouldTransform?.(source, importer) ?? await isPureCJS(source, importer))) continue;
72
68
  if (stmt.specifiers.length === 0) {
73
- if (isBuiltinModule) s.removeNode(stmt);
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
- let requireCode;
89
- if (isBuiltinModule) requireCode = source === "process" || source === "node:process" ? "globalThis.process" : `globalThis.process.getBuiltinModule(${JSON.stringify(source)})`;
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 = builtinNodeModules ? `const ${REQUIRE} = globalThis.process.getBuiltinModule("module").createRequire(import.meta.url);\n` : `import { createRequire as __cjs_createRequire } from "node:module";
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.startsWith("node:")) return false;
108
+ if (isBuiltin(id)) return false;
117
109
  try {
118
- const importResolved = resolvePathSync(id, { url: importer });
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$1) {
139
- const contents = await readFile(path$1, "utf8");
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
- "author": "Kevin Deng <sxzz@sxzz.moe>",
16
- "funding": "https://github.com/sponsors/sxzz",
17
- "files": [
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.1.1",
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.28.5",
42
- "@sxzz/eslint-config": "^7.4.0",
43
- "@sxzz/prettier-config": "^2.2.6",
44
- "@sxzz/test-utils": "^0.5.13",
45
- "@types/node": "^24.10.1",
46
- "bumpp": "^10.3.2",
47
- "eslint": "^9.39.1",
48
- "eslint-plugin-vue": "^10.6.2",
49
- "prettier": "^3.7.1",
50
- "rolldown": "1.0.0-beta.52",
51
- "tsdown": "^0.16.8",
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.14"
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": "tsc --noEmit",
69
+ "typecheck": "tsgo --noEmit",
70
70
  "format": "prettier --cache --write .",
71
71
  "release": "bumpp"
72
72
  }