Skip to content

Commit c29f263

Browse files
committed
fix: fix some arbitrary module namespace handling
1 parent fcee890 commit c29f263

File tree

2 files changed

+60
-30
lines changed

2 files changed

+60
-30
lines changed

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

+23-1
Original file line numberDiff line numberDiff line change
@@ -134,14 +134,36 @@ test('export * as from', async () => {
134134
`)
135135
})
136136

137+
test('export * as from arbitrary module namespace identifier', async () => {
138+
expect(
139+
await ssrTransformSimpleCode(`export * as "arbitrary string" from 'vue'`),
140+
).toMatchInlineSnapshot(`
141+
"const __vite_ssr_import_0__ = await __vite_ssr_import__("vue");
142+
143+
Object.defineProperty(__vite_ssr_exports__, "arbitrary string", { enumerable: true, configurable: true, get(){ return __vite_ssr_import_0__ }});"
144+
`)
145+
})
146+
137147
test('export as arbitrary module namespace identifier', async () => {
138148
expect(
139149
await ssrTransformSimpleCode(
140150
`const something = "Something";export { something as "arbitrary string" };`,
141151
),
142152
).toMatchInlineSnapshot(`
143153
"const something = "Something";
144-
Object.defineProperty(__vite_ssr_exports__, "arbitrary string", { enumerable: true, configurable: true, get(){ return something }});"
154+
Object.defineProperty(__vite_ssr_exports__, "arbitrary string", { enumerable: true, configurable: true, get(){ return something }});"
155+
`)
156+
})
157+
158+
test('export as from arbitrary module namespace identifier', async () => {
159+
expect(
160+
await ssrTransformSimpleCode(
161+
`export { "arbitrary string2" as "arbitrary string" } from 'vue';`,
162+
),
163+
).toMatchInlineSnapshot(`
164+
"const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", {"importedNames":["arbitrary string2"]});
165+
166+
Object.defineProperty(__vite_ssr_exports__, "arbitrary string", { enumerable: true, configurable: true, get(){ return __vite_ssr_import_0__["arbitrary string2"] }});"
145167
`)
146168
})
147169

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

+37-29
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type {
88
Function as FunctionNode,
99
Identifier,
1010
ImportDeclaration,
11+
Literal,
1112
Pattern,
1213
Property,
1314
VariableDeclaration,
@@ -130,7 +131,7 @@ async function ssrTransformScript(
130131
function defineExport(position: number, name: string, local = name) {
131132
s.appendLeft(
132133
position,
133-
`\nObject.defineProperty(${ssrModuleExportsKey}, "${name}", ` +
134+
`\nObject.defineProperty(${ssrModuleExportsKey}, ${JSON.stringify(name)}, ` +
134135
`{ enumerable: true, configurable: true, get(){ return ${local} }});`,
135136
)
136137
}
@@ -163,10 +164,7 @@ async function ssrTransformScript(
163164
importedNames: node.specifiers
164165
.map((s) => {
165166
if (s.type === 'ImportSpecifier')
166-
return s.imported.type === 'Identifier'
167-
? s.imported.name
168-
: // @ts-expect-error TODO: Estree types don't consider arbitrary module namespace specifiers yet
169-
s.imported.value
167+
return getIdentifierNameOrLiteralValue(s.imported) as string
170168
else if (s.type === 'ImportDefaultSpecifier') return 'default'
171169
})
172170
.filter(isDefined),
@@ -182,10 +180,7 @@ async function ssrTransformScript(
182180
} else {
183181
idToImportMap.set(
184182
spec.local.name,
185-
`${importId}[${
186-
// @ts-expect-error TODO: Estree types don't consider arbitrary module namespace specifiers yet
187-
JSON.stringify(spec.imported.value)
188-
}]`,
183+
`${importId}[${JSON.stringify(spec.imported.value as string)}]`,
189184
)
190185
}
191186
} else if (spec.type === 'ImportDefaultSpecifier') {
@@ -226,33 +221,39 @@ async function ssrTransformScript(
226221
node.start,
227222
node.source.value as string,
228223
{
229-
importedNames: node.specifiers.map((s) => s.local.name),
224+
importedNames: node.specifiers.map(
225+
(s) => getIdentifierNameOrLiteralValue(s.local) as string,
226+
),
230227
},
231228
)
232229
for (const spec of node.specifiers) {
233-
const exportedAs =
234-
spec.exported.type === 'Identifier'
235-
? spec.exported.name
236-
: // @ts-expect-error TODO: Estree types don't consider arbitrary module namespace specifiers yet
237-
spec.exported.value
238-
239-
defineExport(
240-
node.start,
241-
exportedAs,
242-
`${importId}.${spec.local.name}`,
243-
)
230+
const exportedAs = getIdentifierNameOrLiteralValue(
231+
spec.exported,
232+
) as string
233+
234+
if (spec.local.type === 'Identifier') {
235+
defineExport(
236+
node.start,
237+
exportedAs,
238+
`${importId}.${spec.local.name}`,
239+
)
240+
} else {
241+
defineExport(
242+
node.start,
243+
exportedAs,
244+
`${importId}[${JSON.stringify(spec.local.value as string)}]`,
245+
)
246+
}
244247
}
245248
} else {
246249
// export { foo, bar }
247250
for (const spec of node.specifiers) {
248-
const local = spec.local.name
251+
// spec.local can be Literal only when it has "from 'something'"
252+
const local = (spec.local as Identifier).name
249253
const binding = idToImportMap.get(local)
250-
251-
const exportedAs =
252-
spec.exported.type === 'Identifier'
253-
? spec.exported.name
254-
: // @ts-expect-error TODO: Estree types don't consider arbitrary module namespace specifiers yet
255-
spec.exported.value
254+
const exportedAs = getIdentifierNameOrLiteralValue(
255+
spec.exported,
256+
) as string
256257

257258
defineExport(node.end, exportedAs, binding || local)
258259
}
@@ -292,7 +293,10 @@ async function ssrTransformScript(
292293
s.remove(node.start, node.end)
293294
const importId = defineImport(node.start, node.source.value as string)
294295
if (node.exported) {
295-
defineExport(node.start, node.exported.name, `${importId}`)
296+
const exportedAs = getIdentifierNameOrLiteralValue(
297+
node.exported,
298+
) as string
299+
defineExport(node.start, exportedAs, `${importId}`)
296300
} else {
297301
s.appendLeft(node.start, `${ssrExportAllKey}(${importId});\n`)
298302
}
@@ -377,6 +381,10 @@ async function ssrTransformScript(
377381
}
378382
}
379383

384+
function getIdentifierNameOrLiteralValue(node: Identifier | Literal) {
385+
return node.type === 'Identifier' ? node.name : node.value
386+
}
387+
380388
interface Visitors {
381389
onIdentifier: (
382390
node: Identifier & {

0 commit comments

Comments
 (0)