Skip to content

Commit aaf7078

Browse files
committed
refactor: js handler
1 parent cbfab78 commit aaf7078

File tree

9 files changed

+446
-520
lines changed

9 files changed

+446
-520
lines changed

packages/core/package.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,7 @@
5252
},
5353
"dependencies": {
5454
"@ast-core/escape": "^1.0.1",
55-
"@babel/core": "^7.24.7",
56-
"@babel/helper-plugin-utils": "^7.24.7",
5755
"@babel/parser": "^7.24.7",
58-
"@babel/preset-typescript": "^7.24.7",
5956
"@babel/traverse": "^7.24.7",
6057
"@babel/types": "^7.24.7",
6158
"@tailwindcss-mangle/config": "workspace:^",
@@ -69,7 +66,6 @@
6966
"postcss-selector-parser": "^6.1.0"
7067
},
7168
"devDependencies": {
72-
"@types/babel__core": "^7.20.5",
7369
"@types/babel__traverse": "^7.20.6",
7470
"@types/micromatch": "^4.0.7",
7571
"@vue/compiler-core": "^3.4.29",

packages/core/src/ctx/index.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,6 @@ export class Context {
4747
}
4848

4949
isPreserveFunction(calleeName: string) {
50-
// if (callee === undefined) {
51-
// return false
52-
// }
5350
return this.preserveFunctionSet.has(calleeName)
5451
}
5552

@@ -78,12 +75,6 @@ export class Context {
7875
}
7976

8077
getReplaceMap() {
81-
// const map = new Map<string, string>()
82-
// for (const [key, value] of sort([...this.replaceMap.entries()]).desc((x) => x[0].length)) {
83-
// if (!this.isPreserveClass(key)) {
84-
// map.set(key, value)
85-
// }
86-
// }
8778
return this.replaceMap // map
8879
}
8980

packages/core/src/html/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import MagicString from 'magic-string'
33
import type { IHtmlHandlerOptions } from '../types'
44
import { makeRegex, splitCode } from '../shared'
55

6-
export function htmlHandler(raw: string, options: IHtmlHandlerOptions) {
6+
export function htmlHandler(raw: string | MagicString, options: IHtmlHandlerOptions) {
77
const { ctx } = options
88
const { replaceMap } = ctx
99
const ms: MagicString = typeof raw === 'string' ? new MagicString(raw) : raw

packages/core/src/js/index.ts

Lines changed: 57 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
1-
import type { CallExpression, StringLiteral, TemplateElement } from '@babel/types'
2-
import { type BabelFileResult, type NodePath, transformSync } from '@babel/core'
1+
import type { StringLiteral, TemplateElement } from '@babel/types'
2+
import MagicString from 'magic-string'
3+
import { jsStringEscape } from '@ast-core/escape'
34
import type { IJsHandlerOptions } from '../types'
45
import { makeRegex, splitCode } from '../shared'
5-
import { isProd as isProduction } from '../env'
6+
import { parse, traverse } from '@/babel'
67

78
export { preProcessJs, preProcessRawCode } from './pre'
89

9-
export function handleValue(raw: string, node: StringLiteral | TemplateElement, options: IJsHandlerOptions) {
10+
export function handleValue(raw: string, node: StringLiteral | TemplateElement, options: IJsHandlerOptions, ms: MagicString, offset: number, escape: boolean) {
1011
const { ctx, splitQuote = true } = options
1112
const { replaceMap, classGenerator: clsGen } = ctx
1213

1314
const array = splitCode(raw, {
1415
splitQuote,
1516
})
1617
let rawString = raw
18+
let needUpdate = false
1719
for (const v of array) {
1820
if (replaceMap.has(v)) {
1921
let ignoreFlag = false
@@ -23,59 +25,64 @@ export function handleValue(raw: string, node: StringLiteral | TemplateElement,
2325

2426
if (!ignoreFlag) {
2527
rawString = rawString.replace(makeRegex(v), clsGen.generateClassName(v).name)
28+
needUpdate = true
2629
}
2730
}
2831
}
32+
if (needUpdate && typeof node.start === 'number' && typeof node.end === 'number') {
33+
const start = node.start + offset
34+
const end = node.end - offset
35+
36+
if (start < end && raw !== rawString) {
37+
ms.update(start, end, escape ? jsStringEscape(rawString) : rawString)
38+
}
39+
}
2940
return rawString
3041
}
3142

32-
export function jsHandler(rawSource: string, options: IJsHandlerOptions) {
33-
const result = transformSync(rawSource, {
34-
babelrc: false,
35-
ast: true,
36-
plugins: [
37-
() => {
38-
return {
39-
visitor: {
40-
StringLiteral: {
41-
enter(p: NodePath<StringLiteral>) {
42-
const n = p.node
43-
n.value = handleValue(n.value, n, options)
44-
},
45-
},
46-
TemplateElement: {
47-
enter(p: NodePath<TemplateElement>) {
48-
const n = p.node
49-
n.value.raw = handleValue(n.value.raw, n, options)
50-
},
51-
},
52-
CallExpression: {
53-
enter(p: NodePath<CallExpression>) {
54-
const calleePath = p.get('callee')
55-
if (calleePath.isIdentifier() && calleePath.node.name === 'eval') {
56-
p.traverse({
57-
StringLiteral: {
58-
enter(s) {
59-
// ___CSS_LOADER_EXPORT___
60-
const res = jsHandler(s.node.value, options)
61-
if (res.code) {
62-
s.node.value = res.code
63-
}
64-
},
65-
},
66-
})
67-
}
68-
},
69-
},
70-
// noScope: true
71-
},
72-
}
43+
export function jsHandler(rawSource: string | MagicString, options: IJsHandlerOptions) {
44+
const ms: MagicString = typeof rawSource === 'string' ? new MagicString(rawSource) : rawSource
45+
const ast = parse(ms.original, {
46+
sourceType: 'unambiguous',
47+
plugins: ['typescript', 'jsx'],
48+
})
49+
traverse(ast, {
50+
StringLiteral: {
51+
enter(p) {
52+
const n = p.node
53+
handleValue(n.value, n, options, ms, 1, true)
54+
},
55+
},
56+
TemplateElement: {
57+
enter(p) {
58+
const n = p.node
59+
handleValue(n.value.raw, n, options, ms, 0, false)
7360
},
74-
],
75-
minified: options.minified ?? isProduction(),
76-
sourceMaps: false,
77-
configFile: false,
61+
},
62+
// CallExpression: {
63+
// enter(p: NodePath<CallExpression>) {
64+
// const calleePath = p.get('callee')
65+
// if (calleePath.isIdentifier() && calleePath.node.name === 'eval') {
66+
// p.traverse({
67+
// StringLiteral: {
68+
// enter(s) {
69+
// // ___CSS_LOADER_EXPORT___
70+
// const res = jsHandler(s.node.value, options)
71+
// if (res.code) {
72+
// s.node.value = res.code
73+
// }
74+
// },
75+
// },
76+
// })
77+
// }
78+
// },
79+
// },
7880
})
7981

80-
return result as BabelFileResult
82+
return {
83+
code: ms.toString(),
84+
get map() {
85+
return ms.generateMap()
86+
},
87+
}
8188
}

packages/core/src/js/pre.ts

Lines changed: 32 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
1-
import babel from '@babel/core'
2-
import { declare } from '@babel/helper-plugin-utils'
31
import MagicString from 'magic-string'
42
import { splitCode } from '@tailwindcss-mangle/shared'
53
import { sort } from 'fast-sort'
64
import { jsStringEscape } from '@ast-core/escape'
75
import type { ParseResult } from '@babel/parser'
8-
// @ts-ignore
9-
import babelTypescript from '@babel/preset-typescript'
106
import { escapeStringRegexp } from '@/utils'
117
import type { Context } from '@/ctx'
128
import { between } from '@/math'
139
import type { IPreProcessJsOptions } from '@/types'
10+
import { parse, traverse } from '@/babel'
1411

1512
interface Options {
1613
magicString: MagicString
@@ -61,72 +58,15 @@ export function handleValue(options: HandleValueOptions) {
6158
}
6259
}
6360

64-
export const JsPlugin = declare((api, options: Options) => {
65-
api.assertVersion(7)
66-
const { magicString, id, ctx, markedArray } = options
67-
return {
68-
visitor: {
69-
StringLiteral: {
70-
exit(p) {
71-
handleValue({
72-
ctx,
73-
id,
74-
magicString,
75-
path: p,
76-
raw: p.node.value,
77-
offset: 1,
78-
escape: true,
79-
markedArray,
80-
})
81-
},
82-
},
83-
TemplateElement: {
84-
exit(p) {
85-
handleValue({
86-
ctx,
87-
id,
88-
magicString,
89-
path: p,
90-
raw: p.node.value.raw,
91-
offset: 0,
92-
escape: false,
93-
markedArray,
94-
})
95-
},
96-
},
97-
},
98-
}
99-
})
100-
101-
function transformSync(ast: babel.types.Node, code: string, plugins: babel.PluginItem[] | null | undefined, filename: string | null | undefined) {
102-
babel.transformFromAstSync(ast, code, {
103-
presets: loadPresets(),
104-
plugins,
105-
filename,
106-
})
107-
}
108-
109-
export function loadPresets() {
110-
return [
111-
[
112-
babelTypescript,
113-
{
114-
allExtensions: true,
115-
isTSX: true,
116-
},
117-
],
118-
]
119-
}
120-
12161
export function preProcessJs(options: IPreProcessJsOptions): string {
12262
const { code, id, ctx } = options
12363
const { replaceMap } = ctx
12464
const magicString = typeof code === 'string' ? new MagicString(code) : code
12565
let ast: ParseResult<babel.types.File>
12666
try {
127-
const file = babel.parseSync(magicString.original, {
67+
const file = parse(magicString.original, {
12868
sourceType: 'unambiguous',
129-
presets: loadPresets(),
69+
plugins: ['typescript', 'jsx'],
13070
})
13171
if (file) {
13272
ast = file
@@ -139,7 +79,7 @@ export function preProcessJs(options: IPreProcessJsOptions): string {
13979
return code.toString()
14080
}
14181
const markedArray: [number, number][] = []
142-
babel.traverse(ast, {
82+
traverse(ast, {
14383
CallExpression: {
14484
enter(p) {
14585
const callee = p.get('callee')
@@ -179,25 +119,35 @@ export function preProcessJs(options: IPreProcessJsOptions): string {
179119
}
180120
},
181121
},
182-
})
183-
184-
transformSync(
185-
ast,
186-
magicString.original,
187-
[
188-
[
189-
JsPlugin,
190-
{
191-
magicString,
192-
replaceMap,
122+
StringLiteral: {
123+
exit(p) {
124+
handleValue({
125+
ctx,
193126
id,
127+
magicString,
128+
path: p,
129+
raw: p.node.value,
130+
offset: 1,
131+
escape: true,
132+
markedArray,
133+
})
134+
},
135+
},
136+
TemplateElement: {
137+
exit(p) {
138+
handleValue({
194139
ctx,
140+
id,
141+
magicString,
142+
path: p,
143+
raw: p.node.value.raw,
144+
offset: 0,
145+
escape: false,
195146
markedArray,
196-
},
197-
],
198-
],
199-
id,
200-
)
147+
})
148+
},
149+
},
150+
})
201151

202152
return magicString.toString()
203153
}
@@ -219,12 +169,12 @@ export function preProcessRawCode(options: IPreProcessJsOptions): string {
219169
for (const regExpMatch of allArr) {
220170
let ast: ParseResult<babel.types.File> | null
221171
try {
222-
ast = babel.parseSync(regExpMatch[0], {
172+
ast = parse(regExpMatch[0], {
223173
sourceType: 'unambiguous',
224174
})
225175

226176
ast
227-
&& babel.traverse(ast, {
177+
&& traverse(ast, {
228178
StringLiteral: {
229179
enter(p) {
230180
const arr = sort(splitCode(p.node.value)).desc(x => x.length)

packages/core/src/js/vue.ts

Whitespace-only changes.

0 commit comments

Comments
 (0)