From 17014d04e686f85d9e6b56e1ddf1f2811b3dc884 Mon Sep 17 00:00:00 2001 From: GrygrFlzr Date: Wed, 30 Jun 2021 19:58:31 +0700 Subject: [PATCH 1/2] fix(ssr): Transform named default exports without altering scope Fixes #4049 --- .../node/ssr/__tests__/ssrTransform.spec.ts | 50 ++++++++++++++++++- packages/vite/src/node/ssr/ssrTransform.ts | 23 +++++++-- 2 files changed, 67 insertions(+), 6 deletions(-) diff --git a/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts b/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts index 0f5339861bc125..b3cc856aa9ae44 100644 --- a/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts +++ b/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts @@ -211,8 +211,56 @@ test('should declare variable for imported super class', async () => { ).toMatchInlineSnapshot(` "const __vite_ssr_import_0__ = __vite_ssr_import__(\\"./dependency\\") const Foo = __vite_ssr_import_0__.Foo; - __vite_ssr_exports__.default = class A extends Foo {} + class A extends Foo {} class B extends Foo {} + Object.defineProperty(__vite_ssr_exports__, \\"default\\", { enumerable: true, value: A }) + Object.defineProperty(__vite_ssr_exports__, \\"B\\", { enumerable: true, configurable: true, get(){ return B }})" + `) +}) + +// #4049 +test('should handle default export variants', async () => { + // default anonymous functions + expect( + (await ssrTransform(`export default function() {}\n`, null, null)).code + ).toMatchInlineSnapshot(` + "__vite_ssr_exports__.default = function() {} + " + `) + // default anonymous class + expect((await ssrTransform(`export default class {}\n`, null, null)).code) + .toMatchInlineSnapshot(` + "__vite_ssr_exports__.default = class {} + " + `) + // default named functions + expect( + ( + await ssrTransform( + `export default function foo() {}\n` + + `foo.prototype = Object.prototype;`, + null, + null + ) + ).code + ).toMatchInlineSnapshot(` + "function foo() {} + foo.prototype = Object.prototype; + Object.defineProperty(__vite_ssr_exports__, \\"default\\", { enumerable: true, value: foo })" + `) + // default named classes + expect( + ( + await ssrTransform( + `export default class A {}\n` + `export class B extends A {}`, + null, + null + ) + ).code + ).toMatchInlineSnapshot(` + "class A {} + class B extends A {} + Object.defineProperty(__vite_ssr_exports__, \\"default\\", { enumerable: true, value: A }) Object.defineProperty(__vite_ssr_exports__, \\"B\\", { enumerable: true, configurable: true, get(){ return B }})" `) }) diff --git a/packages/vite/src/node/ssr/ssrTransform.ts b/packages/vite/src/node/ssr/ssrTransform.ts index 531548997ca00e..cceb2f8cbc1c2c 100644 --- a/packages/vite/src/node/ssr/ssrTransform.ts +++ b/packages/vite/src/node/ssr/ssrTransform.ts @@ -124,11 +124,24 @@ export async function ssrTransform( // default export if (node.type === 'ExportDefaultDeclaration') { - s.overwrite( - node.start, - node.start + 14, - `${ssrModuleExportsKey}.default =` - ) + if ('id' in node.declaration && node.declaration.id) { + // named hoistable/class exports + // export default function foo() {} + // export default class A {} + const { name } = node.declaration.id + s.remove(node.start, node.start + `export default `.length) + s.append( + `\nObject.defineProperty(${ssrModuleExportsKey}, "default", ` + + `{ enumerable: true, value: ${name} })` + ) + } else { + // anonymous default exports + s.overwrite( + node.start, + node.start + `export default`.length, + `${ssrModuleExportsKey}.default =` + ) + } } // export * from './foo' From 5f72011a05eee128353c6c51fcbbf6a1804f52d4 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Fri, 2 Jul 2021 17:28:40 +0800 Subject: [PATCH 2/2] chore: update --- packages/vite/src/node/ssr/ssrTransform.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/vite/src/node/ssr/ssrTransform.ts b/packages/vite/src/node/ssr/ssrTransform.ts index cceb2f8cbc1c2c..c0b085b0b2f3d0 100644 --- a/packages/vite/src/node/ssr/ssrTransform.ts +++ b/packages/vite/src/node/ssr/ssrTransform.ts @@ -129,7 +129,7 @@ export async function ssrTransform( // export default function foo() {} // export default class A {} const { name } = node.declaration.id - s.remove(node.start, node.start + `export default `.length) + s.remove(node.start, node.start + 15 /* 'export default '.length */) s.append( `\nObject.defineProperty(${ssrModuleExportsKey}, "default", ` + `{ enumerable: true, value: ${name} })` @@ -138,7 +138,7 @@ export async function ssrTransform( // anonymous default exports s.overwrite( node.start, - node.start + `export default`.length, + node.start + 14 /* 'export default'.length */, `${ssrModuleExportsKey}.default =` ) }