Skip to content

Commit

Permalink
fix(ssr): hoist statements after hashbang (#12985)
Browse files Browse the repository at this point in the history
  • Loading branch information
bluwy committed Apr 24, 2023
1 parent e0b1197 commit 07bd6d1
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 4 deletions.
13 changes: 13 additions & 0 deletions packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts
Expand Up @@ -743,6 +743,19 @@ console.log("it can parse the hashbang")`,
`)
})

test('import hoisted after hashbang', async () => {
expect(
await ssrTransformSimpleCode(
`#!/usr/bin/env node
import "foo"`,
),
).toMatchInlineSnapshot(`
"#!/usr/bin/env node
const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"foo\\");
"
`)
})

// #10289
test('track scope by class, function, condition blocks', async () => {
const code = `
Expand Down
13 changes: 9 additions & 4 deletions packages/vite/src/node/ssr/ssrTransform.ts
Expand Up @@ -33,6 +33,8 @@ export const ssrDynamicImportKey = `__vite_ssr_dynamic_import__`
export const ssrExportAllKey = `__vite_ssr_exportAll__`
export const ssrImportMetaKey = `__vite_ssr_import_meta__`

const hashbangRE = /^#!.*\n/

export async function ssrTransform(
code: string,
inMap: SourceMap | null,
Expand Down Expand Up @@ -92,13 +94,16 @@ async function ssrTransformScript(
const idToImportMap = new Map<string, string>()
const declaredConst = new Set<string>()

// hoist at the start of the file, after the hashbang
const hoistIndex = code.match(hashbangRE)?.[0].length ?? 0

function defineImport(source: string) {
deps.add(source)
const importId = `__vite_ssr_import_${uid++}__`
// There will be an error if the module is called before it is imported,
// so the module import statement is hoisted to the top
s.appendLeft(
0,
hoistIndex,
`const ${importId} = await ${ssrImportKey}(${JSON.stringify(source)});\n`,
)
return importId
Expand Down Expand Up @@ -165,7 +170,7 @@ async function ssrTransformScript(
// hoist re-exports near the defined import so they are immediately exported
for (const spec of node.specifiers) {
defineExport(
0,
hoistIndex,
spec.exported.name,
`${importId}.${spec.local.name}`,
)
Expand Down Expand Up @@ -214,9 +219,9 @@ async function ssrTransformScript(
const importId = defineImport(node.source.value as string)
// hoist re-exports near the defined import so they are immediately exported
if (node.exported) {
defineExport(0, node.exported.name, `${importId}`)
defineExport(hoistIndex, node.exported.name, `${importId}`)
} else {
s.appendLeft(0, `${ssrExportAllKey}(${importId});\n`)
s.appendLeft(hoistIndex, `${ssrExportAllKey}(${importId});\n`)
}
}
}
Expand Down

0 comments on commit 07bd6d1

Please sign in to comment.