Skip to content

Commit 4e1745b

Browse files
committed
fix(compiler-sfc): refactor resolveTemplateVModelIdentifiers and improve template analysis caching
1 parent 7546248 commit 4e1745b

File tree

2 files changed

+43
-38
lines changed

2 files changed

+43
-38
lines changed

packages/compiler-sfc/src/compileScript.ts

Lines changed: 4 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
import {
22
BindingTypes,
3-
NodeTypes,
4-
type TemplateChildNode,
53
UNREF,
64
isFunctionType,
7-
isSimpleIdentifier,
85
unwrapTSNode,
96
walkIdentifiers,
107
} from '@vue/compiler-dom'
@@ -67,7 +64,10 @@ import {
6764
isTS,
6865
} from './script/utils'
6966
import { analyzeScriptBindings } from './script/analyzeScriptBindings'
70-
import { isImportUsed } from './script/importUsageCheck'
67+
import {
68+
isImportUsed,
69+
resolveTemplateVModelIdentifiers,
70+
} from './script/importUsageCheck'
7171
import { processAwait } from './script/topLevelAwait'
7272

7373
export interface SFCScriptCompileOptions {
@@ -141,36 +141,6 @@ export interface SFCScriptCompileOptions {
141141
customElement?: boolean | ((filename: string) => boolean)
142142
}
143143

144-
function resolveTemplateVModelIdentifiers(sfc: SFCDescriptor): Set<string> {
145-
const ids = new Set<string>()
146-
const template = sfc.template
147-
if (!template?.ast) return ids
148-
149-
template.ast.children.forEach(walk)
150-
151-
function walk(node: TemplateChildNode) {
152-
switch (node.type) {
153-
case NodeTypes.ELEMENT:
154-
for (let i = 0; i < node.props.length; i++) {
155-
const prop = node.props[i]
156-
if (prop.type === NodeTypes.DIRECTIVE && prop.name === 'model') {
157-
const exp = prop.exp
158-
if (exp && exp.type === NodeTypes.SIMPLE_EXPRESSION) {
159-
const expString = exp.content.trim()
160-
if (isSimpleIdentifier(expString) && expString !== 'undefined') {
161-
ids.add(expString)
162-
}
163-
}
164-
}
165-
}
166-
node.children.forEach(walk)
167-
break
168-
}
169-
}
170-
171-
return ids
172-
}
173-
174144
export interface ImportBinding {
175145
isType: boolean
176146
imported: string

packages/compiler-sfc/src/script/importUsageCheck.ts

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
NodeTypes,
55
type SimpleExpressionNode,
66
type TemplateChildNode,
7+
isSimpleIdentifier,
78
parserOptions,
89
walkIdentifiers,
910
} from '@vue/compiler-dom'
@@ -19,16 +20,35 @@ export function isImportUsed(local: string, sfc: SFCDescriptor): boolean {
1920
return resolveTemplateUsedIdentifiers(sfc).has(local)
2021
}
2122

22-
const templateUsageCheckCache = createCache<Set<string>>()
23+
export function resolveTemplateVModelIdentifiers(
24+
sfc: SFCDescriptor,
25+
): Set<string> {
26+
const template = sfc.template
27+
if (!template?.ast) return new Set<string>()
28+
return resolveTemplateAnalysisResult(sfc).vModelIds
29+
}
30+
31+
const templateAnalysisCache = createCache<{
32+
usedIds: Set<string>
33+
vModelIds: Set<string>
34+
}>()
2335

2436
function resolveTemplateUsedIdentifiers(sfc: SFCDescriptor): Set<string> {
37+
return resolveTemplateAnalysisResult(sfc).usedIds
38+
}
39+
40+
function resolveTemplateAnalysisResult(sfc: SFCDescriptor): {
41+
usedIds: Set<string>
42+
vModelIds: Set<string>
43+
} {
2544
const { content, ast } = sfc.template!
26-
const cached = templateUsageCheckCache.get(content)
45+
const cached = templateAnalysisCache.get(content)
2746
if (cached) {
2847
return cached
2948
}
3049

3150
const ids = new Set<string>()
51+
const vModelIds = new Set<string>()
3252

3353
ast!.children.forEach(walk)
3454

@@ -51,6 +71,20 @@ function resolveTemplateUsedIdentifiers(sfc: SFCDescriptor): Set<string> {
5171
ids.add(`v${capitalize(camelize(prop.name))}`)
5272
}
5373

74+
// collect v-model target identifiers (simple identifiers only)
75+
if (prop.name === 'model') {
76+
const exp = prop.exp
77+
if (exp && exp.type === NodeTypes.SIMPLE_EXPRESSION) {
78+
const expString = exp.content.trim()
79+
if (
80+
isSimpleIdentifier(expString) &&
81+
expString !== 'undefined'
82+
) {
83+
vModelIds.add(expString)
84+
}
85+
}
86+
}
87+
5488
// process dynamic directive arguments
5589
if (prop.arg && !(prop.arg as SimpleExpressionNode).isStatic) {
5690
extractIdentifiers(ids, prop.arg)
@@ -81,8 +115,9 @@ function resolveTemplateUsedIdentifiers(sfc: SFCDescriptor): Set<string> {
81115
}
82116
}
83117

84-
templateUsageCheckCache.set(content, ids)
85-
return ids
118+
const result = { usedIds: ids, vModelIds }
119+
templateAnalysisCache.set(content, result)
120+
return result
86121
}
87122

88123
function extractIdentifiers(ids: Set<string>, node: ExpressionNode) {

0 commit comments

Comments
 (0)