Skip to content

Commit 07bd6d1

Browse files
authored
fix(ssr): hoist statements after hashbang (#12985)
1 parent e0b1197 commit 07bd6d1

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts

+13
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,19 @@ console.log("it can parse the hashbang")`,
743743
`)
744744
})
745745

746+
test('import hoisted after hashbang', async () => {
747+
expect(
748+
await ssrTransformSimpleCode(
749+
`#!/usr/bin/env node
750+
import "foo"`,
751+
),
752+
).toMatchInlineSnapshot(`
753+
"#!/usr/bin/env node
754+
const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"foo\\");
755+
"
756+
`)
757+
})
758+
746759
// #10289
747760
test('track scope by class, function, condition blocks', async () => {
748761
const code = `

packages/vite/src/node/ssr/ssrTransform.ts

+9-4
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ export const ssrDynamicImportKey = `__vite_ssr_dynamic_import__`
3333
export const ssrExportAllKey = `__vite_ssr_exportAll__`
3434
export const ssrImportMetaKey = `__vite_ssr_import_meta__`
3535

36+
const hashbangRE = /^#!.*\n/
37+
3638
export async function ssrTransform(
3739
code: string,
3840
inMap: SourceMap | null,
@@ -92,13 +94,16 @@ async function ssrTransformScript(
9294
const idToImportMap = new Map<string, string>()
9395
const declaredConst = new Set<string>()
9496

97+
// hoist at the start of the file, after the hashbang
98+
const hoistIndex = code.match(hashbangRE)?.[0].length ?? 0
99+
95100
function defineImport(source: string) {
96101
deps.add(source)
97102
const importId = `__vite_ssr_import_${uid++}__`
98103
// There will be an error if the module is called before it is imported,
99104
// so the module import statement is hoisted to the top
100105
s.appendLeft(
101-
0,
106+
hoistIndex,
102107
`const ${importId} = await ${ssrImportKey}(${JSON.stringify(source)});\n`,
103108
)
104109
return importId
@@ -165,7 +170,7 @@ async function ssrTransformScript(
165170
// hoist re-exports near the defined import so they are immediately exported
166171
for (const spec of node.specifiers) {
167172
defineExport(
168-
0,
173+
hoistIndex,
169174
spec.exported.name,
170175
`${importId}.${spec.local.name}`,
171176
)
@@ -214,9 +219,9 @@ async function ssrTransformScript(
214219
const importId = defineImport(node.source.value as string)
215220
// hoist re-exports near the defined import so they are immediately exported
216221
if (node.exported) {
217-
defineExport(0, node.exported.name, `${importId}`)
222+
defineExport(hoistIndex, node.exported.name, `${importId}`)
218223
} else {
219-
s.appendLeft(0, `${ssrExportAllKey}(${importId});\n`)
224+
s.appendLeft(hoistIndex, `${ssrExportAllKey}(${importId});\n`)
220225
}
221226
}
222227
}

0 commit comments

Comments
 (0)