From 69654c650c35b22c8795b0c34d44fb120cf85cef Mon Sep 17 00:00:00 2001 From: daiwei Date: Thu, 4 Jan 2024 09:45:23 +0800 Subject: [PATCH 1/4] fix(ssr): clone node support Set and Map --- .../src/transforms/ssrTransformComponent.ts | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/packages/compiler-ssr/src/transforms/ssrTransformComponent.ts b/packages/compiler-ssr/src/transforms/ssrTransformComponent.ts index c179cd50cf7..bd99b661dde 100644 --- a/packages/compiler-ssr/src/transforms/ssrTransformComponent.ts +++ b/packages/compiler-ssr/src/transforms/ssrTransformComponent.ts @@ -372,11 +372,25 @@ function clone(v: any): any { if (isArray(v)) { return v.map(clone) } else if (isObject(v)) { - const res: any = {} - for (const key in v) { - res[key] = clone(v[key]) + if (v instanceof Map) { + const res = new Map() + v.forEach((value: any, key: any) => { + res.set(clone(key), clone(value)) + }) + return res + } else if (v instanceof Set) { + const res = new Set() + v.forEach((value: any) => { + res.add(clone(value)) + }) + return res + } else { + const res: any = {} + for (const key in v) { + res[key] = clone(v[key]) + } + return res } - return res } else { return v } From 64615d2bb834a73fcc7d153aff8966a51698f04d Mon Sep 17 00:00:00 2001 From: daiwei Date: Thu, 4 Jan 2024 10:13:21 +0800 Subject: [PATCH 2/4] test: add test case --- .../__tests__/compileTemplate.spec.ts | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/packages/compiler-sfc/__tests__/compileTemplate.spec.ts b/packages/compiler-sfc/__tests__/compileTemplate.spec.ts index 7ab64bb2667..f5d1d335a81 100644 --- a/packages/compiler-sfc/__tests__/compileTemplate.spec.ts +++ b/packages/compiler-sfc/__tests__/compileTemplate.spec.ts @@ -427,6 +427,30 @@ test('prefixing edge case for reused AST', () => { expect(code).not.toMatch(`_ctx.t`) }) +test('prefixing edge case for reused AST ssr mode', () => { + const src = ` + + + ` + const { descriptor } = parse(src) + // compileScript triggers importUsageCheck + compileScript(descriptor, { id: 'xxx' }) + const { code } = compileTemplate({ + id: 'xxx', + filename: 'test.vue', + ast: descriptor.template!.ast, + source: descriptor.template!.content, + ssr: true, + }) + expect(code).not.toMatch(`_ctx.t`) +}) + interface Pos { line: number column: number From 2c1dbc97bb1a467ec23ce06bb288b3911d736fad Mon Sep 17 00:00:00 2001 From: daiwei Date: Thu, 4 Jan 2024 10:22:16 +0800 Subject: [PATCH 3/4] test: improve test --- .../__tests__/compileTemplate.spec.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/compiler-sfc/__tests__/compileTemplate.spec.ts b/packages/compiler-sfc/__tests__/compileTemplate.spec.ts index f5d1d335a81..45dc54a69db 100644 --- a/packages/compiler-sfc/__tests__/compileTemplate.spec.ts +++ b/packages/compiler-sfc/__tests__/compileTemplate.spec.ts @@ -441,14 +441,15 @@ test('prefixing edge case for reused AST ssr mode', () => { const { descriptor } = parse(src) // compileScript triggers importUsageCheck compileScript(descriptor, { id: 'xxx' }) - const { code } = compileTemplate({ - id: 'xxx', - filename: 'test.vue', - ast: descriptor.template!.ast, - source: descriptor.template!.content, - ssr: true, - }) - expect(code).not.toMatch(`_ctx.t`) + expect(() => + compileTemplate({ + id: 'xxx', + filename: 'test.vue', + ast: descriptor.template!.ast, + source: descriptor.template!.content, + ssr: true, + }), + ).not.toThrowError() }) interface Pos { From a4bcbe8fef805b8c7c073546196c1e10a0b58101 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 4 Jan 2024 10:47:26 +0800 Subject: [PATCH 4/4] perf: simplify clone --- .../src/transforms/ssrTransformComponent.ts | 28 ++++++------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/packages/compiler-ssr/src/transforms/ssrTransformComponent.ts b/packages/compiler-ssr/src/transforms/ssrTransformComponent.ts index bd99b661dde..3146a90a2d6 100644 --- a/packages/compiler-ssr/src/transforms/ssrTransformComponent.ts +++ b/packages/compiler-ssr/src/transforms/ssrTransformComponent.ts @@ -55,7 +55,7 @@ import { ssrProcessTransitionGroup, 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 { ssrProcessTransition, @@ -121,6 +121,8 @@ export const ssrTransformComponent: NodeTransform = (node, context) => { const vnodeBranches: ReturnStatement[] = [] const clonedNode = clone(node) + console.log(clonedNode) + return function ssrPostTransformComponent() { // 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 @@ -371,26 +373,12 @@ function subTransform( function clone(v: any): any { if (isArray(v)) { return v.map(clone) - } else if (isObject(v)) { - if (v instanceof Map) { - const res = new Map() - v.forEach((value: any, key: any) => { - res.set(clone(key), clone(value)) - }) - return res - } else if (v instanceof Set) { - const res = new Set() - v.forEach((value: any) => { - res.add(clone(value)) - }) - return res - } else { - const res: any = {} - for (const key in v) { - res[key] = clone(v[key]) - } - return res + } else if (isPlainObject(v)) { + const res: any = {} + for (const key in v) { + res[key] = clone(v[key as keyof typeof v]) } + return res } else { return v }