Skip to content

Commit 81327eb

Browse files
authoredAug 3, 2024··
perf(ssr): do a single-pass over AST with node cache arrays (#17812)
1 parent 11644f4 commit 81327eb

File tree

1 file changed

+57
-36
lines changed

1 file changed

+57
-36
lines changed
 

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

+57-36
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@ import path from 'node:path'
22
import MagicString from 'magic-string'
33
import type { SourceMap } from 'rollup'
44
import type {
5+
ExportAllDeclaration,
6+
ExportDefaultDeclaration,
7+
ExportNamedDeclaration,
58
Function as FunctionNode,
69
Identifier,
10+
ImportDeclaration,
711
Pattern,
812
Property,
913
VariableDeclaration,
@@ -130,53 +134,70 @@ async function ssrTransformScript(
130134
)
131135
}
132136

133-
// 1. check all import statements and record id -> importName map
137+
const imports: (ImportDeclaration & { start: number; end: number })[] = []
138+
const exports: ((
139+
| ExportNamedDeclaration
140+
| ExportDefaultDeclaration
141+
| ExportAllDeclaration
142+
) & { start: number; end: number })[] = []
143+
134144
for (const node of ast.body as Node[]) {
145+
if (node.type === 'ImportDeclaration') {
146+
imports.push(node)
147+
} else if (
148+
node.type === 'ExportNamedDeclaration' ||
149+
node.type === 'ExportDefaultDeclaration' ||
150+
node.type === 'ExportAllDeclaration'
151+
) {
152+
exports.push(node)
153+
}
154+
}
155+
156+
// 1. check all import statements and record id -> importName map
157+
for (const node of imports) {
135158
// import foo from 'foo' --> foo -> __import_foo__.default
136159
// import { baz } from 'foo' --> baz -> __import_foo__.baz
137160
// import * as ok from 'foo' --> ok -> __import_foo__
138-
if (node.type === 'ImportDeclaration') {
139-
const importId = defineImport(hoistIndex, node.source.value as string, {
140-
importedNames: node.specifiers
141-
.map((s) => {
142-
if (s.type === 'ImportSpecifier')
143-
return s.imported.type === 'Identifier'
144-
? s.imported.name
145-
: // @ts-expect-error TODO: Estree types don't consider arbitrary module namespace specifiers yet
146-
s.imported.value
147-
else if (s.type === 'ImportDefaultSpecifier') return 'default'
148-
})
149-
.filter(isDefined),
150-
})
151-
s.remove(node.start, node.end)
152-
for (const spec of node.specifiers) {
153-
if (spec.type === 'ImportSpecifier') {
154-
if (spec.imported.type === 'Identifier') {
155-
idToImportMap.set(
156-
spec.local.name,
157-
`${importId}.${spec.imported.name}`,
158-
)
159-
} else {
160-
idToImportMap.set(
161-
spec.local.name,
162-
`${importId}[${
163-
// @ts-expect-error TODO: Estree types don't consider arbitrary module namespace specifiers yet
164-
JSON.stringify(spec.imported.value)
165-
}]`,
166-
)
167-
}
168-
} else if (spec.type === 'ImportDefaultSpecifier') {
169-
idToImportMap.set(spec.local.name, `${importId}.default`)
161+
const importId = defineImport(hoistIndex, node.source.value as string, {
162+
importedNames: node.specifiers
163+
.map((s) => {
164+
if (s.type === 'ImportSpecifier')
165+
return s.imported.type === 'Identifier'
166+
? s.imported.name
167+
: // @ts-expect-error TODO: Estree types don't consider arbitrary module namespace specifiers yet
168+
s.imported.value
169+
else if (s.type === 'ImportDefaultSpecifier') return 'default'
170+
})
171+
.filter(isDefined),
172+
})
173+
s.remove(node.start, node.end)
174+
for (const spec of node.specifiers) {
175+
if (spec.type === 'ImportSpecifier') {
176+
if (spec.imported.type === 'Identifier') {
177+
idToImportMap.set(
178+
spec.local.name,
179+
`${importId}.${spec.imported.name}`,
180+
)
170181
} else {
171-
// namespace specifier
172-
idToImportMap.set(spec.local.name, importId)
182+
idToImportMap.set(
183+
spec.local.name,
184+
`${importId}[${
185+
// @ts-expect-error TODO: Estree types don't consider arbitrary module namespace specifiers yet
186+
JSON.stringify(spec.imported.value)
187+
}]`,
188+
)
173189
}
190+
} else if (spec.type === 'ImportDefaultSpecifier') {
191+
idToImportMap.set(spec.local.name, `${importId}.default`)
192+
} else {
193+
// namespace specifier
194+
idToImportMap.set(spec.local.name, importId)
174195
}
175196
}
176197
}
177198

178199
// 2. check all export statements and define exports
179-
for (const node of ast.body as Node[]) {
200+
for (const node of exports) {
180201
// named exports
181202
if (node.type === 'ExportNamedDeclaration') {
182203
if (node.declaration) {

0 commit comments

Comments
 (0)
Please sign in to comment.