Skip to content

Commit 2f6f10c

Browse files
committed
esm-proxy-for-cjs-react
1 parent 1bb7f19 commit 2f6f10c

File tree

3 files changed

+165
-54
lines changed

3 files changed

+165
-54
lines changed

apps/1000/rolldown.config.mjs

Lines changed: 108 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,115 @@
11
import { defineConfig } from "rolldown";
22
import { minify } from "rollup-plugin-esbuild";
3+
import * as cjsLexer from "cjs-module-lexer";
4+
import esbuild from "esbuild";
5+
cjsLexer.initSync();
36
const sourceMap = !!process.env.SOURCE_MAP;
47
const m = !!process.env.MINIFY;
58

9+
10+
['react', 'react/jsx']
11+
12+
13+
// import base64Msg from 'data:text/javascript;base64, ZXhwb3J0IGRlZmF1bHQgJ2hpJw==';
14+
/**
15+
*
16+
* @param {string[]} pkgs
17+
*/
18+
function cjsToEsm(pkgs) {
19+
let idCount = 0;
20+
let idCountToCode = {};
21+
/**
22+
* @type {import("rolldown").Plugin}
23+
*/
24+
const reactShims = {
25+
name: "cjs-to-esm",
26+
resolveId(id) {
27+
if (idCountToCode[id]) {
28+
return id;
29+
}
30+
},
31+
load(id) {
32+
if (idCountToCode[id]) {
33+
return idCountToCode[id];
34+
}
35+
},
36+
async transform(rawCode, id) {
37+
const ids = [
38+
"react/index.js",
39+
"react.production.min.js",
40+
"cjs/react.development.js",
41+
"react/jsx-runtime.js",
42+
"react-jsx-runtime.development.js",
43+
"cjs/react-jsx-runtime.production.min.js",
44+
];
45+
46+
const isCjs = ids.some((eachId) => id.includes(eachId));
47+
// ideally this should be a check for package name that uses passed to plugin
48+
// Eg: if module.packageJson.name == "react" ...
49+
if (isCjs) {
50+
const code = (await esbuild.transform(rawCode, {
51+
define: { "process.env.NODE_ENV": JSON.stringify("production") },
52+
minifySyntax: true,
53+
})).code;
54+
const exports = cjsLexer.parse(code);
55+
console.log(exports);
56+
if (exports.reexports.length === 0 && exports.exports.length > 0) {
57+
console.log(exports);
58+
const newId = `cjs-to-esm:${idCount}`;
59+
const importReact = `import React from '${newId}'`;
60+
idCountToCode[newId] = code;
61+
idCount += 1;
62+
63+
const exportsStr = exports.exports
64+
.map(
65+
(exportName) =>
66+
`export const ${exportName} = React.${exportName};`
67+
)
68+
.join("\n");
69+
const exportDefault = `export default React;`;
70+
71+
return [importReact, exportsStr, exportDefault].join("\n");
72+
} else if (
73+
exports.reexports.length === 1 &&
74+
exports.exports.length === 0
75+
) {
76+
const dep = exports.reexports[0];
77+
console.log(dep);
78+
return [
79+
`export * as default from '${dep}';`,
80+
`export * from '${dep}';`,
81+
].join("\n");
82+
}
83+
}
84+
return rawCode;
85+
},
86+
};
87+
return reactShims;
88+
}
89+
690
export default defineConfig({
7-
input: {
8-
main: "./src/index.jsx",
9-
},
10-
define: {
11-
"process.env.NODE_ENV": JSON.stringify("production"),
12-
},
13-
plugins: [
14-
m
15-
? minify({
16-
minify: true,
17-
legalComments: "none",
18-
target: "es2022",
19-
})
20-
: null,
21-
].filter(Boolean),
22-
profilerNames: !m,
23-
output: {
24-
minify: false,
25-
sourcemap: sourceMap,
26-
dir: "rolldown-dist",
27-
},
91+
input: {
92+
main: "./src/index.jsx",
93+
},
94+
define: {
95+
"process.env.NODE_ENV": JSON.stringify("production"),
96+
},
97+
plugins: [
98+
cjsToEsm(),
99+
m
100+
? minify({
101+
minify: true,
102+
legalComments: "none",
103+
target: "es2022",
104+
})
105+
: null,
106+
].filter(Boolean),
107+
profilerNames: !m,
108+
treeshake: true,
109+
output: {
110+
minify: false,
111+
112+
sourcemap: sourceMap,
113+
dir: "rolldown-dist",
114+
},
28115
});

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"@rspack/cli": "1.1.8",
2323
"@swc/core": "^1.10.1",
2424
"@types/glob": "^7.1.1",
25+
"cjs-module-lexer": "^1.4.1",
2526
"esbuild": "^0.24.0",
2627
"glob": "11.0.0",
2728
"lint-staged": "^15.2.10",

0 commit comments

Comments
 (0)