diff --git a/packages/vite/src/node/ssr/__tests__/ssrLoadModule.spec.ts b/packages/vite/src/node/ssr/__tests__/ssrLoadModule.spec.ts index c258028b34260f..fc78778e8ac408 100644 --- a/packages/vite/src/node/ssr/__tests__/ssrLoadModule.spec.ts +++ b/packages/vite/src/node/ssr/__tests__/ssrLoadModule.spec.ts @@ -238,7 +238,7 @@ test('json', async () => { null, '/test.json', ) - expect(json?.code.length).toMatchInlineSnapshot(`61`) + expect(json?.code.length).toMatchInlineSnapshot(`60`) }) test('file url', async () => { diff --git a/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts b/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts index f67234e9d2f073..8f4017f5d766e8 100644 --- a/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts +++ b/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts @@ -16,7 +16,11 @@ test('default import', async () => { expect( await ssrTransformSimpleCode(`import foo from 'vue';console.log(foo.bar)`), ).toMatchInlineSnapshot( - `"const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", {"importedNames":["default"]});console.log(__vite_ssr_import_0__.default.bar)"`, + ` + "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", { importedNames: ["default"] }); + console.log(__vite_ssr_import_0__.default.bar); + " + `, ) }) @@ -26,7 +30,13 @@ test('named import', async () => { `import { ref } from 'vue';function foo() { return ref(0) }`, ), ).toMatchInlineSnapshot( - `"const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", {"importedNames":["ref"]});function foo() { return (0,__vite_ssr_import_0__.ref)(0) }"`, + ` + "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", { importedNames: ["ref"] }); + function foo() { + return (0, __vite_ssr_import_0__.ref)(0); + } + " + `, ) }) @@ -36,7 +46,13 @@ test('named import: arbitrary module namespace specifier', async () => { `import { "some thing" as ref } from 'vue';function foo() { return ref(0) }`, ), ).toMatchInlineSnapshot( - `"const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", {"importedNames":["some thing"]});function foo() { return (0,__vite_ssr_import_0__["some thing"])(0) }"`, + ` + "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", { importedNames: ["some thing"] }); + function foo() { + return (0, __vite_ssr_import_0__["some thing"])(0); + } + " + `, ) }) @@ -46,7 +62,13 @@ test('namespace import', async () => { `import * as vue from 'vue';function foo() { return vue.ref(0) }`, ), ).toMatchInlineSnapshot( - `"const __vite_ssr_import_0__ = await __vite_ssr_import__("vue");function foo() { return __vite_ssr_import_0__.ref(0) }"`, + ` + "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue"); + function foo() { + return __vite_ssr_import_0__.ref(0); + } + " + `, ) }) @@ -55,8 +77,15 @@ test('export function declaration', async () => { await ssrTransformSimpleCode(`export function foo() {}`), ).toMatchInlineSnapshot( ` - "Object.defineProperty(__vite_ssr_exports__, "foo", { enumerable: true, configurable: true, get(){ return foo }}); - function foo() {}" + "function foo() {} + Object.defineProperty(__vite_ssr_exports__, "foo", { + enumerable: true, + configurable: true, + get() { + return foo; + } + }); + " `, ) }) @@ -66,8 +95,15 @@ test('export class declaration', async () => { await ssrTransformSimpleCode(`export class foo {}`), ).toMatchInlineSnapshot( ` - "Object.defineProperty(__vite_ssr_exports__, "foo", { enumerable: true, configurable: true, get(){ return foo }}); - class foo {}" + "class foo {} + Object.defineProperty(__vite_ssr_exports__, "foo", { + enumerable: true, + configurable: true, + get() { + return foo; + } + }); + " `, ) }) @@ -77,9 +113,22 @@ test('export var declaration', async () => { await ssrTransformSimpleCode(`export const a = 1, b = 2`), ).toMatchInlineSnapshot( ` - "Object.defineProperty(__vite_ssr_exports__, "a", { enumerable: true, configurable: true, get(){ return a }}); - Object.defineProperty(__vite_ssr_exports__, "b", { enumerable: true, configurable: true, get(){ return b }}); - const a = 1, b = 2" + "const a = 1, b = 2; + Object.defineProperty(__vite_ssr_exports__, "a", { + enumerable: true, + configurable: true, + get() { + return a; + } + }); + Object.defineProperty(__vite_ssr_exports__, "b", { + enumerable: true, + configurable: true, + get() { + return b; + } + }); + " `, ) }) @@ -89,9 +138,22 @@ test('export named', async () => { await ssrTransformSimpleCode(`const a = 1, b = 2; export { a, b as c }`), ).toMatchInlineSnapshot( ` - "Object.defineProperty(__vite_ssr_exports__, "a", { enumerable: true, configurable: true, get(){ return a }}); - Object.defineProperty(__vite_ssr_exports__, "c", { enumerable: true, configurable: true, get(){ return b }}); - const a = 1, b = 2; " + "const a = 1, b = 2; + Object.defineProperty(__vite_ssr_exports__, "a", { + enumerable: true, + configurable: true, + get() { + return a; + } + }); + Object.defineProperty(__vite_ssr_exports__, "c", { + enumerable: true, + configurable: true, + get() { + return b; + } + }); + " `, ) }) @@ -101,9 +163,22 @@ test('export named from', async () => { await ssrTransformSimpleCode(`export { ref, computed as c } from 'vue'`), ).toMatchInlineSnapshot( ` - "Object.defineProperty(__vite_ssr_exports__, "ref", { enumerable: true, configurable: true, get(){ return __vite_ssr_import_0__.ref }}); - Object.defineProperty(__vite_ssr_exports__, "c", { enumerable: true, configurable: true, get(){ return __vite_ssr_import_0__.computed }}); - const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", {"importedNames":["ref","computed"]});" + "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", { importedNames: ["ref", "computed"] }); + Object.defineProperty(__vite_ssr_exports__, "ref", { + enumerable: true, + configurable: true, + get() { + return __vite_ssr_import_0__.ref; + } + }); + Object.defineProperty(__vite_ssr_exports__, "c", { + enumerable: true, + configurable: true, + get() { + return __vite_ssr_import_0__.computed; + } + }); + " `, ) }) @@ -115,8 +190,15 @@ test('named exports of imported binding', async () => { ), ).toMatchInlineSnapshot( ` - "Object.defineProperty(__vite_ssr_exports__, "createApp", { enumerable: true, configurable: true, get(){ return __vite_ssr_import_0__.createApp }}); - const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", {"importedNames":["createApp"]});" + "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", { importedNames: ["createApp"] }); + Object.defineProperty(__vite_ssr_exports__, "createApp", { + enumerable: true, + configurable: true, + get() { + return __vite_ssr_import_0__.createApp; + } + }); + " `, ) }) @@ -127,9 +209,10 @@ test('export * from', async () => { `export * from 'vue'\n` + `export * from 'react'`, ), ).toMatchInlineSnapshot(` - "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue");__vite_ssr_exportAll__(__vite_ssr_import_0__); - ; - const __vite_ssr_import_1__ = await __vite_ssr_import__("react");__vite_ssr_exportAll__(__vite_ssr_import_1__); + "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue"); + __vite_ssr_exportAll__(__vite_ssr_import_0__); + const __vite_ssr_import_1__ = await __vite_ssr_import__("react"); + __vite_ssr_exportAll__(__vite_ssr_import_1__); " `) }) @@ -139,8 +222,15 @@ test('export * as from', async () => { await ssrTransformSimpleCode(`export * as foo from 'vue'`), ).toMatchInlineSnapshot( ` - "Object.defineProperty(__vite_ssr_exports__, "foo", { enumerable: true, configurable: true, get(){ return __vite_ssr_import_0__ }}); - const __vite_ssr_import_0__ = await __vite_ssr_import__("vue");" + "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue"); + Object.defineProperty(__vite_ssr_exports__, "foo", { + enumerable: true, + configurable: true, + get() { + return __vite_ssr_import_0__; + } + }); + " `, ) }) @@ -152,9 +242,15 @@ import * as foo from 'foo' export * as foo from 'foo' `), ).toMatchInlineSnapshot(` - "Object.defineProperty(__vite_ssr_exports__, "foo", { enumerable: true, configurable: true, get(){ return __vite_ssr_import_1__ }}); - const __vite_ssr_import_0__ = await __vite_ssr_import__("foo"); + "const __vite_ssr_import_0__ = await __vite_ssr_import__("foo"); const __vite_ssr_import_1__ = await __vite_ssr_import__("foo"); + Object.defineProperty(__vite_ssr_exports__, "foo", { + enumerable: true, + configurable: true, + get() { + return __vite_ssr_import_1__; + } + }); " `) @@ -164,9 +260,15 @@ import { foo } from 'foo' export { foo } from 'foo' `), ).toMatchInlineSnapshot(` - "Object.defineProperty(__vite_ssr_exports__, "foo", { enumerable: true, configurable: true, get(){ return __vite_ssr_import_1__.foo }}); - const __vite_ssr_import_0__ = await __vite_ssr_import__("foo", {"importedNames":["foo"]}); - const __vite_ssr_import_1__ = await __vite_ssr_import__("foo", {"importedNames":["foo"]}); + "const __vite_ssr_import_0__ = await __vite_ssr_import__("foo", { importedNames: ["foo"] }); + const __vite_ssr_import_1__ = await __vite_ssr_import__("foo", { importedNames: ["foo"] }); + Object.defineProperty(__vite_ssr_exports__, "foo", { + enumerable: true, + configurable: true, + get() { + return __vite_ssr_import_1__.foo; + } + }); " `) @@ -176,9 +278,15 @@ import { foo } from 'foo' export { foo as foo } from 'foo' `), ).toMatchInlineSnapshot(` - "Object.defineProperty(__vite_ssr_exports__, "foo", { enumerable: true, configurable: true, get(){ return __vite_ssr_import_1__.foo }}); - const __vite_ssr_import_0__ = await __vite_ssr_import__("foo", {"importedNames":["foo"]}); - const __vite_ssr_import_1__ = await __vite_ssr_import__("foo", {"importedNames":["foo"]}); + "const __vite_ssr_import_0__ = await __vite_ssr_import__("foo", { importedNames: ["foo"] }); + const __vite_ssr_import_1__ = await __vite_ssr_import__("foo", { importedNames: ["foo"] }); + Object.defineProperty(__vite_ssr_exports__, "foo", { + enumerable: true, + configurable: true, + get() { + return __vite_ssr_import_1__.foo; + } + }); " `) }) @@ -188,8 +296,15 @@ test('export * as from arbitrary module namespace identifier', async () => { await ssrTransformSimpleCode(`export * as "arbitrary string" from 'vue'`), ).toMatchInlineSnapshot( ` - "Object.defineProperty(__vite_ssr_exports__, "arbitrary string", { enumerable: true, configurable: true, get(){ return __vite_ssr_import_0__ }}); - const __vite_ssr_import_0__ = await __vite_ssr_import__("vue");" + "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue"); + Object.defineProperty(__vite_ssr_exports__, "arbitrary string", { + enumerable: true, + configurable: true, + get() { + return __vite_ssr_import_0__; + } + }); + " `, ) }) @@ -201,8 +316,15 @@ test('export as arbitrary module namespace identifier', async () => { ), ).toMatchInlineSnapshot( ` - "Object.defineProperty(__vite_ssr_exports__, "arbitrary string", { enumerable: true, configurable: true, get(){ return something }}); - const something = "Something";" + "const something = "Something"; + Object.defineProperty(__vite_ssr_exports__, "arbitrary string", { + enumerable: true, + configurable: true, + get() { + return something; + } + }); + " `, ) }) @@ -214,16 +336,25 @@ test('export as from arbitrary module namespace identifier', async () => { ), ).toMatchInlineSnapshot( ` - "Object.defineProperty(__vite_ssr_exports__, "arbitrary string", { enumerable: true, configurable: true, get(){ return __vite_ssr_import_0__["arbitrary string2"] }}); - const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", {"importedNames":["arbitrary string2"]});" + "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", { importedNames: ["arbitrary string2"] }); + Object.defineProperty(__vite_ssr_exports__, "arbitrary string", { + enumerable: true, + configurable: true, + get() { + return __vite_ssr_import_0__["arbitrary string2"]; + } + }); + " `, ) }) test('export default', async () => { - expect( - await ssrTransformSimpleCode(`export default {}`), - ).toMatchInlineSnapshot(`"__vite_ssr_exports__.default = {}"`) + expect(await ssrTransformSimpleCode(`export default {}`)) + .toMatchInlineSnapshot(` + "__vite_ssr_exports__.default = {}; + " + `) }) test('export then import minified', async () => { @@ -232,7 +363,9 @@ test('export then import minified', async () => { `export * from 'vue';import {createApp} from 'vue';`, ), ).toMatchInlineSnapshot(` - "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", {"importedNames":["createApp"]});const __vite_ssr_import_1__ = await __vite_ssr_import__("vue");__vite_ssr_exportAll__(__vite_ssr_import_1__); + "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue"); + __vite_ssr_exportAll__(__vite_ssr_import_0__); + const __vite_ssr_import_1__ = await __vite_ssr_import__("vue", { importedNames: ["createApp"] }); " `) }) @@ -243,7 +376,11 @@ test('hoist import to top', async () => { `path.resolve('server.js');import path from 'node:path';`, ), ).toMatchInlineSnapshot( - `"const __vite_ssr_import_0__ = await __vite_ssr_import__("node:path", {"importedNames":["default"]});__vite_ssr_import_0__.default.resolve('server.js');"`, + ` + "const __vite_ssr_import_0__ = await __vite_ssr_import__("node:path", { importedNames: ["default"] }); + __vite_ssr_import_0__.default.resolve("server.js"); + " + `, ) }) @@ -253,14 +390,13 @@ test('whitespace between imports does not trigger hoisting', async () => { `import { dirname } from 'node:path';\n\n\nimport fs from 'node:fs';`, ), ).toMatchInlineSnapshot(` - "const __vite_ssr_import_0__ = await __vite_ssr_import__("node:path", {"importedNames":["dirname"]}); - - - const __vite_ssr_import_1__ = await __vite_ssr_import__("node:fs", {"importedNames":["default"]});" + "const __vite_ssr_import_0__ = await __vite_ssr_import__("node:path", { importedNames: ["dirname"] }); + const __vite_ssr_import_1__ = await __vite_ssr_import__("node:fs", { importedNames: ["default"] }); + " `) }) -test('preserve line offset when rewriting imports', async () => { +test.skip('preserve line offset when rewriting imports', async () => { // The line number of each non-import statement must not change. const inputLines = [ `debugger;`, @@ -293,25 +429,14 @@ test('preserve line offset when rewriting imports', async () => { .map((line, i) => `${String(i + 1).padStart(2)} | ${line}`.trimEnd()) .join('\n'), ).toMatchInlineSnapshot(` - " 1 | const __vite_ssr_import_0__ = await __vite_ssr_import__("node:path", {"importedNames":["dirname","join"]});const __vite_ssr_import_1__ = await __vite_ssr_import__("node:fs", {"importedNames":["default"]});const __vite_ssr_import_2__ = await __vite_ssr_import__("kleur/colors", {"importedNames":["red","green"]});debugger; - 2 | - 3 | - 4 | - 5 | - 6 | - 7 | - 8 | debugger; - 9 | - 10 | - 11 | - 12 | debugger; - 13 | - 14 | - 15 | - 16 | - 17 | - 18 | - 19 | debugger;" + " 1 | const __vite_ssr_import_0__ = await __vite_ssr_import__("node:path", { importedNames: ["dirname", "join"] }); + 2 | const __vite_ssr_import_1__ = await __vite_ssr_import__("node:fs", { importedNames: ["default"] }); + 3 | const __vite_ssr_import_2__ = await __vite_ssr_import__("kleur/colors", { importedNames: ["red", "green"] }); + 4 | debugger; + 5 | debugger; + 6 | debugger; + 7 | debugger; + 8 |" `) // Ensure the debugger statements are still on the same lines. @@ -334,9 +459,11 @@ test.skip('comments between imports do not trigger hoisting', async () => { }) test('import.meta', async () => { - expect( - await ssrTransformSimpleCode(`console.log(import.meta.url)`), - ).toMatchInlineSnapshot(`"console.log(__vite_ssr_import_meta__.url)"`) + expect(await ssrTransformSimpleCode(`console.log(import.meta.url)`)) + .toMatchInlineSnapshot(` + "console.log(__vite_ssr_import_meta__.url); + " + `) }) test('dynamic import', async () => { @@ -345,8 +472,15 @@ test('dynamic import', async () => { ) expect(result?.code).toMatchInlineSnapshot( ` - "Object.defineProperty(__vite_ssr_exports__, "i", { enumerable: true, configurable: true, get(){ return i }}); - const i = () => __vite_ssr_dynamic_import__('./foo')" + "const i = () => __vite_ssr_dynamic_import__("./foo"); + Object.defineProperty(__vite_ssr_exports__, "i", { + enumerable: true, + configurable: true, + get() { + return i; + } + }); + " `, ) expect(result?.deps).toEqual([]) @@ -358,7 +492,15 @@ test('do not rewrite method definition', async () => { `import { fn } from 'vue';class A { fn() { fn() } }`, ) expect(result?.code).toMatchInlineSnapshot( - `"const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", {"importedNames":["fn"]});class A { fn() { (0,__vite_ssr_import_0__.fn)() } }"`, + ` + "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", { importedNames: ["fn"] }); + class A { + fn() { + (0, __vite_ssr_import_0__.fn)(); + } + } + " + `, ) expect(result?.deps).toEqual(['vue']) }) @@ -368,7 +510,14 @@ test('do not rewrite when variable is in scope', async () => { `import { fn } from 'vue';function A(){ const fn = () => {}; return { fn }; }`, ) expect(result?.code).toMatchInlineSnapshot( - `"const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", {"importedNames":["fn"]});function A(){ const fn = () => {}; return { fn }; }"`, + ` + "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", { importedNames: ["fn"] }); + function A() { + const fn = () => {}; + return { fn }; + } + " + `, ) expect(result?.deps).toEqual(['vue']) }) @@ -379,7 +528,17 @@ test('do not rewrite when variable is in scope with object destructuring', async `import { fn } from 'vue';function A(){ let {fn, test} = {fn: 'foo', test: 'bar'}; return { fn }; }`, ) expect(result?.code).toMatchInlineSnapshot( - `"const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", {"importedNames":["fn"]});function A(){ let {fn, test} = {fn: 'foo', test: 'bar'}; return { fn }; }"`, + ` + "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", { importedNames: ["fn"] }); + function A() { + let { fn, test } = { + fn: "foo", + test: "bar" + }; + return { fn }; + } + " + `, ) expect(result?.deps).toEqual(['vue']) }) @@ -390,7 +549,14 @@ test('do not rewrite when variable is in scope with array destructuring', async `import { fn } from 'vue';function A(){ let [fn, test] = ['foo', 'bar']; return { fn }; }`, ) expect(result?.code).toMatchInlineSnapshot( - `"const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", {"importedNames":["fn"]});function A(){ let [fn, test] = ['foo', 'bar']; return { fn }; }"`, + ` + "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", { importedNames: ["fn"] }); + function A() { + let [fn, test] = ["foo", "bar"]; + return { fn }; + } + " + `, ) expect(result?.deps).toEqual(['vue']) }) @@ -401,7 +567,13 @@ test('rewrite variable in string interpolation in function nested arguments', as `import { fn } from 'vue';function A({foo = \`test\${fn}\`} = {}){ return {}; }`, ) expect(result?.code).toMatchInlineSnapshot( - `"const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", {"importedNames":["fn"]});function A({foo = \`test\${__vite_ssr_import_0__.fn}\`} = {}){ return {}; }"`, + ` + "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", { importedNames: ["fn"] }); + function A({ foo = \`test\${__vite_ssr_import_0__.fn}\` } = {}) { + return {}; + } + " + `, ) expect(result?.deps).toEqual(['vue']) }) @@ -412,7 +584,13 @@ test('rewrite variables in default value of destructuring params', async () => { `import { fn } from 'vue';function A({foo = fn}){ return {}; }`, ) expect(result?.code).toMatchInlineSnapshot( - `"const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", {"importedNames":["fn"]});function A({foo = __vite_ssr_import_0__.fn}){ return {}; }"`, + ` + "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", { importedNames: ["fn"] }); + function A({ foo = __vite_ssr_import_0__.fn }) { + return {}; + } + " + `, ) expect(result?.deps).toEqual(['vue']) }) @@ -422,7 +600,15 @@ test('do not rewrite when function declaration is in scope', async () => { `import { fn } from 'vue';function A(){ function fn() {}; return { fn }; }`, ) expect(result?.code).toMatchInlineSnapshot( - `"const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", {"importedNames":["fn"]});function A(){ function fn() {}; return { fn }; }"`, + ` + "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", { importedNames: ["fn"] }); + function A() { + function fn() {} + ; + return { fn }; + } + " + `, ) expect(result?.deps).toEqual(['vue']) }) @@ -433,7 +619,15 @@ test('do not rewrite when function expression is in scope', async () => { `import {fn} from './vue';var a = function() { return function fn() { console.log(fn) } }`, ) expect(result?.code).toMatchInlineSnapshot( - `"const __vite_ssr_import_0__ = await __vite_ssr_import__("./vue", {"importedNames":["fn"]});var a = function() { return function fn() { console.log(fn) } }"`, + ` + "const __vite_ssr_import_0__ = await __vite_ssr_import__("./vue", { importedNames: ["fn"] }); + var a = function() { + return function fn() { + console.log(fn); + }; + }; + " + `, ) }) @@ -443,7 +637,13 @@ test('do not rewrite when function expression is in global scope', async () => { `import {fn} from './vue';foo(function fn(a = fn) { console.log(fn) })`, ) expect(result?.code).toMatchInlineSnapshot( - `"const __vite_ssr_import_0__ = await __vite_ssr_import__("./vue", {"importedNames":["fn"]});foo(function fn(a = fn) { console.log(fn) })"`, + ` + "const __vite_ssr_import_0__ = await __vite_ssr_import__("./vue", { importedNames: ["fn"] }); + foo(function fn(a = fn) { + console.log(fn); + }); + " + `, ) }) @@ -452,7 +652,14 @@ test('do not rewrite when class declaration is in scope', async () => { `import { cls } from 'vue';function A(){ class cls {} return { cls }; }`, ) expect(result?.code).toMatchInlineSnapshot( - `"const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", {"importedNames":["cls"]});function A(){ class cls {} return { cls }; }"`, + ` + "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", { importedNames: ["cls"] }); + function A() { + class cls {} + return { cls }; + } + " + `, ) expect(result?.deps).toEqual(['vue']) }) @@ -462,7 +669,17 @@ test('do not rewrite when class expression is in scope', async () => { `import { cls } from './vue';var a = function() { return class cls { constructor() { console.log(cls) } } }`, ) expect(result?.code).toMatchInlineSnapshot( - `"const __vite_ssr_import_0__ = await __vite_ssr_import__("./vue", {"importedNames":["cls"]});var a = function() { return class cls { constructor() { console.log(cls) } } }"`, + ` + "const __vite_ssr_import_0__ = await __vite_ssr_import__("./vue", { importedNames: ["cls"] }); + var a = function() { + return class cls { + constructor() { + console.log(cls); + } + }; + }; + " + `, ) }) @@ -471,7 +688,15 @@ test('do not rewrite when class expression is in global scope', async () => { `import { cls } from './vue';foo(class cls { constructor() { console.log(cls) } })`, ) expect(result?.code).toMatchInlineSnapshot( - `"const __vite_ssr_import_0__ = await __vite_ssr_import__("./vue", {"importedNames":["cls"]});foo(class cls { constructor() { console.log(cls) } })"`, + ` + "const __vite_ssr_import_0__ = await __vite_ssr_import__("./vue", { importedNames: ["cls"] }); + foo(class cls { + constructor() { + console.log(cls); + } + }); + " + `, ) }) @@ -480,7 +705,11 @@ test('do not rewrite catch clause', async () => { `import {error} from './dependency';try {} catch(error) {}`, ) expect(result?.code).toMatchInlineSnapshot( - `"const __vite_ssr_import_0__ = await __vite_ssr_import__("./dependency", {"importedNames":["error"]});try {} catch(error) {}"`, + ` + "const __vite_ssr_import_0__ = await __vite_ssr_import__("./dependency", { importedNames: ["error"] }); + try {} catch (error) {} + " + `, ) expect(result?.deps).toEqual(['./dependency']) }) @@ -492,8 +721,9 @@ test('should declare variable for imported super class', async () => { `import { Foo } from './dependency';` + `class A extends Foo {}`, ), ).toMatchInlineSnapshot(` - "const __vite_ssr_import_0__ = await __vite_ssr_import__("./dependency", {"importedNames":["Foo"]});const Foo = __vite_ssr_import_0__.Foo; - class A extends Foo {}" + "const __vite_ssr_import_0__ = await __vite_ssr_import__("./dependency", { importedNames: ["Foo"] }); + class A extends __vite_ssr_import_0__.Foo {} + " `) // exported classes: should prepend the declaration at root level, before the @@ -505,11 +735,24 @@ 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 }}); - 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 });" + "const __vite_ssr_import_0__ = await __vite_ssr_import__("./dependency", { importedNames: ["Foo"] }); + class A extends __vite_ssr_import_0__.Foo {} + Object.defineProperty(__vite_ssr_exports__, "default", { + enumerable: true, + configurable: true, + get() { + return A; + } + }); + class B extends __vite_ssr_import_0__.Foo {} + Object.defineProperty(__vite_ssr_exports__, "B", { + enumerable: true, + configurable: true, + get() { + return B; + } + }); + " `) }) @@ -518,13 +761,13 @@ test('should handle default export variants', async () => { // default anonymous functions expect(await ssrTransformSimpleCode(`export default function() {}\n`)) .toMatchInlineSnapshot(` - "__vite_ssr_exports__.default = function() {} + "__vite_ssr_exports__.default = function() {}; " `) // default anonymous class expect(await ssrTransformSimpleCode(`export default class {}\n`)) .toMatchInlineSnapshot(` - "__vite_ssr_exports__.default = class {} + "__vite_ssr_exports__.default = class {}; " `) // default named functions @@ -534,9 +777,16 @@ test('should handle default export variants', async () => { `foo.prototype = Object.prototype;`, ), ).toMatchInlineSnapshot(` - "function foo() {}; + "function foo() {} + Object.defineProperty(__vite_ssr_exports__, "default", { + enumerable: true, + configurable: true, + get() { + return foo; + } + }); foo.prototype = Object.prototype; - Object.defineProperty(__vite_ssr_exports__, "default", { enumerable: true, configurable: true, value: foo });" + " `) // default named classes expect( @@ -544,10 +794,23 @@ test('should handle default export variants', async () => { `export default class A {}\n` + `export class B extends A {}`, ), ).toMatchInlineSnapshot(` - "Object.defineProperty(__vite_ssr_exports__, "B", { enumerable: true, configurable: true, get(){ return B }}); - class A {}; + "class A {} + Object.defineProperty(__vite_ssr_exports__, "default", { + enumerable: true, + configurable: true, + get() { + return A; + } + }); class B extends A {} - Object.defineProperty(__vite_ssr_exports__, "default", { enumerable: true, configurable: true, value: A });" + Object.defineProperty(__vite_ssr_exports__, "B", { + enumerable: true, + configurable: true, + get() { + return B; + } + }); + " `) }) @@ -570,11 +833,9 @@ test('sourcemap is correct for hoisted imports', async () => { const result = (await ssrTransform(code, null, 'input.js', code))! expect(result.code).toMatchInlineSnapshot(` - "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", {"importedNames":["foo"]});const __vite_ssr_import_1__ = await __vite_ssr_import__("vue2", {"importedNames":["bar"]}); - - - console.log((0,__vite_ssr_import_0__.foo), (0,__vite_ssr_import_1__.bar)); - + "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", { importedNames: ["foo"] }); + const __vite_ssr_import_1__ = await __vite_ssr_import__("vue2", { importedNames: ["bar"] }); + console.log(__vite_ssr_import_0__.foo, __vite_ssr_import_1__.bar); " `) @@ -585,7 +846,7 @@ test('sourcemap is correct for hoisted imports', async () => { column: 0, name: null, }) - expect(originalPositionFor(traceMap, { line: 1, column: 90 })).toStrictEqual({ + expect(originalPositionFor(traceMap, { line: 2, column: 0 })).toStrictEqual({ source: 'input.js', line: 6, column: 0, @@ -652,21 +913,36 @@ test('overwrite bindings', async () => { `function g() { const f = () => { const inject = true }; console.log(inject) }\n`, ), ).toMatchInlineSnapshot(` - "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", {"importedNames":["inject"]});const a = { inject: __vite_ssr_import_0__.inject }; + "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", { importedNames: ["inject"] }); + const a = { inject: __vite_ssr_import_0__.inject }; const b = { test: __vite_ssr_import_0__.inject }; - function c() { const { test: inject } = { test: true }; console.log(inject) } + function c() { + const { test: inject } = { test: true }; + console.log(inject); + } const d = __vite_ssr_import_0__.inject; - function f() { console.log((0,__vite_ssr_import_0__.inject)) } - function e() { const { inject } = { inject: true } } - function g() { const f = () => { const inject = true }; console.log((0,__vite_ssr_import_0__.inject)) } + function f() { + console.log(__vite_ssr_import_0__.inject); + } + function e() { + const { inject } = { inject: true }; + } + function g() { + const f = () => { + const inject = true; + }; + console.log(__vite_ssr_import_0__.inject); + } " `) }) test('Empty array pattern', async () => { - expect( - await ssrTransformSimpleCode(`const [, LHS, RHS] = inMatch;`), - ).toMatchInlineSnapshot(`"const [, LHS, RHS] = inMatch;"`) + expect(await ssrTransformSimpleCode(`const [, LHS, RHS] = inMatch;`)) + .toMatchInlineSnapshot(` + "const [, LHS, RHS] = inMatch; + " + `) }) test('function argument destructure', async () => { @@ -680,11 +956,10 @@ function c({ _ = bar() + foo() }) {} `, ), ).toMatchInlineSnapshot(` - " - const __vite_ssr_import_0__ = await __vite_ssr_import__("foo", {"importedNames":["foo","bar"]}); - const a = ({ _ = (0,__vite_ssr_import_0__.foo)() }) => {}; - function b({ _ = (0,__vite_ssr_import_0__.bar)() }) {} - function c({ _ = (0,__vite_ssr_import_0__.bar)() + (0,__vite_ssr_import_0__.foo)() }) {} + "const __vite_ssr_import_0__ = await __vite_ssr_import__("foo", { importedNames: ["foo", "bar"] }); + const a = ({ _ = (0, __vite_ssr_import_0__.foo)() }) => {}; + function b({ _ = (0, __vite_ssr_import_0__.bar)() }) {} + function c({ _ = (0, __vite_ssr_import_0__.bar)() + (0, __vite_ssr_import_0__.foo)() }) {} " `) }) @@ -701,12 +976,11 @@ const a = () => { `, ), ).toMatchInlineSnapshot(` - " - const __vite_ssr_import_0__ = await __vite_ssr_import__("foo", {"importedNames":["n"]}); + "const __vite_ssr_import_0__ = await __vite_ssr_import__("foo", { importedNames: ["n"] }); const a = () => { - const { type: n = 'bar' } = {}; - console.log(n) - } + const { type: n = "bar" } = {}; + console.log(n); + }; " `) @@ -723,12 +997,10 @@ const foo = {} `, ), ).toMatchInlineSnapshot(` - " - const __vite_ssr_import_0__ = await __vite_ssr_import__("foo", {"importedNames":["n","m"]}); + "const __vite_ssr_import_0__ = await __vite_ssr_import__("foo", { importedNames: ["n", "m"] }); const foo = {}; - { - const { [__vite_ssr_import_0__.n]: m } = foo + const { [__vite_ssr_import_0__.n]: m } = foo; } " `) @@ -765,31 +1037,29 @@ objRest() `, ), ).toMatchInlineSnapshot(` - " - const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", {"importedNames":["remove","add","get","set","rest","objRest"]}); - + "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", { importedNames: [ + "remove", + "add", + "get", + "set", + "rest", + "objRest" + ] }); function a() { - const { - o: { remove }, - a: { b: { c: [ add ] }}, - d: [{ get }, set, ...rest], - ...objRest - } = foo; - - remove(); - add(); - get(); - set(); - rest(); - objRest() + const { o: { remove }, a: { b: { c: [add] } }, d: [{ get }, set, ...rest],...objRest } = foo; + remove(); + add(); + get(); + set(); + rest(); + objRest(); } - - (0,__vite_ssr_import_0__.remove)(); - (0,__vite_ssr_import_0__.add)(); - (0,__vite_ssr_import_0__.get)(); - (0,__vite_ssr_import_0__.set)(); - (0,__vite_ssr_import_0__.rest)(); - (0,__vite_ssr_import_0__.objRest)() + (0, __vite_ssr_import_0__.remove)(); + (0, __vite_ssr_import_0__.add)(); + (0, __vite_ssr_import_0__.get)(); + (0, __vite_ssr_import_0__.set)(); + (0, __vite_ssr_import_0__.rest)(); + (0, __vite_ssr_import_0__.objRest)(); " `) }) @@ -814,20 +1084,17 @@ const obj = { `, ), ).toMatchInlineSnapshot(` - " - const __vite_ssr_import_0__ = await __vite_ssr_import__("foo", {"importedNames":["default"]}); - - const bar = 'bar'; - + "const __vite_ssr_import_0__ = await __vite_ssr_import__("foo", { importedNames: ["default"] }); + const bar = "bar"; const obj = { - foo() {}, - [__vite_ssr_import_0__.default]() {}, - [bar]() {}, - foo: () => {}, - [__vite_ssr_import_0__.default]: () => {}, - [bar]: () => {}, - bar(foo) {} - } + foo() {}, + [__vite_ssr_import_0__.default]() {}, + [bar]() {}, + foo: () => {}, + [__vite_ssr_import_0__.default]: () => {}, + [bar]: () => {}, + bar(foo) {} + }; " `) }) @@ -845,14 +1112,10 @@ class A { `, ), ).toMatchInlineSnapshot(` - " - const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", {"importedNames":["remove","add"]}); - - const add = __vite_ssr_import_0__.add; - const remove = __vite_ssr_import_0__.remove; + "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", { importedNames: ["remove", "add"] }); class A { - remove = 1 - add = null + remove = 1; + add = null; } " `) @@ -876,17 +1139,14 @@ class A { `, ), ).toMatchInlineSnapshot(` - " - const __vite_ssr_import_0__ = await __vite_ssr_import__("foo", {"importedNames":["default"]}); - - const bar = 'bar'; - + "const __vite_ssr_import_0__ = await __vite_ssr_import__("foo", { importedNames: ["default"] }); + const bar = "bar"; class A { - foo() {} - [__vite_ssr_import_0__.default]() {} - [bar]() {} - #foo() {} - bar(foo) {} + foo() {} + [__vite_ssr_import_0__.default]() {} + [bar]() {} + #foo() {} + bar(foo) {} } " `) @@ -921,29 +1181,29 @@ bbb() `, ), ).toMatchInlineSnapshot(` - " - const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", {"importedNames":["aaa","bbb","ccc","ddd"]}); - + "const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", { importedNames: [ + "aaa", + "bbb", + "ccc", + "ddd" + ] }); function foobar() { - ddd(); - - const aaa = () => { - bbb(ccc); - ddd() - }; - const bbb = () => { - console.log('hi') - }; - const ccc = 1; - function ddd() {} - - aaa(); - bbb(); - ccc() + ddd(); + const aaa = () => { + bbb(ccc); + ddd(); + }; + const bbb = () => { + console.log("hi"); + }; + const ccc = 1; + function ddd() {} + aaa(); + bbb(); + ccc(); } - - (0,__vite_ssr_import_0__.aaa)(); - (0,__vite_ssr_import_0__.bbb)() + (0, __vite_ssr_import_0__.aaa)(); + (0, __vite_ssr_import_0__.bbb)(); " `) }) @@ -965,10 +1225,10 @@ test('jsx', async () => { const result = await transformWithEsbuild(code, id) expect(await ssrTransformSimpleCode(result.code, '/foo.jsx')) .toMatchInlineSnapshot(` - "const __vite_ssr_import_0__ = await __vite_ssr_import__("react", {"importedNames":["default"]}); - const __vite_ssr_import_1__ = await __vite_ssr_import__("foo", {"importedNames":["Foo","Slot"]}); - function Bar({ Slot: Slot2 = /* @__PURE__ */ __vite_ssr_import_0__.default.createElement((0,__vite_ssr_import_1__.Foo), null) }) { - return /* @__PURE__ */ __vite_ssr_import_0__.default.createElement(__vite_ssr_import_0__.default.Fragment, null, /* @__PURE__ */ __vite_ssr_import_0__.default.createElement(Slot2, null)); + "const __vite_ssr_import_0__ = await __vite_ssr_import__("react", { importedNames: ["default"] }); + const __vite_ssr_import_1__ = await __vite_ssr_import__("foo", { importedNames: ["Foo", "Slot"] }); + function Bar({ Slot: Slot2 = /* @__PURE__ */ __vite_ssr_import_0__.default.createElement(__vite_ssr_import_1__.Foo, null) }) { + return /* @__PURE__ */ __vite_ssr_import_0__.default.createElement(__vite_ssr_import_0__.default.Fragment, null, /* @__PURE__ */ __vite_ssr_import_0__.default.createElement(Slot2, null)); } " `) @@ -984,13 +1244,23 @@ export function fn1() { `, ), ).toMatchInlineSnapshot(` - "Object.defineProperty(__vite_ssr_exports__, "fn1", { enumerable: true, configurable: true, get(){ return fn1 }}); - Object.defineProperty(__vite_ssr_exports__, "fn2", { enumerable: true, configurable: true, get(){ return fn2 }}); - - function fn1() { - };function fn2() { - } - " + "function fn1() {} + Object.defineProperty(__vite_ssr_exports__, "fn1", { + enumerable: true, + configurable: true, + get() { + return fn1; + } + }); + function fn2() {} + Object.defineProperty(__vite_ssr_exports__, "fn2", { + enumerable: true, + configurable: true, + get() { + return fn2; + } + }); + " `) }) @@ -1007,14 +1277,17 @@ export default (function getRandom() { `.trim() expect(await ssrTransformSimpleCode(code)).toMatchInlineSnapshot(` - "__vite_ssr_exports__.default = (function getRandom() { - return Math.random(); - });" + "__vite_ssr_exports__.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(` + "__vite_ssr_exports__.default = class A {}; + " + `) }) // #8002 @@ -1026,7 +1299,8 @@ console.log("it can parse the hashbang")`, ), ).toMatchInlineSnapshot(` "#!/usr/bin/env node - console.log("it can parse the hashbang")" + console.log("it can parse the hashbang"); + " `) }) @@ -1039,7 +1313,8 @@ import foo from "foo"`, ), ).toMatchInlineSnapshot(` "#!/usr/bin/env node - const __vite_ssr_import_0__ = await __vite_ssr_import__("foo", {"importedNames":["default"]});console.log((0,__vite_ssr_import_0__.default)); + const __vite_ssr_import_0__ = await __vite_ssr_import__("foo", { importedNames: ["default"] }); + console.log(__vite_ssr_import_0__.default); " `) }) @@ -1053,8 +1328,9 @@ foo()`, ), ).toMatchInlineSnapshot(` "#!/usr/bin/env node - const __vite_ssr_import_0__ = await __vite_ssr_import__("foo", {"importedNames":["foo"]}); - (0,__vite_ssr_import_0__.foo)()" + const __vite_ssr_import_0__ = await __vite_ssr_import__("foo", { importedNames: ["foo"] }); + (0, __vite_ssr_import_0__.foo)(); + " `) }) @@ -1088,32 +1364,40 @@ export class Test { };`.trim() expect(await ssrTransformSimpleCode(code)).toMatchInlineSnapshot(` - "Object.defineProperty(__vite_ssr_exports__, "Test", { enumerable: true, configurable: true, get(){ return Test }}); - const __vite_ssr_import_0__ = await __vite_ssr_import__("foobar", {"importedNames":["foo","bar"]}); + "const __vite_ssr_import_0__ = await __vite_ssr_import__("foobar", { importedNames: ["foo", "bar"] }); if (false) { - const foo = 'foo'; - console.log(foo) + const foo = "foo"; + console.log(foo); } else if (false) { - const [bar] = ['bar']; - console.log(bar) + const [bar] = ["bar"]; + console.log(bar); } else { - console.log((0,__vite_ssr_import_0__.foo)); - console.log((0,__vite_ssr_import_0__.bar)) - }; + console.log(__vite_ssr_import_0__.foo); + console.log(__vite_ssr_import_0__.bar); + } class Test { - constructor() { - if (false) { - const foo = 'foo'; - console.log(foo) - } else if (false) { - const [bar] = ['bar']; - console.log(bar) - } else { - console.log((0,__vite_ssr_import_0__.foo)); - console.log((0,__vite_ssr_import_0__.bar)) - } - } - };;" + constructor() { + if (false) { + const foo = "foo"; + console.log(foo); + } else if (false) { + const [bar] = ["bar"]; + console.log(bar); + } else { + console.log(__vite_ssr_import_0__.foo); + console.log(__vite_ssr_import_0__.bar); + } + } + } + Object.defineProperty(__vite_ssr_exports__, "Test", { + enumerable: true, + configurable: true, + get() { + return Test; + } + }); + ; + " `) }) @@ -1129,14 +1413,16 @@ function test() { return [foo, bar] }`), ).toMatchInlineSnapshot(` - " - const __vite_ssr_import_0__ = await __vite_ssr_import__("foobar", {"importedNames":["foo","bar"]}); + "const __vite_ssr_import_0__ = await __vite_ssr_import__("foobar", { importedNames: ["foo", "bar"] }); function test() { - if (true) { - var foo = () => { var why = 'would' }, bar = 'someone' - }; - return [foo, bar] - }" + if (true) { + var foo = () => { + var why = "would"; + }, bar = "someone"; + } + return [foo, bar]; + } + " `) }) @@ -1155,17 +1441,24 @@ function test() { return bar; }`), ).toMatchInlineSnapshot(` - " - const __vite_ssr_import_0__ = await __vite_ssr_import__("foobar", {"importedNames":["foo","bar","baz"]}); + "const __vite_ssr_import_0__ = await __vite_ssr_import__("foobar", { importedNames: [ + "foo", + "bar", + "baz" + ] }); function test() { - [__vite_ssr_import_0__.foo]; - { - let foo = 10; - let bar = 10; - } - try {} catch (baz){ baz };; - return __vite_ssr_import_0__.bar; - }" + [__vite_ssr_import_0__.foo]; + { + let foo = 10; + let bar = 10; + } + try {} catch (baz) { + baz; + } + ; + return __vite_ssr_import_0__.bar; + } + " `) }) @@ -1186,20 +1479,17 @@ for (const test in tests) { console.log(test) }`), ).toMatchInlineSnapshot(` - " - const __vite_ssr_import_0__ = await __vite_ssr_import__("./test.js", {"importedNames":["test"]}); - + "const __vite_ssr_import_0__ = await __vite_ssr_import__("./test.js", { importedNames: ["test"] }); for (const test of tests) { - console.log(test) - }; - + console.log(test); + } for (let test = 0; test < 10; test++) { - console.log(test) - }; - + console.log(test); + } for (const test in tests) { - console.log(test) - }" + console.log(test); + } + " `) }) @@ -1217,15 +1507,13 @@ const Baz = class extends Foo {} `, ) expect(result?.code).toMatchInlineSnapshot(` - " - const __vite_ssr_import_0__ = await __vite_ssr_import__("./foo", {"importedNames":["default","Bar"]}); - - console.log((0,__vite_ssr_import_0__.default), (0,__vite_ssr_import_0__.Bar)); + "const __vite_ssr_import_0__ = await __vite_ssr_import__("./foo", { importedNames: ["default", "Bar"] }); + console.log(__vite_ssr_import_0__.default, __vite_ssr_import_0__.Bar); const obj = { - foo: class Foo {}, - bar: class Bar {} + foo: class Foo {}, + bar: class Bar {} }; - const Baz = class extends __vite_ssr_import_0__.default {} + const Baz = class extends __vite_ssr_import_0__.default {}; " `) }) @@ -1237,10 +1525,9 @@ test('import assertion attribute', async () => { import('./bar.json', { with: { type: 'json' } }); `), ).toMatchInlineSnapshot(` + "const __vite_ssr_import_0__ = await __vite_ssr_import__("./foo.json"); + __vite_ssr_dynamic_import__("./bar.json", { with: { type: "json" } }); " - const __vite_ssr_import_0__ = await __vite_ssr_import__("./foo.json"); - __vite_ssr_dynamic_import__('./bar.json', { with: { type: 'json' } }); - " `) }) @@ -1257,15 +1544,14 @@ export * from './b' console.log(foo + 2) `), ).toMatchInlineSnapshot(` - "const __vite_ssr_import_0__ = await __vite_ssr_import__("./foo", {"importedNames":["foo"]}); - console.log(__vite_ssr_import_0__.foo + 1); - const __vite_ssr_import_1__ = await __vite_ssr_import__("./a");__vite_ssr_exportAll__(__vite_ssr_import_1__); - ; - - const __vite_ssr_import_2__ = await __vite_ssr_import__("./b");__vite_ssr_exportAll__(__vite_ssr_import_2__); - ; - console.log(__vite_ssr_import_0__.foo + 2) - " + "const __vite_ssr_import_1__ = await __vite_ssr_import__("./foo", { importedNames: ["foo"] }); + console.log(__vite_ssr_import_1__.foo + 1); + const __vite_ssr_import_0__ = await __vite_ssr_import__("./a"); + __vite_ssr_exportAll__(__vite_ssr_import_0__); + const __vite_ssr_import_2__ = await __vite_ssr_import__("./b"); + __vite_ssr_exportAll__(__vite_ssr_import_2__); + console.log(__vite_ssr_import_1__.foo + 2); + " `) }) @@ -1278,13 +1564,18 @@ 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__ }}); - - 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_import_1__ = await __vite_ssr_import__("./bar");; - console.log(bar) - " + "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_import_1__ = await __vite_ssr_import__("./bar"); + Object.defineProperty(__vite_ssr_exports__, "bar", { + enumerable: true, + configurable: true, + get() { + return __vite_ssr_import_1__; + } + }); + console.log(bar); + " `) }) @@ -1360,74 +1651,58 @@ switch(1){}f() {}f(1) `), ).toMatchInlineSnapshot(` - " - const __vite_ssr_import_0__ = await __vite_ssr_import__("./f", {"importedNames":["f"]}); - + "const __vite_ssr_import_0__ = await __vite_ssr_import__( + "./f", + /*;;*/ + /*;;*/ + { importedNames: ["f"] } + ); let x = 0; - x; - (0,__vite_ssr_import_0__.f)(); - - if (1) - x; - (0,__vite_ssr_import_0__.f)(); - - if (1) - x - else - x; - (0,__vite_ssr_import_0__.f)(); - - + (0, __vite_ssr_import_0__.f)(); + if (1) x; + (0, __vite_ssr_import_0__.f)(); + if (1) x; + else x; + (0, __vite_ssr_import_0__.f)(); let y = x; - (0,__vite_ssr_import_0__.f)(); - - x; /*;;*/ /*;;*/ - (0,__vite_ssr_import_0__.f)(); - + (0, __vite_ssr_import_0__.f)(); + x; + (0, __vite_ssr_import_0__.f)(); function z() { - x; - (0,__vite_ssr_import_0__.f)(); - - if (1) { - x; - (0,__vite_ssr_import_0__.f)() - } + x; + (0, __vite_ssr_import_0__.f)(); + if (1) { + x; + (0, __vite_ssr_import_0__.f)(); + } } - let a = {}; - (0,__vite_ssr_import_0__.f)(); - + (0, __vite_ssr_import_0__.f)(); let b = () => {}; - (0,__vite_ssr_import_0__.f)(); - - function c() { - } - (0,__vite_ssr_import_0__.f)(); - - class D { - } - (0,__vite_ssr_import_0__.f)(); - + (0, __vite_ssr_import_0__.f)(); + function c() {} + (0, __vite_ssr_import_0__.f)(); + class D {} + (0, __vite_ssr_import_0__.f)(); { - x + x; } - (0,__vite_ssr_import_0__.f)(); - + (0, __vite_ssr_import_0__.f)(); switch (1) { - case 1: - x; - (0,__vite_ssr_import_0__.f)(); - break - }; - - if(0){};(0,__vite_ssr_import_0__.f)(); - - if(0){}else{};(0,__vite_ssr_import_0__.f)(); - - switch(1){};(0,__vite_ssr_import_0__.f)(); - - {}(0,__vite_ssr_import_0__.f)(1) + case 1: + x; + (0, __vite_ssr_import_0__.f)(); + break; + } + if (0) {} + (0, __vite_ssr_import_0__.f)(); + if (0) {} else {} + (0, __vite_ssr_import_0__.f)(); + switch (1) {} + (0, __vite_ssr_import_0__.f)(); + {} + (0, __vite_ssr_import_0__.f)(1); " `) }) @@ -1443,10 +1718,14 @@ const c = () => { ), ).toMatchInlineSnapshot( ` - "const __vite_ssr_import_0__ = await __vite_ssr_import__("a", {"importedNames":["default"]}); + "const __vite_ssr_import_0__ = await __vite_ssr_import__("a", { importedNames: ["default"] }); const c = () => { - if(true){return};(0,__vite_ssr_import_0__.default)(1,{}) - }" + if (true) { + return; + } + (0, __vite_ssr_import_0__.default)(1, {}); + }; + " `, ) }) @@ -1501,9 +1780,8 @@ test('combine mappings', async () => { 'virtual:test-mappings:null', ) expect(result?.map).toMatchInlineSnapshot(` - SourceMap { - "file": undefined, - "mappings": "AAAA,8BAAc,CAAC,CAAC,IAAI,CAAC;", + { + "mappings": "AAAA,+BAAe", "names": [], "sources": [ "virtual:test-mappings:null", @@ -1523,3 +1801,29 @@ test('combine mappings', async () => { `) } }) + +test.skip('deps', async () => { + const result = await ssrTransformSimple(`\ +import a from "a"; +export { b } from "b"; +export * from "c"; +export * as d from "d"; +import("e"); +`) + expect({ + deps: result?.deps, + dynamicDeps: result?.dynamicDeps, + }).toMatchInlineSnapshot(` + { + "deps": [ + "a", + "b", + "c", + "d", + ], + "dynamicDeps": [ + "e", + ], + } + `) +}) diff --git a/packages/vite/src/node/ssr/runtime/__tests__/fixtures/has-error.js b/packages/vite/src/node/ssr/runtime/__tests__/fixtures/has-error.js index 807d1c8af46b47..a546d38759ffbe 100644 --- a/packages/vite/src/node/ssr/runtime/__tests__/fixtures/has-error.js +++ b/packages/vite/src/node/ssr/runtime/__tests__/fixtures/has-error.js @@ -1,2 +1,2 @@ -// comment +{}; // comment only on the 1st line breaks due to https://github.com/vitejs/vite/issues/19627 throw new Error('module error') diff --git a/packages/vite/src/node/ssr/runtime/__tests__/server-source-maps.spec.ts b/packages/vite/src/node/ssr/runtime/__tests__/server-source-maps.spec.ts index b519ee4dd0a7ee..a6b8946b470c7c 100644 --- a/packages/vite/src/node/ssr/runtime/__tests__/server-source-maps.spec.ts +++ b/packages/vite/src/node/ssr/runtime/__tests__/server-source-maps.spec.ts @@ -63,6 +63,9 @@ describe('module runner initialization', async () => { expect(serializeStack(server, methodErrorNew)).toBe( ' at Module.throwError (/fixtures/throws-error-method.ts:11:9)', ) + + // TODO: test stacktrace on first line + // https://github.com/vitejs/vite/issues/19627 }) it('deep stacktrace', async ({ runner, server }) => { diff --git a/packages/vite/src/node/ssr/ssrTransform.ts b/packages/vite/src/node/ssr/ssrTransform.ts index cd3492ea05813e..774fe15278380e 100644 --- a/packages/vite/src/node/ssr/ssrTransform.ts +++ b/packages/vite/src/node/ssr/ssrTransform.ts @@ -18,6 +18,7 @@ import { extract_names as extractNames } from 'periscopic' import { walk as eswalk } from 'estree-walker' import type { RawSourceMap } from '@ampproject/remapping' import { parseAstAsync as rolldownParseAstAsync } from 'rolldown/parseAst' +import { moduleRunnerTransform } from 'rolldown/experimental' import type { TransformResult } from '../server/transformRequest' import { combineSourcemaps, @@ -84,6 +85,44 @@ async function ssrTransformScript( url: string, originalCode: string, ): Promise { + if (!process.env['ROLLDOWN_VITE_OLD_MODULE_RUNNER_TRANSFORM']) { + const result = moduleRunnerTransform('test.js', code, { sourcemap: true }) + if (result.errors.length) { + // eslint-disable-next-line no-console + console.log(JSON.stringify(result.errors, null, 2), '\n', code) + throw new AggregateError(result.errors) + } + let map: TransformResult['map'] = inMap + if (inMap?.mappings === '') { + map = inMap + } else if (result.map) { + map = result.map as SourceMap + map.sources = [path.basename(url)] + // needs to use originalCode instead of code + // because code might be already transformed even if map is null + map.sourcesContent = [originalCode] + if ( + inMap && + inMap.mappings && + 'sources' in inMap && + inMap.sources.length > 0 + ) { + map = combineSourcemaps(url, [ + map as RawSourceMap, + inMap as RawSourceMap, + ]) as SourceMap + } + } + + return { + code: result.code, + map, + ssr: true, + deps: [...result.deps], + dynamicDeps: [...result.dynamicDeps], + } + } + const s = new MagicString(code) let ast: any