From c0b756e3ad876c404674f6ca4c54fc47cd515d16 Mon Sep 17 00:00:00 2001 From: zhiyuanzmj <260480378@qq.com> Date: Mon, 29 Sep 2025 21:27:34 +0800 Subject: [PATCH 1/3] refactor(compiler-vapor): remove isNodesEquivalent to reduce bundle size --- packages/compiler-vapor/src/generators/for.ts | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/packages/compiler-vapor/src/generators/for.ts b/packages/compiler-vapor/src/generators/for.ts index 026db797ba6..14839a31e6f 100644 --- a/packages/compiler-vapor/src/generators/for.ts +++ b/packages/compiler-vapor/src/generators/for.ts @@ -16,12 +16,7 @@ import { genCall, genMulti, } from './utils' -import { - type Expression, - type Identifier, - type Node, - isNodesEquivalent, -} from '@babel/types' +import type { Expression, Identifier, Node } from '@babel/types' import { parseExpression } from '@babel/parser' import { VaporVForFlags } from '../../../shared/src/vaporFlags' import { walk } from 'estree-walker' @@ -32,7 +27,7 @@ export function genFor( oper: ForIRNode, context: CodegenContext, ): CodeFragment[] { - const { helper } = context + const { helper, ir } = context const { source, value, @@ -98,6 +93,7 @@ export function genFor( render, keyProp, idMap, + ir.source, ) const selectorDeclarations: CodeFragment[] = [] const selectorSetup: CodeFragment[] = [] @@ -320,6 +316,7 @@ function matchPatterns( render: BlockIRNode, keyProp: SimpleExpressionNode | undefined, idMap: Record, + source: string, ) { const selectorPatterns: NonNullable< ReturnType @@ -330,12 +327,12 @@ function matchPatterns( render.effect = render.effect.filter(effect => { if (keyProp !== undefined) { - const selector = matchSelectorPattern(effect, keyProp.ast, idMap) + const selector = matchSelectorPattern(effect, keyProp.ast, idMap, source) if (selector) { selectorPatterns.push(selector) return false } - const keyOnly = matchKeyOnlyBindingPattern(effect, keyProp.ast) + const keyOnly = matchKeyOnlyBindingPattern(effect, keyProp.ast, source) if (keyOnly) { keyOnlyBindingPatterns.push(keyOnly) return false @@ -354,6 +351,7 @@ function matchPatterns( function matchKeyOnlyBindingPattern( effect: IREffect, keyAst: any, + source: string, ): | { effect: IREffect @@ -363,7 +361,7 @@ function matchKeyOnlyBindingPattern( if (effect.expressions.length === 1) { const ast = effect.expressions[0].ast if (typeof ast === 'object' && ast !== null) { - if (isKeyOnlyBinding(ast, keyAst)) { + if (isKeyOnlyBinding(ast, keyAst, source)) { return { effect } } } @@ -374,6 +372,7 @@ function matchSelectorPattern( effect: IREffect, keyAst: any, idMap: Record, + source: string, ): | { effect: IREffect @@ -400,8 +399,8 @@ function matchSelectorPattern( [left, right], [right, left], ]) { - const aIsKey = isKeyOnlyBinding(a, keyAst) - const bIsKey = isKeyOnlyBinding(b, keyAst) + const aIsKey = isKeyOnlyBinding(a, keyAst, source) + const bIsKey = isKeyOnlyBinding(b, keyAst, source) const bVars = analyzeVariableScopes(b, idMap) if (aIsKey && !bIsKey && !bVars.locals.length) { matcheds.push([a, b]) @@ -466,8 +465,8 @@ function matchSelectorPattern( [left, right], [right, left], ]) { - const aIsKey = isKeyOnlyBinding(a, keyAst) - const bIsKey = isKeyOnlyBinding(b, keyAst) + const aIsKey = isKeyOnlyBinding(a, keyAst, source) + const bIsKey = isKeyOnlyBinding(b, keyAst, source) const bVars = analyzeVariableScopes(b, idMap) if (aIsKey && !bIsKey && !bVars.locals.length) { return { @@ -520,11 +519,14 @@ function analyzeVariableScopes( return { globals, locals } } -function isKeyOnlyBinding(expr: Node, keyAst: any) { +function isKeyOnlyBinding(expr: Node, keyAst: Node, source: string) { let only = true walk(expr, { enter(node) { - if (isNodesEquivalent(node, keyAst)) { + if ( + source.slice(node.start!, node.end!) === + source.slice(keyAst.start!, keyAst.end!) + ) { this.skip() return } From 738de8422b7735ecc064b76592540ea2a741d242 Mon Sep 17 00:00:00 2001 From: zhiyuanzmj <260480378@qq.com> Date: Mon, 29 Sep 2025 22:21:53 +0800 Subject: [PATCH 2/3] chore: update --- packages/compiler-vapor/src/generators/for.ts | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/packages/compiler-vapor/src/generators/for.ts b/packages/compiler-vapor/src/generators/for.ts index 14839a31e6f..8726c439c78 100644 --- a/packages/compiler-vapor/src/generators/for.ts +++ b/packages/compiler-vapor/src/generators/for.ts @@ -27,7 +27,7 @@ export function genFor( oper: ForIRNode, context: CodegenContext, ): CodeFragment[] { - const { helper, ir } = context + const { helper } = context const { source, value, @@ -93,7 +93,6 @@ export function genFor( render, keyProp, idMap, - ir.source, ) const selectorDeclarations: CodeFragment[] = [] const selectorSetup: CodeFragment[] = [] @@ -316,7 +315,6 @@ function matchPatterns( render: BlockIRNode, keyProp: SimpleExpressionNode | undefined, idMap: Record, - source: string, ) { const selectorPatterns: NonNullable< ReturnType @@ -327,12 +325,12 @@ function matchPatterns( render.effect = render.effect.filter(effect => { if (keyProp !== undefined) { - const selector = matchSelectorPattern(effect, keyProp.ast, idMap, source) + const selector = matchSelectorPattern(effect, keyProp.content, idMap) if (selector) { selectorPatterns.push(selector) return false } - const keyOnly = matchKeyOnlyBindingPattern(effect, keyProp.ast, source) + const keyOnly = matchKeyOnlyBindingPattern(effect, keyProp.content) if (keyOnly) { keyOnlyBindingPatterns.push(keyOnly) return false @@ -350,8 +348,7 @@ function matchPatterns( function matchKeyOnlyBindingPattern( effect: IREffect, - keyAst: any, - source: string, + key: string, ): | { effect: IREffect @@ -359,9 +356,9 @@ function matchKeyOnlyBindingPattern( | undefined { // TODO: expressions can be multiple? if (effect.expressions.length === 1) { - const ast = effect.expressions[0].ast + const { ast, content } = effect.expressions[0] if (typeof ast === 'object' && ast !== null) { - if (isKeyOnlyBinding(ast, keyAst, source)) { + if (isKeyOnlyBinding(ast, key, content)) { return { effect } } } @@ -370,9 +367,8 @@ function matchKeyOnlyBindingPattern( function matchSelectorPattern( effect: IREffect, - keyAst: any, + key: string, idMap: Record, - source: string, ): | { effect: IREffect @@ -381,7 +377,7 @@ function matchSelectorPattern( | undefined { // TODO: expressions can be multiple? if (effect.expressions.length === 1) { - const ast = effect.expressions[0].ast + const { ast, content } = effect.expressions[0] if (typeof ast === 'object' && ast) { const matcheds: [key: Expression, selector: Expression][] = [] @@ -399,8 +395,16 @@ function matchSelectorPattern( [left, right], [right, left], ]) { - const aIsKey = isKeyOnlyBinding(a, keyAst, source) - const bIsKey = isKeyOnlyBinding(b, keyAst, source) + const aIsKey = isKeyOnlyBinding( + a, + key, + effect.expressions[0].content, + ) + const bIsKey = isKeyOnlyBinding( + b, + key, + effect.expressions[0].content, + ) const bVars = analyzeVariableScopes(b, idMap) if (aIsKey && !bIsKey && !bVars.locals.length) { matcheds.push([a, b]) @@ -448,7 +452,6 @@ function matchSelectorPattern( } } - const content = effect.expressions[0].content if ( typeof ast === 'object' && ast && @@ -465,8 +468,8 @@ function matchSelectorPattern( [left, right], [right, left], ]) { - const aIsKey = isKeyOnlyBinding(a, keyAst, source) - const bIsKey = isKeyOnlyBinding(b, keyAst, source) + const aIsKey = isKeyOnlyBinding(a, key, content) + const bIsKey = isKeyOnlyBinding(b, key, content) const bVars = analyzeVariableScopes(b, idMap) if (aIsKey && !bIsKey && !bVars.locals.length) { return { @@ -519,14 +522,11 @@ function analyzeVariableScopes( return { globals, locals } } -function isKeyOnlyBinding(expr: Node, keyAst: Node, source: string) { +function isKeyOnlyBinding(expr: Node, key: string, source: string) { let only = true walk(expr, { enter(node) { - if ( - source.slice(node.start!, node.end!) === - source.slice(keyAst.start!, keyAst.end!) - ) { + if (source.slice(node.start! - 1, node.end! - 1) === key) { this.skip() return } From 36373e28e03cd2c07023abf9058fc60a2ab8f9c6 Mon Sep 17 00:00:00 2001 From: zhiyuanzmj <260480378@qq.com> Date: Wed, 5 Nov 2025 16:46:44 +0800 Subject: [PATCH 3/3] chore: refactor --- packages/compiler-vapor/src/generators/for.ts | 62 ++----------------- 1 file changed, 4 insertions(+), 58 deletions(-) diff --git a/packages/compiler-vapor/src/generators/for.ts b/packages/compiler-vapor/src/generators/for.ts index 8726c439c78..ddb5d3b43a8 100644 --- a/packages/compiler-vapor/src/generators/for.ts +++ b/packages/compiler-vapor/src/generators/for.ts @@ -1,7 +1,6 @@ import { type SimpleExpressionNode, createSimpleExpression, - isStaticNode, walkIdentifiers, } from '@vue/compiler-dom' import { genBlockContent } from './block' @@ -395,18 +394,10 @@ function matchSelectorPattern( [left, right], [right, left], ]) { - const aIsKey = isKeyOnlyBinding( - a, - key, - effect.expressions[0].content, - ) - const bIsKey = isKeyOnlyBinding( - b, - key, - effect.expressions[0].content, - ) + const aIsKey = isKeyOnlyBinding(a, key, content) + const bIsKey = isKeyOnlyBinding(b, key, content) const bVars = analyzeVariableScopes(b, idMap) - if (aIsKey && !bIsKey && !bVars.locals.length) { + if (aIsKey && !bIsKey && !bVars.length) { matcheds.push([a, b]) } } @@ -419,18 +410,14 @@ function matchSelectorPattern( const content = effect.expressions[0].content let hasExtraId = false - const parentStackMap = new Map() - const parentStack: Node[] = [] walkIdentifiers( ast, id => { if (id.start !== key.start && id.start !== selector.start) { hasExtraId = true } - parentStackMap.set(id, parentStack.slice()) }, false, - parentStack, ) if (!hasExtraId) { @@ -451,40 +438,6 @@ function matchSelectorPattern( } } } - - if ( - typeof ast === 'object' && - ast && - ast.type === 'ConditionalExpression' && - ast.test.type === 'BinaryExpression' && - ast.test.operator === '===' && - ast.test.left.type !== 'PrivateName' && - isStaticNode(ast.consequent) && - isStaticNode(ast.alternate) - ) { - const left = ast.test.left - const right = ast.test.right - for (const [a, b] of [ - [left, right], - [right, left], - ]) { - const aIsKey = isKeyOnlyBinding(a, key, content) - const bIsKey = isKeyOnlyBinding(b, key, content) - const bVars = analyzeVariableScopes(b, idMap) - if (aIsKey && !bIsKey && !bVars.locals.length) { - return { - effect, - // @ts-expect-error - selector: { - content: content.slice(b.start! - 1, b.end! - 1), - ast: b, - loc: b.loc as any, - isStatic: false, - }, - } - } - } - } } } @@ -492,20 +445,15 @@ function analyzeVariableScopes( ast: Node, idMap: Record, ) { - let globals: string[] = [] let locals: string[] = [] const ids: Identifier[] = [] - const parentStackMap = new Map() - const parentStack: Node[] = [] walkIdentifiers( ast, id => { ids.push(id) - parentStackMap.set(id, parentStack.slice()) }, false, - parentStack, ) for (const id of ids) { @@ -514,12 +462,10 @@ function analyzeVariableScopes( } if (idMap[id.name]) { locals.push(id.name) - } else { - globals.push(id.name) } } - return { globals, locals } + return locals } function isKeyOnlyBinding(expr: Node, key: string, source: string) {