diff --git a/packages/plugin-rsc/src/plugins/cjs.ts b/packages/plugin-rsc/src/plugins/cjs.ts index b2b9e85e..a232f69c 100644 --- a/packages/plugin-rsc/src/plugins/cjs.ts +++ b/packages/plugin-rsc/src/plugins/cjs.ts @@ -56,7 +56,10 @@ export function cjsModuleRunnerPlugin(): Plugin[] { // TODO: can we use cjs-module-lexer to properly define named exports? // for re-exports, we need to eagerly transform dependencies though. // https://github.com/nodejs/node/blob/f3adc11e37b8bfaaa026ea85c1cf22e3a0e29ae9/lib/internal/modules/esm/translators.js#L382-L409 - output.append(`__vite_ssr_exportAll__(module.exports)`) + output.append(` +;__vite_ssr_exportAll__(module.exports); +export default module.exports; +`) return { code: output.toString(), map: output.generateMap({ hires: 'boundary' }), diff --git a/packages/plugin-rsc/src/transforms/cjs.test.ts b/packages/plugin-rsc/src/transforms/cjs.test.ts index 659eff7d..2305ddea 100644 --- a/packages/plugin-rsc/src/transforms/cjs.test.ts +++ b/packages/plugin-rsc/src/transforms/cjs.test.ts @@ -1,7 +1,8 @@ -import { parseAstAsync } from 'vite' +import { createServer, createServerModuleRunner, parseAstAsync } from 'vite' import { describe, expect, it } from 'vitest' import { debugSourceMap } from './test-utils' import { transformCjsToEsm } from './cjs' +import path from 'node:path' describe(transformCjsToEsm, () => { async function testTransform(input: string) { @@ -83,4 +84,51 @@ if (true) { " `) }) + + it('e2e', async () => { + const server = await createServer({ + configFile: false, + logLevel: 'error', + root: path.join(import.meta.dirname, 'fixtures/cjs'), + plugins: [ + { + name: 'cjs-module-runner-transform', + async transform(code, id) { + if (id.endsWith('.cjs')) { + const ast = await parseAstAsync(code) + const { output } = transformCjsToEsm(code, ast) + output.append(` +;__vite_ssr_exportAll__(module.exports); +export default module.exports; +`) + return { + code: output.toString(), + map: output.generateMap({ hires: 'boundary' }), + } + } + }, + }, + ], + }) + const runner = createServerModuleRunner(server.environments.ssr, { + hmr: false, + }) + const mod = await runner.import('/entry.mjs') + expect(mod).toMatchInlineSnapshot(` + { + "depDefault": { + "a": "a", + "b": "b", + }, + "depNamespace": { + "a": "a", + "b": "b", + "default": { + "a": "a", + "b": "b", + }, + }, + } + `) + }) }) diff --git a/packages/plugin-rsc/src/transforms/fixtures/cjs/dep1.cjs b/packages/plugin-rsc/src/transforms/fixtures/cjs/dep1.cjs new file mode 100644 index 00000000..9d823f88 --- /dev/null +++ b/packages/plugin-rsc/src/transforms/fixtures/cjs/dep1.cjs @@ -0,0 +1,2 @@ +exports.a = 'a' +exports.b = 'b' diff --git a/packages/plugin-rsc/src/transforms/fixtures/cjs/dep2.cjs b/packages/plugin-rsc/src/transforms/fixtures/cjs/dep2.cjs new file mode 100644 index 00000000..9d823f88 --- /dev/null +++ b/packages/plugin-rsc/src/transforms/fixtures/cjs/dep2.cjs @@ -0,0 +1,2 @@ +exports.a = 'a' +exports.b = 'b' diff --git a/packages/plugin-rsc/src/transforms/fixtures/cjs/entry.mjs b/packages/plugin-rsc/src/transforms/fixtures/cjs/entry.mjs new file mode 100644 index 00000000..bdcffd80 --- /dev/null +++ b/packages/plugin-rsc/src/transforms/fixtures/cjs/entry.mjs @@ -0,0 +1,3 @@ +import depDefault from './dep1.cjs' +import * as depNamespace from './dep2.cjs' +export { depDefault, depNamespace }