Skip to content

Commit c2e0c9c

Browse files
committed
perf(weapp-tailwindcss): 复用标签忽略判定上下文
1 parent be9f9db commit c2e0c9c

2 files changed

Lines changed: 38 additions & 15 deletions

File tree

packages/weapp-tailwindcss/src/js/taggedTemplateIgnore.ts

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,26 @@ export function createTaggedTemplateIgnore(
1717
): TaggedTemplateIgnore {
1818
const bindingIgnoreCache = new Map<Binding, boolean>()
1919
const taggedTemplateIgnoreCache = new WeakMap<Node, boolean>()
20+
const seenBindings = new Set<Binding>()
2021
const canonicalIgnoreNames = new Set(
2122
(names ?? [])
2223
.filter((item): item is string => typeof item === 'string'),
2324
)
25+
const hasCanonicalIgnoreNames = canonicalIgnoreNames.size > 0
26+
27+
const matchesIgnoreName = (value: string): boolean => {
28+
return (hasCanonicalIgnoreNames && canonicalIgnoreNames.has(value)) || matcher(value)
29+
}
2430

2531
const propertyMatches = (propertyPath: NodePath<Node> | undefined): boolean => {
2632
if (!propertyPath) {
2733
return false
2834
}
2935
if (propertyPath.isIdentifier()) {
30-
const { name } = propertyPath.node
31-
return canonicalIgnoreNames.has(name) || matcher(name)
36+
return matchesIgnoreName(propertyPath.node.name)
3237
}
3338
if (propertyPath.isStringLiteral()) {
34-
const { value } = propertyPath.node
35-
return canonicalIgnoreNames.has(value) || matcher(value)
39+
return matchesIgnoreName(propertyPath.node.value)
3640
}
3741
return false
3842
}
@@ -72,10 +76,10 @@ export function createTaggedTemplateIgnore(
7276

7377
if (bindingPath.isImportSpecifier()) {
7478
const imported = bindingPath.node.imported
75-
if (imported.type === 'Identifier' && (canonicalIgnoreNames.has(imported.name) || matcher(imported.name))) {
79+
if (imported.type === 'Identifier' && matchesIgnoreName(imported.name)) {
7680
result = true
7781
}
78-
else if (imported.type === 'StringLiteral' && (canonicalIgnoreNames.has(imported.value) || matcher(imported.value))) {
82+
else if (imported.type === 'StringLiteral' && matchesIgnoreName(imported.value)) {
7983
result = true
8084
}
8185
}
@@ -120,7 +124,7 @@ export function createTaggedTemplateIgnore(
120124
}
121125
if (current.isSequenceExpression()) {
122126
const expressions = current.get('expressions') as NodePath<Node>[]
123-
const last = expressions[expressions.length - 1]
127+
const last = expressions.at(-1)
124128
if (last) {
125129
current = last
126130
continue
@@ -136,25 +140,25 @@ export function createTaggedTemplateIgnore(
136140
return current
137141
}
138142

139-
const evaluateTagPath = (tagPath: NodePath<Node>): boolean => {
143+
const evaluateTagPath = (tagPath: NodePath<Node>, seen: Set<Binding>): boolean => {
140144
if (tagPath.isCallExpression?.() || tagPath.node.type === 'CallExpression') {
141145
const calleePath = tagPath.get('callee') as NodePath<Node>
142-
return evaluateTagPath(calleePath)
146+
return evaluateTagPath(calleePath, seen)
143147
}
144148

145149
if (tagPath.isIdentifier()) {
146-
if (matcher(tagPath.node.name)) {
150+
if (matchesIgnoreName(tagPath.node.name)) {
147151
return true
148152
}
149153
const binding = (tagPath as any)?.scope?.getBinding?.(tagPath.node.name)
150154
if (binding) {
151-
return resolvesToWeappTwIgnore(binding, new Set())
155+
return resolvesToWeappTwIgnore(binding, seen)
152156
}
153157
return false
154158
}
155159

156160
if (tagPath.isMemberExpression()) {
157-
return resolvesMemberExpressionToIgnore(tagPath as NodePath<MemberExpression>, new Set())
161+
return resolvesMemberExpressionToIgnore(tagPath as NodePath<MemberExpression>, seen)
158162
}
159163

160164
return false
@@ -173,7 +177,8 @@ export function createTaggedTemplateIgnore(
173177
return effectiveCached
174178
}
175179

176-
const result = evaluateTagPath(effectiveTagPath)
180+
seenBindings.clear()
181+
const result = evaluateTagPath(effectiveTagPath, seenBindings)
177182
taggedTemplateIgnoreCache.set(effectiveTagPath.node, result)
178183
taggedTemplateIgnoreCache.set(tagPath.node, result)
179184
return result

packages/weapp-tailwindcss/test/js/taggedTemplateIgnore.test.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,21 +45,24 @@ describe('taggedTemplateIgnore', () => {
4545
expect(helper.shouldIgnore(chainedAlias)).toBe(true)
4646
})
4747

48-
it('does not treat plain String.raw aliases as ignored', () => {
48+
it('does not treat plain String.raw aliases as ignored and clears cycle tracking between evaluations', () => {
4949
const helper = createTaggedTemplateIgnore({ matcher: () => false, names: ['weappTwIgnore'] })
50-
const [rawAlias, chained, cycle] = getTagPaths([
50+
const [rawAlias, chained, cycle, importedAlias] = getTagPaths([
5151
'const rawAlias = String.raw',
5252
'const chained = rawAlias',
5353
'rawAlias`foo`',
5454
'chained`bar`',
5555
'const a = b',
5656
'const b = a',
5757
'a`cycle`',
58+
'import { weappTwIgnore as imported } from "weapp-tailwindcss/escape"',
59+
'imported`ok`',
5860
].join('\n'))
5961

6062
expect(helper.shouldIgnore(rawAlias)).toBe(false)
6163
expect(helper.shouldIgnore(chained)).toBe(false)
6264
expect(helper.shouldIgnore(cycle)).toBe(false)
65+
expect(helper.shouldIgnore(importedAlias)).toBe(true)
6366
})
6467

6568
it('recognises helper properties on objects and computed lookups', () => {
@@ -86,6 +89,21 @@ describe('taggedTemplateIgnore', () => {
8689
expect(helper.shouldIgnore(unsupportedTag)).toBe(false)
8790
})
8891

92+
it('reuses effective tag evaluation for wrapped non-null expressions', () => {
93+
const helper = createTaggedTemplateIgnore({ matcher: () => false, names: ['weappTwIgnore'] })
94+
const [wrappedTag] = getTagPaths([
95+
'import { weappTwIgnore as imported } from "weapp-tailwindcss/escape"',
96+
'const chained = imported',
97+
'chained!`foo`',
98+
].join('\n'), ['typescript'])
99+
100+
const effectiveTag = helper.getEffectiveTagPath(wrappedTag)
101+
102+
expect(effectiveTag.isIdentifier({ name: 'chained' })).toBe(true)
103+
expect(helper.shouldIgnore(wrappedTag)).toBe(true)
104+
expect(helper.shouldIgnore(effectiveTag)).toBe(true)
105+
})
106+
89107
it('returns false when identifiers are not recognised', () => {
90108
const helper = createTaggedTemplateIgnore({ matcher: () => false })
91109
const [unknownTag] = getTagPaths('unknown`foo`')

0 commit comments

Comments
 (0)