Skip to content

Commit d0ee6b5

Browse files
Copilothi-ogawa
andcommitted
fix(plugin-rsc): use explicit marker for CJS module detection in interop helper
- Change interop helper to check for __cjs_module_runner_transform marker - Add marker export to all transformed CJS modules - Update tests to include marker in transformed modules - More explicit approach than heuristic-based detection Co-authored-by: hi-ogawa <4232207+hi-ogawa@users.noreply.github.com>
1 parent 5f18644 commit d0ee6b5

File tree

3 files changed

+9
-8
lines changed

3 files changed

+9
-8
lines changed

packages/plugin-rsc/src/plugins/cjs.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export function cjsModuleRunnerPlugin(): Plugin[] {
6060
output.append(`
6161
;__vite_ssr_exportAll__(module.exports);
6262
export default module.exports;
63+
export const __cjs_module_runner_transform = true;
6364
`)
6465
return {
6566
code: output.toString(),

packages/plugin-rsc/src/transforms/cjs.test.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ if (true) {
3838
`
3939
expect(await testTransform(input)).toMatchInlineSnapshot(`
4040
"let exports = {}; const module = { exports };
41-
function __cjs_interop__(m) { return m && m.__esModule ? m.default : (m.default !== undefined ? m.default : m); }
41+
function __cjs_interop__(m) { return m.__cjs_module_runner_transform ? m.default : m; }
4242
if (true) {
4343
module.exports = (__cjs_interop__(await import('./cjs/use-sync-external-store.production.js')));
4444
} else {
@@ -58,7 +58,7 @@ if (true) {
5858
`
5959
expect(await testTransform(input)).toMatchInlineSnapshot(`
6060
"let exports = {}; const module = { exports };
61-
function __cjs_interop__(m) { return m && m.__esModule ? m.default : (m.default !== undefined ? m.default : m); }
61+
function __cjs_interop__(m) { return m.__cjs_module_runner_transform ? m.default : m; }
6262
const __cjs_to_esm_hoist_0 = __cjs_interop__(await import("react"));
6363
const __cjs_to_esm_hoist_1 = __cjs_interop__(await import("react-dom"));
6464
"production" !== process.env.NODE_ENV && (function() {
@@ -84,7 +84,7 @@ function test() {
8484
`
8585
expect(await testTransform(input)).toMatchInlineSnapshot(`
8686
"let exports = {}; const module = { exports };
87-
function __cjs_interop__(m) { return m && m.__esModule ? m.default : (m.default !== undefined ? m.default : m); }
87+
function __cjs_interop__(m) { return m.__cjs_module_runner_transform ? m.default : m; }
8888
const __cjs_to_esm_hoist_0 = __cjs_interop__(await import("te" + "st"));
8989
const __cjs_to_esm_hoist_1 = __cjs_interop__(await import("test"));
9090
const __cjs_to_esm_hoist_2 = __cjs_interop__(await import("test"));
@@ -133,6 +133,7 @@ function test() {
133133
output.append(`
134134
;__vite_ssr_exportAll__(module.exports);
135135
export default module.exports;
136+
export const __cjs_module_runner_transform = true;
136137
`)
137138
return {
138139
code: output.toString(),
@@ -159,6 +160,7 @@ export default module.exports;
159160
"value": 3,
160161
},
161162
"depNamespace": {
163+
"__cjs_module_runner_transform": true,
162164
"a": "a",
163165
"b": "b",
164166
"default": {

packages/plugin-rsc/src/transforms/cjs.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@ import { analyze } from 'periscopic'
44
import { walk } from 'estree-walker'
55

66
// Runtime helper to handle CJS/ESM interop when transforming require() to import()
7-
// This is needed because when CJS code does require("pkg"), it expects:
8-
// - For CJS modules: the module.exports value directly
9-
// - For ESM modules: Node.js actually returns the namespace object
10-
// Since we're transforming to dynamic import(), we need to handle both cases
11-
const CJS_INTEROP_HELPER = `function __cjs_interop__(m) { return m && m.__esModule ? m.default : (m.default !== undefined ? m.default : m); }`
7+
// Only unwrap .default for modules that were transformed by this plugin (marked with __cjs_module_runner_transform)
8+
// This ensures we don't incorrectly unwrap .default on genuine ESM modules
9+
const CJS_INTEROP_HELPER = `function __cjs_interop__(m) { return m.__cjs_module_runner_transform ? m.default : m; }`
1210

1311
export function transformCjsToEsm(
1412
code: string,

0 commit comments

Comments
 (0)