From feadb33a0373c2282151d7a927c7740412361d2b Mon Sep 17 00:00:00 2001 From: daiwei Date: Sat, 8 Feb 2025 15:41:01 +0800 Subject: [PATCH 1/4] fix(ssr): support resolve tag name from _attrs in transition group rendering --- .../__tests__/ssrTransitionGroup.spec.ts | 12 +++++++ .../transforms/ssrTransformTransitionGroup.ts | 33 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/packages/compiler-ssr/__tests__/ssrTransitionGroup.spec.ts b/packages/compiler-ssr/__tests__/ssrTransitionGroup.spec.ts index 82122e621c7..af83e3032e6 100644 --- a/packages/compiler-ssr/__tests__/ssrTransitionGroup.spec.ts +++ b/packages/compiler-ssr/__tests__/ssrTransitionGroup.spec.ts @@ -11,11 +11,17 @@ describe('transition-group', () => { "const { ssrRenderList: _ssrRenderList } = require("vue/server-renderer") return function ssrRender(_ctx, _push, _parent, _attrs) { + if (_attrs.tag) { + _push(\`<\${_attrs.tag}>\`) + } _push(\`\`) _ssrRenderList(_ctx.list, (i) => { _push(\`
\`) }) _push(\`\`) + if (_attrs.tag) { + _push(\`\`) + } }" `) }) @@ -114,6 +120,9 @@ describe('transition-group', () => { "const { ssrRenderList: _ssrRenderList } = require("vue/server-renderer") return function ssrRender(_ctx, _push, _parent, _attrs) { + if (_attrs.tag) { + _push(\`<\${_attrs.tag}>\`) + } _push(\`\`) _ssrRenderList(10, (i) => { _push(\`
\`) @@ -125,6 +134,9 @@ describe('transition-group', () => { _push(\`
ok
\`) } _push(\`\`) + if (_attrs.tag) { + _push(\`\`) + } }" `) }) diff --git a/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts b/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts index 27ddebec103..c88142c2ede 100644 --- a/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts +++ b/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts @@ -6,7 +6,10 @@ import { NodeTypes, type TransformContext, buildProps, + createBlockStatement, createCallExpression, + createIfStatement, + createSimpleExpression, findProp, } from '@vue/compiler-dom' import { SSR_RENDER_ATTRS } from '../runtimeHelpers' @@ -112,7 +115,37 @@ export function ssrProcessTransitionGroup( context.pushStringPart(``) } } else { + // #12827 _attrs fallthrough may contain tag property + const hasFallthroughAttrs = node.props.some( + p => + p.type === NodeTypes.DIRECTIVE && + p.name === 'bind' && + p.exp && + p.exp.type === NodeTypes.SIMPLE_EXPRESSION && + p.exp.content === '_attrs', + ) + if (hasFallthroughAttrs) { + context.pushStatement( + createIfStatement( + createSimpleExpression('_attrs.tag'), + createBlockStatement([ + createSimpleExpression('_push(`<${_attrs.tag}>`)'), + ]), + ), + ) + } // fragment processChildren(node, context, true, true, true) + + if (hasFallthroughAttrs) { + context.pushStatement( + createIfStatement( + createSimpleExpression('_attrs.tag'), + createBlockStatement([ + createSimpleExpression('_push(``)'), + ]), + ), + ) + } } } From b6ec6e94518edee2d69ab68362903d1f5ec40300 Mon Sep 17 00:00:00 2001 From: daiwei Date: Sat, 8 Feb 2025 15:50:06 +0800 Subject: [PATCH 2/4] chore: update --- .../compiler-ssr/__tests__/ssrTransitionGroup.spec.ts | 8 ++++---- .../src/transforms/ssrTransformTransitionGroup.ts | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/compiler-ssr/__tests__/ssrTransitionGroup.spec.ts b/packages/compiler-ssr/__tests__/ssrTransitionGroup.spec.ts index af83e3032e6..99a9933f1e6 100644 --- a/packages/compiler-ssr/__tests__/ssrTransitionGroup.spec.ts +++ b/packages/compiler-ssr/__tests__/ssrTransitionGroup.spec.ts @@ -11,7 +11,7 @@ describe('transition-group', () => { "const { ssrRenderList: _ssrRenderList } = require("vue/server-renderer") return function ssrRender(_ctx, _push, _parent, _attrs) { - if (_attrs.tag) { + if (_attrs && _attrs.tag) { _push(\`<\${_attrs.tag}>\`) } _push(\`\`) @@ -19,7 +19,7 @@ describe('transition-group', () => { _push(\`
\`) }) _push(\`\`) - if (_attrs.tag) { + if (_attrs && _attrs.tag) { _push(\`\`) } }" @@ -120,7 +120,7 @@ describe('transition-group', () => { "const { ssrRenderList: _ssrRenderList } = require("vue/server-renderer") return function ssrRender(_ctx, _push, _parent, _attrs) { - if (_attrs.tag) { + if (_attrs && _attrs.tag) { _push(\`<\${_attrs.tag}>\`) } _push(\`\`) @@ -134,7 +134,7 @@ describe('transition-group', () => { _push(\`
ok
\`) } _push(\`\`) - if (_attrs.tag) { + if (_attrs && _attrs.tag) { _push(\`\`) } }" diff --git a/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts b/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts index c88142c2ede..4945d1e3a84 100644 --- a/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts +++ b/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts @@ -127,7 +127,7 @@ export function ssrProcessTransitionGroup( if (hasFallthroughAttrs) { context.pushStatement( createIfStatement( - createSimpleExpression('_attrs.tag'), + createSimpleExpression('_attrs && _attrs.tag'), createBlockStatement([ createSimpleExpression('_push(`<${_attrs.tag}>`)'), ]), @@ -140,7 +140,7 @@ export function ssrProcessTransitionGroup( if (hasFallthroughAttrs) { context.pushStatement( createIfStatement( - createSimpleExpression('_attrs.tag'), + createSimpleExpression('_attrs && _attrs.tag'), createBlockStatement([ createSimpleExpression('_push(``)'), ]), From bac645bb0cf8c3e95f512ab8359f89c43b2b2d05 Mon Sep 17 00:00:00 2001 From: daiwei Date: Sat, 8 Feb 2025 15:55:43 +0800 Subject: [PATCH 3/4] chore: update codegen --- .../__tests__/ssrTransitionGroup.spec.ts | 18 ++++++++++-------- .../compiler-ssr/src/ssrCodegenTransform.ts | 3 ++- .../transforms/ssrTransformTransitionGroup.ts | 15 +++++++-------- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/packages/compiler-ssr/__tests__/ssrTransitionGroup.spec.ts b/packages/compiler-ssr/__tests__/ssrTransitionGroup.spec.ts index 99a9933f1e6..cd98d8c7e2a 100644 --- a/packages/compiler-ssr/__tests__/ssrTransitionGroup.spec.ts +++ b/packages/compiler-ssr/__tests__/ssrTransitionGroup.spec.ts @@ -11,16 +11,17 @@ describe('transition-group', () => { "const { ssrRenderList: _ssrRenderList } = require("vue/server-renderer") return function ssrRender(_ctx, _push, _parent, _attrs) { - if (_attrs && _attrs.tag) { - _push(\`<\${_attrs.tag}>\`) + const _tag = _attrs && _attrs.tag + if (_tag) { + _push(\`<\${_tag}>\`) } _push(\`\`) _ssrRenderList(_ctx.list, (i) => { _push(\`
\`) }) _push(\`\`) - if (_attrs && _attrs.tag) { - _push(\`\`) + if (_tag) { + _push(\`\`) } }" `) @@ -120,8 +121,9 @@ describe('transition-group', () => { "const { ssrRenderList: _ssrRenderList } = require("vue/server-renderer") return function ssrRender(_ctx, _push, _parent, _attrs) { - if (_attrs && _attrs.tag) { - _push(\`<\${_attrs.tag}>\`) + const _tag = _attrs && _attrs.tag + if (_tag) { + _push(\`<\${_tag}>\`) } _push(\`\`) _ssrRenderList(10, (i) => { @@ -134,8 +136,8 @@ describe('transition-group', () => { _push(\`
ok
\`) } _push(\`\`) - if (_attrs && _attrs.tag) { - _push(\`\`) + if (_tag) { + _push(\`\`) } }" `) diff --git a/packages/compiler-ssr/src/ssrCodegenTransform.ts b/packages/compiler-ssr/src/ssrCodegenTransform.ts index 536cbb5c1e9..0d09887317f 100644 --- a/packages/compiler-ssr/src/ssrCodegenTransform.ts +++ b/packages/compiler-ssr/src/ssrCodegenTransform.ts @@ -4,6 +4,7 @@ import { type CompilerError, type CompilerOptions, ElementTypes, + type ExpressionNode, type IfStatement, type JSChildNode, NodeTypes, @@ -84,7 +85,7 @@ export interface SSRTransformContext { onError: (error: CompilerError) => void helper(name: T): T pushStringPart(part: TemplateLiteral['elements'][0]): void - pushStatement(statement: IfStatement | CallExpression): void + pushStatement(statement: IfStatement | CallExpression | ExpressionNode): void } function createSSRTransformContext( diff --git a/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts b/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts index 4945d1e3a84..e1669a59403 100644 --- a/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts +++ b/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts @@ -125,12 +125,13 @@ export function ssrProcessTransitionGroup( p.exp.content === '_attrs', ) if (hasFallthroughAttrs) { + context.pushStatement( + createSimpleExpression('const _tag = _attrs && _attrs.tag'), + ) context.pushStatement( createIfStatement( - createSimpleExpression('_attrs && _attrs.tag'), - createBlockStatement([ - createSimpleExpression('_push(`<${_attrs.tag}>`)'), - ]), + createSimpleExpression('_tag'), + createBlockStatement([createSimpleExpression('_push(`<${_tag}>`)')]), ), ) } @@ -140,10 +141,8 @@ export function ssrProcessTransitionGroup( if (hasFallthroughAttrs) { context.pushStatement( createIfStatement( - createSimpleExpression('_attrs && _attrs.tag'), - createBlockStatement([ - createSimpleExpression('_push(``)'), - ]), + createSimpleExpression('_tag'), + createBlockStatement([createSimpleExpression('_push(``)')]), ), ) } From 92bf78e48ee81f2258989a19576f562ff4696bb4 Mon Sep 17 00:00:00 2001 From: daiwei Date: Sat, 8 Feb 2025 16:06:34 +0800 Subject: [PATCH 4/4] chore: update codegen test: add test --- .../__tests__/ssrTransitionGroup.spec.ts | 4 ++-- .../transforms/ssrTransformTransitionGroup.ts | 6 ++++-- .../__tests__/ssrAttrFallthrough.spec.ts | 16 ++++++++++++++++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/packages/compiler-ssr/__tests__/ssrTransitionGroup.spec.ts b/packages/compiler-ssr/__tests__/ssrTransitionGroup.spec.ts index cd98d8c7e2a..4ca320b78b5 100644 --- a/packages/compiler-ssr/__tests__/ssrTransitionGroup.spec.ts +++ b/packages/compiler-ssr/__tests__/ssrTransitionGroup.spec.ts @@ -11,7 +11,7 @@ describe('transition-group', () => { "const { ssrRenderList: _ssrRenderList } = require("vue/server-renderer") return function ssrRender(_ctx, _push, _parent, _attrs) { - const _tag = _attrs && _attrs.tag + const _tag = (_attrs && typeof _attrs.tag === 'string') ? _attrs.tag : '' if (_tag) { _push(\`<\${_tag}>\`) } @@ -121,7 +121,7 @@ describe('transition-group', () => { "const { ssrRenderList: _ssrRenderList } = require("vue/server-renderer") return function ssrRender(_ctx, _push, _parent, _attrs) { - const _tag = _attrs && _attrs.tag + const _tag = (_attrs && typeof _attrs.tag === 'string') ? _attrs.tag : '' if (_tag) { _push(\`<\${_tag}>\`) } diff --git a/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts b/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts index e1669a59403..831dffb8393 100644 --- a/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts +++ b/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts @@ -115,7 +115,7 @@ export function ssrProcessTransitionGroup( context.pushStringPart(``) } } else { - // #12827 _attrs fallthrough may contain tag property + // _attrs may contain tag property const hasFallthroughAttrs = node.props.some( p => p.type === NodeTypes.DIRECTIVE && @@ -126,7 +126,9 @@ export function ssrProcessTransitionGroup( ) if (hasFallthroughAttrs) { context.pushStatement( - createSimpleExpression('const _tag = _attrs && _attrs.tag'), + createSimpleExpression( + `const _tag = (_attrs && typeof _attrs.tag === 'string') ? _attrs.tag : ''`, + ), ) context.pushStatement( createIfStatement( diff --git a/packages/server-renderer/__tests__/ssrAttrFallthrough.spec.ts b/packages/server-renderer/__tests__/ssrAttrFallthrough.spec.ts index e8cfa75e77c..66f6688b7f3 100644 --- a/packages/server-renderer/__tests__/ssrAttrFallthrough.spec.ts +++ b/packages/server-renderer/__tests__/ssrAttrFallthrough.spec.ts @@ -75,4 +75,20 @@ describe('ssr: attr fallthrough', () => { `
`, ) }) + + // #12827 + test('with transition-group tag name', async () => { + expect( + await renderToString( + createApp({ + components: { + one: { + template: ``, + }, + }, + template: `

{{i}}

`, + }), + ), + ).toBe(`

1

2

`) + }) })