fix(compiler-ssr): fix node clone edge case caused by AST reuse (#9983)

close #9981
This commit is contained in:
edison 2024-01-04 10:52:09 +08:00 committed by GitHub
parent d2d89551bb
commit 7dbdb3edf0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 3 deletions

View File

@ -427,6 +427,31 @@ test('prefixing edge case for reused AST', () => {
expect(code).not.toMatch(`_ctx.t`) expect(code).not.toMatch(`_ctx.t`)
}) })
test('prefixing edge case for reused AST ssr mode', () => {
const src = `
<script setup lang="ts">
import { Foo } from './foo'
</script>
<template>
<Bar>
<template #option="{ foo }"></template>
</Bar>
</template>
`
const { descriptor } = parse(src)
// compileScript triggers importUsageCheck
compileScript(descriptor, { id: 'xxx' })
expect(() =>
compileTemplate({
id: 'xxx',
filename: 'test.vue',
ast: descriptor.template!.ast,
source: descriptor.template!.content,
ssr: true,
}),
).not.toThrowError()
})
interface Pos { interface Pos {
line: number line: number
column: number column: number

View File

@ -55,7 +55,7 @@ import {
ssrProcessTransitionGroup, ssrProcessTransitionGroup,
ssrTransformTransitionGroup, ssrTransformTransitionGroup,
} from './ssrTransformTransitionGroup' } from './ssrTransformTransitionGroup'
import { extend, isArray, isObject, isSymbol } from '@vue/shared' import { extend, isArray, isObject, isPlainObject, isSymbol } from '@vue/shared'
import { buildSSRProps } from './ssrTransformElement' import { buildSSRProps } from './ssrTransformElement'
import { import {
ssrProcessTransition, ssrProcessTransition,
@ -121,6 +121,8 @@ export const ssrTransformComponent: NodeTransform = (node, context) => {
const vnodeBranches: ReturnStatement[] = [] const vnodeBranches: ReturnStatement[] = []
const clonedNode = clone(node) const clonedNode = clone(node)
console.log(clonedNode)
return function ssrPostTransformComponent() { return function ssrPostTransformComponent() {
// Using the cloned node, build the normal VNode-based branches (for // Using the cloned node, build the normal VNode-based branches (for
// fallback in case the child is render-fn based). Store them in an array // fallback in case the child is render-fn based). Store them in an array
@ -371,10 +373,10 @@ function subTransform(
function clone(v: any): any { function clone(v: any): any {
if (isArray(v)) { if (isArray(v)) {
return v.map(clone) return v.map(clone)
} else if (isObject(v)) { } else if (isPlainObject(v)) {
const res: any = {} const res: any = {}
for (const key in v) { for (const key in v) {
res[key] = clone(v[key]) res[key] = clone(v[key as keyof typeof v])
} }
return res return res
} else { } else {