From 32542fb875b1e277541bc63d5495176c79e243b7 Mon Sep 17 00:00:00 2001 From: daiwei Date: Sat, 16 Aug 2025 10:01:58 +0800 Subject: [PATCH] refactor: hydration --- packages/compiler-core/src/ast.ts | 5 + packages/compiler-core/src/codegen.ts | 1 + packages/compiler-core/src/options.ts | 5 + packages/compiler-core/src/transform.ts | 2 + .../compiler-core/src/transforms/vSlot.ts | 13 +- packages/compiler-sfc/src/compileScript.ts | 5 + packages/compiler-sfc/src/compileTemplate.ts | 1 + .../__tests__/ssrComponent.spec.ts | 9 +- .../compiler-ssr/__tests__/ssrElement.spec.ts | 46 - .../__tests__/ssrFallthroughAttrs.spec.ts | 1 - .../__tests__/ssrInjectCssVars.spec.ts | 1 - .../__tests__/ssrSlotOutlet.spec.ts | 1 - .../__tests__/ssrTransitionGroup.spec.ts | 13 +- .../compiler-ssr/__tests__/ssrVFor.spec.ts | 16 +- .../compiler-ssr/__tests__/ssrVIf.spec.ts | 14 +- .../compiler-ssr/__tests__/ssrVModel.spec.ts | 12 +- .../__tests__/ssrVaporAnchors.spes.ts | 828 ++++ packages/compiler-ssr/__tests__/utils.ts | 8 +- .../compiler-ssr/src/ssrCodegenTransform.ts | 237 +- .../src/transforms/ssrTransformComponent.ts | 228 +- .../src/transforms/ssrTransformSlotOutlet.ts | 6 + .../compiler-ssr/src/transforms/ssrVFor.ts | 13 +- .../compiler-ssr/src/transforms/ssrVIf.ts | 44 +- .../__snapshots__/compile.spec.ts.snap | 18 +- .../__snapshots__/expression.spec.ts.snap | 8 +- .../transformChildren.spec.ts.snap | 18 +- .../__snapshots__/vFor.spec.ts.snap | 40 +- .../transforms/__snapshots__/vIf.spec.ts.snap | 16 +- .../__snapshots__/vSlot.spec.ts.snap | 4 +- .../__snapshots__/vText.spec.ts.snap | 8 +- packages/compiler-vapor/src/generate.ts | 5 +- .../src/generators/operation.ts | 11 +- .../compiler-vapor/src/generators/template.ts | 12 +- .../compiler-vapor/src/generators/text.ts | 2 +- packages/compiler-vapor/src/ir/index.ts | 1 - packages/compiler-vapor/src/transform.ts | 2 +- .../src/transforms/transformChildren.ts | 40 +- .../runtime-core/__tests__/hydration.spec.ts | 42 +- packages/runtime-core/src/apiCreateApp.ts | 11 +- packages/runtime-core/src/hydration.ts | 35 +- .../runtime-vapor/__tests__/hydration.spec.ts | 4013 +++++++---------- .../src/apiCreateDynamicComponent.ts | 10 +- packages/runtime-vapor/src/apiCreateFor.ts | 32 +- packages/runtime-vapor/src/apiCreateIf.ts | 59 +- packages/runtime-vapor/src/block.ts | 35 +- packages/runtime-vapor/src/component.ts | 44 +- packages/runtime-vapor/src/componentSlots.ts | 31 +- packages/runtime-vapor/src/dom/hydration.ts | 152 +- packages/runtime-vapor/src/dom/node.ts | 149 +- packages/runtime-vapor/src/dom/template.ts | 16 +- packages/runtime-vapor/src/index.ts | 2 +- packages/runtime-vapor/src/insertionState.ts | 29 +- packages/runtime-vapor/src/vdomInterop.ts | 203 +- .../server-renderer/__tests__/render.spec.ts | 14 +- .../__tests__/ssrAttrFallthrough.spec.ts | 2 +- .../__tests__/ssrDynamicComponent.spec.ts | 14 +- .../__tests__/ssrScopeId.spec.ts | 12 +- .../server-renderer/__tests__/ssrSlot.spec.ts | 30 +- .../src/helpers/ssrRenderSlot.ts | 21 +- packages/server-renderer/src/render.ts | 16 +- packages/shared/src/domAnchors.ts | 29 +- 61 files changed, 3350 insertions(+), 3345 deletions(-) create mode 100644 packages/compiler-ssr/__tests__/ssrVaporAnchors.spes.ts diff --git a/packages/compiler-core/src/ast.ts b/packages/compiler-core/src/ast.ts index bae13372a9..1ecab369a3 100644 --- a/packages/compiler-core/src/ast.ts +++ b/packages/compiler-core/src/ast.ts @@ -163,6 +163,7 @@ export interface ComponentNode extends BaseElementNode { | MemoExpression // when cached by v-memo | undefined ssrCodegenNode?: CallExpression + anchor?: string } export interface SlotOutletNode extends BaseElementNode { @@ -172,12 +173,14 @@ export interface SlotOutletNode extends BaseElementNode { | CacheExpression // when cached by v-once | undefined ssrCodegenNode?: CallExpression + anchor?: string } export interface TemplateNode extends BaseElementNode { tagType: ElementTypes.TEMPLATE // TemplateNode is a container type that always gets compiled away codegenNode: undefined + anchor?: string } export interface TextNode extends Node { @@ -287,6 +290,7 @@ export interface IfNode extends Node { type: NodeTypes.IF branches: IfBranchNode[] codegenNode?: IfConditionalExpression | CacheExpression //
+ anchor?: string } export interface IfBranchNode extends Node { @@ -306,6 +310,7 @@ export interface ForNode extends Node { parseResult: ForParseResult children: TemplateChildNode[] codegenNode?: ForCodegenNode + anchor?: string } export interface ForParseResult { diff --git a/packages/compiler-core/src/codegen.ts b/packages/compiler-core/src/codegen.ts index 99020bcf1a..468acd7f2b 100644 --- a/packages/compiler-core/src/codegen.ts +++ b/packages/compiler-core/src/codegen.ts @@ -136,6 +136,7 @@ export interface CodegenContext | 'inline' | 'vaporRuntimeModuleName' | 'expressionPlugins' + | 'vapor' > { source: string code: string diff --git a/packages/compiler-core/src/options.ts b/packages/compiler-core/src/options.ts index 9983071609..03a32e0113 100644 --- a/packages/compiler-core/src/options.ts +++ b/packages/compiler-core/src/options.ts @@ -220,6 +220,11 @@ interface SharedTransformCodegenOptions { * @default 'template.vue.html' */ filename?: string + + /** + * Indicates vapor component + */ + vapor?: boolean } export interface TransformOptions diff --git a/packages/compiler-core/src/transform.ts b/packages/compiler-core/src/transform.ts index 10121fb5d5..11077df625 100644 --- a/packages/compiler-core/src/transform.ts +++ b/packages/compiler-core/src/transform.ts @@ -146,6 +146,7 @@ export function createTransformContext( slotted = true, ssr = false, inSSR = false, + vapor = false, ssrCssVars = ``, bindingMetadata = EMPTY_OBJ, inline = false, @@ -173,6 +174,7 @@ export function createTransformContext( slotted, ssr, inSSR, + vapor, ssrCssVars, bindingMetadata, inline, diff --git a/packages/compiler-core/src/transforms/vSlot.ts b/packages/compiler-core/src/transforms/vSlot.ts index 43296dcc9b..da29d0de89 100644 --- a/packages/compiler-core/src/transforms/vSlot.ts +++ b/packages/compiler-core/src/transforms/vSlot.ts @@ -100,6 +100,7 @@ export type SlotFnBuilder = ( vFor: DirectiveNode | undefined, slotChildren: TemplateChildNode[], loc: SourceLocation, + parent: ElementNode, ) => FunctionExpression const buildClientSlotFn: SlotFnBuilder = (props, _vForExp, children, loc) => @@ -147,7 +148,7 @@ export function buildSlots( slotsProperties.push( createObjectProperty( arg || createSimpleExpression('default', true), - buildSlotFn(exp, undefined, children, loc), + buildSlotFn(exp, undefined, children, loc, node), ), ) } @@ -200,7 +201,13 @@ export function buildSlots( } const vFor = findDir(slotElement, 'for') - const slotFunction = buildSlotFn(slotProps, vFor, slotChildren, slotLoc) + const slotFunction = buildSlotFn( + slotProps, + vFor, + slotChildren, + slotLoc, + slotElement, + ) // check if this slot is conditional (v-if/v-for) let vIf: DirectiveNode | undefined @@ -304,7 +311,7 @@ export function buildSlots( props: ExpressionNode | undefined, children: TemplateChildNode[], ) => { - const fn = buildSlotFn(props, undefined, children, loc) + const fn = buildSlotFn(props, undefined, children, loc, node) if (__COMPAT__ && context.compatConfig) { fn.isNonScopedSlot = true } diff --git a/packages/compiler-sfc/src/compileScript.ts b/packages/compiler-sfc/src/compileScript.ts index 54ca260bdd..686747458e 100644 --- a/packages/compiler-sfc/src/compileScript.ts +++ b/packages/compiler-sfc/src/compileScript.ts @@ -980,6 +980,11 @@ export function compileScript( ctx.hasDefineExposeCall || options.inlineTemplate ? `` : ` __expose();\n` // wrap setup code with function. if (ctx.isTS) { + // in SSR, always use defineComponent, so __vapor flag is required + if (ssr && vapor) { + runtimeOptions += `\n __vapor: true,` + } + // for TS, make sure the exported type is still valid type with // correct props information // we have to use object spread for types to be merged properly diff --git a/packages/compiler-sfc/src/compileTemplate.ts b/packages/compiler-sfc/src/compileTemplate.ts index 29d1853d2d..1d832388fe 100644 --- a/packages/compiler-sfc/src/compileTemplate.ts +++ b/packages/compiler-sfc/src/compileTemplate.ts @@ -253,6 +253,7 @@ function doCompileTemplate({ slotted, sourceMap: true, ...compilerOptions, + vapor, hmr: !isProd, nodeTransforms: nodeTransforms.concat( compilerOptions.nodeTransforms || [], diff --git a/packages/compiler-ssr/__tests__/ssrComponent.spec.ts b/packages/compiler-ssr/__tests__/ssrComponent.spec.ts index fb2fff8657..2fde4560ec 100644 --- a/packages/compiler-ssr/__tests__/ssrComponent.spec.ts +++ b/packages/compiler-ssr/__tests__/ssrComponent.spec.ts @@ -39,7 +39,6 @@ describe('ssr: components', () => { return function ssrRender(_ctx, _push, _parent, _attrs) { _ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent("foo"), _mergeProps({ prop: "b" }, _attrs), null), _parent) - _push(\`\`) }" `) @@ -50,7 +49,6 @@ describe('ssr: components', () => { return function ssrRender(_ctx, _push, _parent, _attrs) { _ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent(_ctx.foo), _mergeProps({ prop: "b" }, _attrs), null), _parent) - _push(\`\`) }" `) }) @@ -246,8 +244,7 @@ describe('ssr: components', () => { _ssrRenderList(list, (i) => { _push(\`\`) }) - _push(\`
\`) - _push(\`\`) + _push(\`\`) } else { _push(\`\`) } @@ -270,8 +267,7 @@ describe('ssr: components', () => { _ssrRenderList(_ctx.list, (i) => { _push(\`\`) }) - _push(\`\`) - _push(\`\`) + _push(\`\`) } else { _push(\`\`) } @@ -365,7 +361,6 @@ describe('ssr: components', () => { _push(\`\`) if (false) { _push(\`\`) - _push(\`\`) } else { _push(\`\`) } diff --git a/packages/compiler-ssr/__tests__/ssrElement.spec.ts b/packages/compiler-ssr/__tests__/ssrElement.spec.ts index d344405f3e..f1d509acfb 100644 --- a/packages/compiler-ssr/__tests__/ssrElement.spec.ts +++ b/packages/compiler-ssr/__tests__/ssrElement.spec.ts @@ -396,50 +396,4 @@ describe('ssr: element', () => { `) }) }) - - describe('dynamic anchor', () => { - test('two consecutive components', () => { - expect( - getCompiledString(` -
-
- - -
-
- `), - ).toMatchInlineSnapshot(` - "\`
\`) - _push(_ssrRenderComponent(_component_Comp1, null, null, _parent)) - _push(\`\`) - _push(_ssrRenderComponent(_component_Comp2, null, null, _parent)) - _push(\`
\`" - `) - }) - - test('multiple consecutive components', () => { - expect( - getCompiledString(` -
-
- - - - -
-
- `), - ).toMatchInlineSnapshot(` - "\`
\`) - _push(_ssrRenderComponent(_component_Comp1, null, null, _parent)) - _push(\`\`) - _push(_ssrRenderComponent(_component_Comp2, null, null, _parent)) - _push(\`\`) - _push(_ssrRenderComponent(_component_Comp3, null, null, _parent)) - _push(\`\`) - _push(_ssrRenderComponent(_component_Comp4, null, null, _parent)) - _push(\`
\`" - `) - }) - }) }) diff --git a/packages/compiler-ssr/__tests__/ssrFallthroughAttrs.spec.ts b/packages/compiler-ssr/__tests__/ssrFallthroughAttrs.spec.ts index 712c09d094..7b3d1962c3 100644 --- a/packages/compiler-ssr/__tests__/ssrFallthroughAttrs.spec.ts +++ b/packages/compiler-ssr/__tests__/ssrFallthroughAttrs.spec.ts @@ -29,7 +29,6 @@ describe('ssr: attrs fallthrough', () => { _push(\`\`) if (true) { _push(\`
\`) - _push(\`\`) } else { _push(\`\`) } diff --git a/packages/compiler-ssr/__tests__/ssrInjectCssVars.spec.ts b/packages/compiler-ssr/__tests__/ssrInjectCssVars.spec.ts index 0666e8949c..9e70dac0bd 100644 --- a/packages/compiler-ssr/__tests__/ssrInjectCssVars.spec.ts +++ b/packages/compiler-ssr/__tests__/ssrInjectCssVars.spec.ts @@ -70,7 +70,6 @@ describe('ssr: inject