diff --git a/packages/vite/src/module-runner/runner.ts b/packages/vite/src/module-runner/runner.ts index dcbbbe77688fb9..902aa70bcbd02b 100644 --- a/packages/vite/src/module-runner/runner.ts +++ b/packages/vite/src/module-runner/runner.ts @@ -429,7 +429,7 @@ function exportAll(exports: any, sourceModule: any) { return for (const key in sourceModule) { - if (key !== 'default' && key !== '__esModule') { + if (key !== 'default' && key !== '__esModule' && !(key in exports)) { try { Object.defineProperty(exports, key, { enumerable: true, diff --git a/packages/vite/src/node/ssr/__tests__/fixtures/named-overwrite-all/dep1.js b/packages/vite/src/node/ssr/__tests__/fixtures/named-overwrite-all/dep1.js new file mode 100644 index 00000000000000..ccc8eb47f073dc --- /dev/null +++ b/packages/vite/src/node/ssr/__tests__/fixtures/named-overwrite-all/dep1.js @@ -0,0 +1,4 @@ +export const a = 'dep1-a' +export const b = 'dep1-b' +export const c = 'dep1-c' +export const d = 'dep1-d' diff --git a/packages/vite/src/node/ssr/__tests__/fixtures/named-overwrite-all/dep2.js b/packages/vite/src/node/ssr/__tests__/fixtures/named-overwrite-all/dep2.js new file mode 100644 index 00000000000000..e112aa48c4d298 --- /dev/null +++ b/packages/vite/src/node/ssr/__tests__/fixtures/named-overwrite-all/dep2.js @@ -0,0 +1 @@ +export const d = 'dep2-d' diff --git a/packages/vite/src/node/ssr/__tests__/fixtures/named-overwrite-all/main.js b/packages/vite/src/node/ssr/__tests__/fixtures/named-overwrite-all/main.js new file mode 100644 index 00000000000000..860f5fdd95a931 --- /dev/null +++ b/packages/vite/src/node/ssr/__tests__/fixtures/named-overwrite-all/main.js @@ -0,0 +1,4 @@ +export const a = 'main-a' +export * from './dep1.js' +export const c = 'main-c' +export * from './dep2.js' diff --git a/packages/vite/src/node/ssr/__tests__/ssrLoadModule.spec.ts b/packages/vite/src/node/ssr/__tests__/ssrLoadModule.spec.ts index f4011d76c95aee..fd49c288387ad4 100644 --- a/packages/vite/src/node/ssr/__tests__/ssrLoadModule.spec.ts +++ b/packages/vite/src/node/ssr/__tests__/ssrLoadModule.spec.ts @@ -292,3 +292,26 @@ test('plugin error', async () => { Plugin: test-plugin" `) }) + +test('named exports overwrite export all', async () => { + const server = await createDevServer() + const mod = await server.ssrLoadModule( + './fixtures/named-overwrite-all/main.js', + ) + + // ESM spec doesn't allow conflicting `export *` and such duplicate exports are removed (in this case "d"), + // but this is likely not possible to support due to Vite dev SSR's lazy nature. + // [Node] + // $ node -e 'import("./packages/vite/src/node/ssr/__tests__/fixtures/named-overwrite-all/main.js").then(console.log)' + // [Module: null prototype] { a: 'main-a', b: 'dep1-b', c: 'main-c' } + // [Rollup] + // Conflicting namespaces: "main.js" re-exports "d" from one of the modules "dep1.js" and "dep2.js" (will be ignored). + expect(mod).toMatchInlineSnapshot(` + { + "a": "main-a", + "b": "dep1-b", + "c": "main-c", + "d": "dep1-d", + } + `) +})