@@ -5,34 +5,36 @@ import { getConfig } from '@tailwindcss-mangle/config'
5
5
import type { MangleUserConfig } from '@tailwindcss-mangle/config'
6
6
import { sort } from 'fast-sort'
7
7
import defu from 'defu'
8
- import AhoCorasick from 'modern-ahocorasick'
9
8
import { createGlobMatcher , defaultMangleClassFilter , escapeStringRegexp } from '@/utils'
10
9
10
+ interface InitConfigOptions {
11
+ cwd ?: string
12
+ classList ?: string [ ]
13
+ mangleOptions ?: MangleUserConfig
14
+ }
15
+
11
16
export class Context {
12
17
options : MangleUserConfig
13
- includeMatcher : ( file : string ) => boolean
14
- excludeMatcher : ( file : string ) => boolean
18
+ private includeMatcher : ( file : string ) => boolean
19
+ private excludeMatcher : ( file : string ) => boolean
20
+ private replaceMap : Map < string , string >
15
21
classSet : Set < string >
16
- replaceMap : Map < string , string >
22
+
17
23
classGenerator : ClassGenerator
18
- ahoCorasick ?: AhoCorasick
19
- useAC : boolean
24
+
20
25
preserveFunctionSet : Set < string >
21
26
preserveClassNamesSet : Set < string >
22
27
preserveFunctionRegexs : RegExp [ ]
23
- constructor ( opts : MangleUserConfig = { } ) {
24
- this . options = opts // defu(opts, getDefaultMangleUserConfig())
28
+ constructor ( ) {
29
+ this . options = { }
25
30
this . classSet = new Set ( )
26
31
this . replaceMap = new Map ( )
27
- this . includeMatcher = createGlobMatcher ( this . options . include , true )
28
- this . excludeMatcher = createGlobMatcher ( this . options . exclude , false )
29
- this . classGenerator = new ClassGenerator ( this . options . classGenerator )
30
- this . useAC = false
31
- this . preserveFunctionSet = new Set ( opts . preserveFunction )
32
+ this . includeMatcher = ( ) => true
33
+ this . excludeMatcher = ( ) => false
34
+ this . classGenerator = new ClassGenerator ( )
35
+ this . preserveFunctionSet = new Set ( )
32
36
this . preserveClassNamesSet = new Set ( )
33
- this . preserveFunctionRegexs = [ ...this . preserveFunctionSet . values ( ) ] . map ( ( x ) => {
34
- return new RegExp ( escapeStringRegexp ( x ) + '\\(([^)]*)\\)' , 'g' )
35
- } )
37
+ this . preserveFunctionRegexs = [ ]
36
38
}
37
39
38
40
isPreserveClass ( className : string ) {
@@ -50,12 +52,16 @@ export class Context {
50
52
return this . preserveFunctionSet . has ( calleeName )
51
53
}
52
54
53
- mergeOptions ( opts ?: MangleUserConfig ) {
55
+ private mergeOptions ( opts ?: MangleUserConfig ) {
54
56
// 配置选项优先
55
57
this . options = defu ( this . options , opts )
56
58
this . includeMatcher = createGlobMatcher ( this . options . include , true )
57
59
this . excludeMatcher = createGlobMatcher ( this . options . exclude , false )
58
60
this . classGenerator = new ClassGenerator ( this . options . classGenerator )
61
+ this . preserveFunctionSet = new Set ( opts ?. preserveFunction ?? [ ] )
62
+ this . preserveFunctionRegexs = [ ...this . preserveFunctionSet . values ( ) ] . map ( ( x ) => {
63
+ return new RegExp ( escapeStringRegexp ( x ) + '\\(([^)]*)\\)' , 'g' )
64
+ } )
59
65
}
60
66
61
67
isInclude ( file : string ) {
@@ -87,57 +93,42 @@ export class Context {
87
93
}
88
94
}
89
95
90
- search ( str : string ) {
91
- const arr = this . ahoCorasick ?. search ( str ) ?? [ ]
92
- const map = new Map < string , [ number , number ] [ ] > ( )
93
- for ( const [ end , classNames ] of arr ) {
94
- for ( const className of classNames ) {
95
- if ( map . has ( className ) ) {
96
- const v = map . get ( className )
97
- if ( v ) {
98
- v . push ( [ end - className . length + 1 , end + 1 ] )
99
- }
100
- } else {
101
- map . set ( className , [ [ end - className . length + 1 , end + 1 ] ] )
102
- }
103
- }
104
- }
105
- // end - str.length + 1, end + 1, value
106
- return {
107
- map,
108
- arr : sort ( [ ...map . entries ( ) ] ) . desc ( ( x ) => x [ 0 ] . length )
109
- }
110
- }
111
-
112
- async initConfig ( cwd ?: string ) {
96
+ async initConfig ( opts : InitConfigOptions = { } ) {
97
+ const { cwd, classList : _classList , mangleOptions } = opts
113
98
const { config, cwd : configCwd } = await getConfig ( cwd )
114
- const mangleConfig = config ?. mangle
99
+ const mangleConfig = mangleOptions ?? config ?. mangle
115
100
this . mergeOptions ( mangleConfig )
116
-
117
- let jsonPath = this . options . classListPath ?? resolve ( process . cwd ( ) , config ?. patch ?. output ?. filename as string )
118
- if ( ! isAbsolute ( jsonPath ) ) {
119
- jsonPath = resolve ( configCwd ?? process . cwd ( ) , jsonPath )
120
- }
121
-
122
- if ( jsonPath && fs . existsSync ( jsonPath ) ) {
123
- const rawClassList = fs . readFileSync ( jsonPath , 'utf8' )
124
- const list = JSON . parse ( rawClassList ) as string [ ]
125
- // why?
126
- // cause bg-red-500 and bg-red-500/50 same time
127
- // transform bg-red-500/50 first
128
- const classList = sort ( list ) . desc ( ( c ) => c . length )
101
+ if ( _classList ) {
102
+ const classList = sort ( _classList ) . desc ( ( c ) => c . length )
129
103
for ( const className of classList ) {
130
104
if ( this . currentMangleClassFilter ( className ) ) {
131
105
this . classSet . add ( className )
132
106
}
133
107
}
108
+ } else {
109
+ let jsonPath = this . options . classListPath ?? resolve ( process . cwd ( ) , config ?. patch ?. output ?. filename as string )
110
+ if ( ! isAbsolute ( jsonPath ) ) {
111
+ jsonPath = resolve ( configCwd ?? process . cwd ( ) , jsonPath )
112
+ }
113
+
114
+ if ( jsonPath && fs . existsSync ( jsonPath ) ) {
115
+ const rawClassList = fs . readFileSync ( jsonPath , 'utf8' )
116
+ const list = JSON . parse ( rawClassList ) as string [ ]
117
+ // why?
118
+ // cause bg-red-500 and bg-red-500/50 same time
119
+ // transform bg-red-500/50 first
120
+ const classList = sort ( list ) . desc ( ( c ) => c . length )
121
+ for ( const className of classList ) {
122
+ if ( this . currentMangleClassFilter ( className ) ) {
123
+ this . classSet . add ( className )
124
+ }
125
+ }
126
+ }
134
127
}
135
- const keywords : string [ ] = [ ]
128
+
136
129
for ( const cls of this . classSet ) {
137
130
this . classGenerator . generateClassName ( cls )
138
- keywords . push ( cls )
139
131
}
140
- this . ahoCorasick = new AhoCorasick ( keywords )
141
132
142
133
for ( const x of Object . entries ( this . classGenerator . newClassMap ) ) {
143
134
this . replaceMap . set ( x [ 0 ] , x [ 1 ] . name )
0 commit comments