Skip to content

Commit be9f9db

Browse files
committed
perf(weapp-tailwindcss): 精简名称匹配默认路径
1 parent 9711fd0 commit be9f9db

2 files changed

Lines changed: 53 additions & 6 deletions

File tree

packages/weapp-tailwindcss/src/utils/nameMatcher.ts

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { escapeStringRegexp } from '@weapp-core/regex'
22

33
export type NameMatcher = (value: string) => boolean
4+
const NEVER_MATCH_NAME: NameMatcher = () => false
5+
const GLOBAL_FLAG_REGEXP = /g/g
46

57
function buildFuzzyMatcher(fuzzyStrings: string[]): ((value: string) => boolean) | undefined {
68
if (fuzzyStrings.length === 0) {
@@ -20,15 +22,15 @@ function normaliseRegex(regex: RegExp) {
2022
if (!flags.includes('g')) {
2123
return regex
2224
}
23-
return new RegExp(source, flags.replace(/g/g, ''))
25+
return new RegExp(source, flags.replace(GLOBAL_FLAG_REGEXP, ''))
2426
}
2527

2628
export function createNameMatcher(
2729
list: (string | RegExp)[] | undefined,
2830
{ exact = false }: { exact?: boolean } = {},
2931
): NameMatcher {
3032
if (!list || list.length === 0) {
31-
return () => false
33+
return NEVER_MATCH_NAME
3234
}
3335

3436
const exactStrings = exact ? new Set<string>() : undefined
@@ -49,13 +51,43 @@ export function createNameMatcher(
4951
}
5052
}
5153

54+
if (exact) {
55+
const exactStringCount = exactStrings?.size ?? 0
56+
if (exactStringCount === 1 && regexList.length === 0) {
57+
const [needle] = exactStrings!
58+
return value => value === needle
59+
}
60+
61+
if (regexList.length === 0) {
62+
return value => exactStrings!.has(value)
63+
}
64+
65+
if (exactStringCount === 0 && regexList.length === 1) {
66+
const [regex] = regexList
67+
return value => regex.test(value)
68+
}
69+
70+
return (value: string) => {
71+
if (exactStrings?.has(value)) {
72+
return true
73+
}
74+
return regexList.some(regex => regex.test(value))
75+
}
76+
}
77+
5278
const fuzzyMatcher = exact ? undefined : buildFuzzyMatcher(fuzzyStrings)
5379
const hasRegex = regexList.length > 0
5480

81+
if (fuzzyMatcher && !hasRegex) {
82+
return fuzzyMatcher
83+
}
84+
85+
if (!fuzzyMatcher && regexList.length === 1) {
86+
const [regex] = regexList
87+
return value => regex.test(value)
88+
}
89+
5590
return (value: string) => {
56-
if (exact && exactStrings?.has(value)) {
57-
return true
58-
}
5991
if (fuzzyMatcher?.(value)) {
6092
return true
6193
}

packages/weapp-tailwindcss/test/utils/nameMatcher.test.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { describe, expect, it } from 'vitest'
22
import { createNameMatcher } from '@/utils/nameMatcher'
33

4+
const GLOBAL_FOO_REGEXP = /fo{2,}/g
5+
const EXACT_STYLED_REGEXP = /^styled$/
6+
47
describe('utils/createNameMatcher', () => {
58
it('returns false when matcher is empty', () => {
69
const matcher = createNameMatcher(undefined)
@@ -13,6 +16,12 @@ describe('utils/createNameMatcher', () => {
1316
expect(matcher('not-me')).toBe(false)
1417
})
1518

19+
it('matches a single exact string through the dedicated fast path', () => {
20+
const matcher = createNameMatcher(['weappTwIgnore'], { exact: true })
21+
expect(matcher('weappTwIgnore')).toBe(true)
22+
expect(matcher('weappTwIgnorex')).toBe(false)
23+
})
24+
1625
it('performs fuzzy matches while escaping special characters', () => {
1726
const matcher = createNameMatcher(['foo.bar', 'baz'])
1827
expect(matcher('wrapped foo.bar value')).toBe(true)
@@ -21,9 +30,15 @@ describe('utils/createNameMatcher', () => {
2130
})
2231

2332
it('handles regular expressions with global flag safely', () => {
24-
const matcher = createNameMatcher([/fo{2,}/g])
33+
const matcher = createNameMatcher([GLOBAL_FOO_REGEXP])
2534
expect(matcher('foo foo')).toBe(true)
2635
// call twice to ensure no lastIndex leakage
2736
expect(matcher('foo foo')).toBe(true)
2837
})
38+
39+
it('supports exact mode with regex-only input', () => {
40+
const matcher = createNameMatcher([EXACT_STYLED_REGEXP], { exact: true })
41+
expect(matcher('styled')).toBe(true)
42+
expect(matcher('styled.div')).toBe(false)
43+
})
2944
})

0 commit comments

Comments
 (0)