Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/vite/src/node/ssr/__tests__/ssrLoadModule.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ test('json', async () => {
null,
'/test.json',
)
expect(json?.code.length).toMatchInlineSnapshot(`61`)
expect(json?.code.length).toMatchInlineSnapshot(`208`)
})

test('file url', async () => {
Expand Down
50 changes: 29 additions & 21 deletions packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,9 +221,11 @@ test('export as from arbitrary module namespace identifier', async () => {
})

test('export default', async () => {
expect(
await ssrTransformSimpleCode(`export default {}`),
).toMatchInlineSnapshot(`"__vite_ssr_exports__.default = {}"`)
expect(await ssrTransformSimpleCode(`export default {}`))
.toMatchInlineSnapshot(`
"Object.defineProperty(__vite_ssr_exports__, "default", { enumerable: true, configurable: true, get(){ return __vite_ssr_export_default__ }});
const __vite_ssr_export_default__ = {}"
`)
})

test('export then import minified', async () => {
Expand Down Expand Up @@ -505,11 +507,11 @@ test('should declare variable for imported super class', async () => {
`export class B extends Foo {}`,
),
).toMatchInlineSnapshot(`
"Object.defineProperty(__vite_ssr_exports__, "B", { enumerable: true, configurable: true, get(){ return B }});
"Object.defineProperty(__vite_ssr_exports__, "default", { enumerable: true, configurable: true, get(){ return A }});
Object.defineProperty(__vite_ssr_exports__, "B", { enumerable: true, configurable: true, get(){ return B }});
const __vite_ssr_import_0__ = await __vite_ssr_import__("./dependency", {"importedNames":["Foo"]});const Foo = __vite_ssr_import_0__.Foo;
class A extends Foo {};
class B extends Foo {}
Object.defineProperty(__vite_ssr_exports__, "default", { enumerable: true, configurable: true, value: A });"
class B extends Foo {}"
`)
})

Expand All @@ -518,13 +520,15 @@ test('should handle default export variants', async () => {
// default anonymous functions
expect(await ssrTransformSimpleCode(`export default function() {}\n`))
.toMatchInlineSnapshot(`
"__vite_ssr_exports__.default = function() {}
"Object.defineProperty(__vite_ssr_exports__, "default", { enumerable: true, configurable: true, get(){ return __vite_ssr_export_default__ }});
const __vite_ssr_export_default__ = function() {}
"
`)
// default anonymous class
expect(await ssrTransformSimpleCode(`export default class {}\n`))
.toMatchInlineSnapshot(`
"__vite_ssr_exports__.default = class {}
"Object.defineProperty(__vite_ssr_exports__, "default", { enumerable: true, configurable: true, get(){ return __vite_ssr_export_default__ }});
const __vite_ssr_export_default__ = class {}
"
`)
// default named functions
Expand All @@ -534,20 +538,20 @@ test('should handle default export variants', async () => {
`foo.prototype = Object.prototype;`,
),
).toMatchInlineSnapshot(`
"function foo() {};
foo.prototype = Object.prototype;
Object.defineProperty(__vite_ssr_exports__, "default", { enumerable: true, configurable: true, value: foo });"
"Object.defineProperty(__vite_ssr_exports__, "default", { enumerable: true, configurable: true, get(){ return foo }});
function foo() {};
foo.prototype = Object.prototype;"
`)
// default named classes
expect(
await ssrTransformSimpleCode(
`export default class A {}\n` + `export class B extends A {}`,
),
).toMatchInlineSnapshot(`
"Object.defineProperty(__vite_ssr_exports__, "B", { enumerable: true, configurable: true, get(){ return B }});
"Object.defineProperty(__vite_ssr_exports__, "default", { enumerable: true, configurable: true, get(){ return A }});
Object.defineProperty(__vite_ssr_exports__, "B", { enumerable: true, configurable: true, get(){ return B }});
class A {};
class B extends A {}
Object.defineProperty(__vite_ssr_exports__, "default", { enumerable: true, configurable: true, value: A });"
class B extends A {}"
`)
})

Expand Down Expand Up @@ -1007,14 +1011,17 @@ export default (function getRandom() {
`.trim()

expect(await ssrTransformSimpleCode(code)).toMatchInlineSnapshot(`
"__vite_ssr_exports__.default = (function getRandom() {
"Object.defineProperty(__vite_ssr_exports__, "default", { enumerable: true, configurable: true, get(){ return __vite_ssr_export_default__ }});
const __vite_ssr_export_default__ = (function getRandom() {
return Math.random();
});"
`)

expect(
await ssrTransformSimpleCode(`export default (class A {});`),
).toMatchInlineSnapshot(`"__vite_ssr_exports__.default = (class A {});"`)
expect(await ssrTransformSimpleCode(`export default (class A {});`))
.toMatchInlineSnapshot(`
"Object.defineProperty(__vite_ssr_exports__, "default", { enumerable: true, configurable: true, get(){ return __vite_ssr_export_default__ }});
const __vite_ssr_export_default__ = (class A {});"
`)
})

// #8002
Expand Down Expand Up @@ -1278,10 +1285,11 @@ export * as bar from './bar'
console.log(bar)
`),
).toMatchInlineSnapshot(`
"Object.defineProperty(__vite_ssr_exports__, "bar", { enumerable: true, configurable: true, get(){ return __vite_ssr_import_1__ }});
"Object.defineProperty(__vite_ssr_exports__, "default", { enumerable: true, configurable: true, get(){ return __vite_ssr_export_default__ }});
Object.defineProperty(__vite_ssr_exports__, "bar", { enumerable: true, configurable: true, get(){ return __vite_ssr_import_1__ }});

const __vite_ssr_import_0__ = await __vite_ssr_import__("./foo", {"importedNames":["foo"]});
__vite_ssr_exports__.default = (0,__vite_ssr_import_0__.foo)();
const __vite_ssr_export_default__ = (0,__vite_ssr_import_0__.foo)();
const __vite_ssr_import_1__ = await __vite_ssr_import__("./bar");;
console.log(bar)
"
Expand Down Expand Up @@ -1503,7 +1511,7 @@ test('combine mappings', async () => {
expect(result?.map).toMatchInlineSnapshot(`
SourceMap {
"file": undefined,
"mappings": "AAAA,8BAAc,CAAC,CAAC,IAAI,CAAC;",
"mappings": ";AAAA,mCAAc,CAAC,CAAC,IAAI,CAAC;",
"names": [],
"sources": [
"virtual:test-mappings:null",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import dep from "./index.js"
export default dep
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import dep from "./dep.js";
export default dep
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "module"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default function f() {
return 0;
}

f = () => 1;

f = () => 2;

export function update() {
f = () => 3;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import f, { update } from "./dep.js";

const x = f();
update();
const y = f();
export default [x, y];
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
function f() {
return 0;
}

f = () => 1;

export default f;

f = () => 2;

export function update() {
f = () => 3;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import f, { update } from "./dep.js";

const x = f();
update();
const y = f();
export default [x, y];
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
function f() {
return 0;
}

f = () => 1

export { f as default }

f = () => 2

export function update() {
f = () => 3;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import f, { update } from "./dep.js";

const x = f();
update();
const y = f();
export default [x, y];
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export default class C {
static f = () => 0;
}

C = class {
static f = () => 1;
}

C = class {
static f = () => 2;
}

export function update() {
C = class {
static f = () => 3;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import C, { update } from "./dep.js";

const x = C.f();
update();
const y = C.f();
export default [x, y];
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,55 @@ describe('module runner initialization', async () => {
`[ReferenceError: Cannot access 'dep1' before initialization]`,
)
})

it(`live binding (export default function f)`, async ({ runner }) => {
const mod = await runner.import('/fixtures/live-binding/test1/index.js')
expect(mod.default).toMatchInlineSnapshot(`
[
2,
3,
]
`)
})

it(`live binding (export default f)`, async ({ runner }) => {
const mod = await runner.import('/fixtures/live-binding/test2/index.js')
expect(mod.default).toMatchInlineSnapshot(`
[
1,
1,
]
`)
})

it(`live binding (export { f as default })`, async ({ runner }) => {
const mod = await runner.import('/fixtures/live-binding/test3/index.js')
expect(mod.default).toMatchInlineSnapshot(`
[
2,
3,
]
`)
})

it(`live binding (export default class C)`, async ({ runner }) => {
const mod = await runner.import('/fixtures/live-binding/test4/index.js')
expect(mod.default).toMatchInlineSnapshot(`
[
2,
3,
]
`)
})

it(`export default getter is hoisted`, async ({ runner }) => {
// Node error is `ReferenceError: Cannot access 'dep' before initialization`
await expect(() =>
runner.import('/fixtures/cyclic2/test9/index.js'),
).rejects.toMatchInlineSnapshot(
`[ReferenceError: Cannot access '__vite_ssr_export_default__' before initialization]`,
)
})
})

describe('optimize-deps', async () => {
Expand Down
9 changes: 4 additions & 5 deletions packages/vite/src/node/ssr/ssrTransform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,17 +318,16 @@ async function ssrTransformScript(
// export default class A {}
const { name } = node.declaration.id
s.remove(node.start, node.start + 15 /* 'export default '.length */)
s.append(
`\nObject.defineProperty(${ssrModuleExportsKey}, "default", ` +
`{ enumerable: true, configurable: true, value: ${name} });`,
)
defineExport('default', name)
} else {
// anonymous default exports
const name = `__vite_ssr_export_default__`
s.update(
node.start,
node.start + 14 /* 'export default'.length */,
`${ssrModuleExportsKey}.default =`,
`const ${name} =`,
)
defineExport('default', name)
}
}

Expand Down
2 changes: 2 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.