Skip to content

Commit 830822c

Browse files
committed
feat: normalize IHandler interface
1 parent 0078ca7 commit 830822c

File tree

16 files changed

+153
-754
lines changed

16 files changed

+153
-754
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
"turbo": "^2.0.4",
5656
"typescript": "^5.5.2",
5757
"unbuild": "^2.0.0",
58+
"unplugin": "^1.10.1",
5859
"unplugin-tailwindcss-mangle": "workspace:*",
5960
"vitest": "^1.6.0"
6061
}

packages/core/src/css/index.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
import postcss from 'postcss'
2-
import type { ICssHandlerOptions } from '../types'
32
import { transformSelectorPostcssPlugin } from './plugins'
3+
import type { ICssHandlerOptions, IHandlerTransformResult } from '@/types'
44

5-
export function cssHandler(rawSource: string, options: ICssHandlerOptions) {
5+
export async function cssHandler(rawSource: string, options: ICssHandlerOptions): Promise<IHandlerTransformResult> {
66
const acceptedPlugins = [transformSelectorPostcssPlugin(options)]
77
const { id } = options
8-
return postcss(acceptedPlugins).process(rawSource, {
8+
const { css: code, map } = await postcss(acceptedPlugins).process(rawSource, {
99
from: id,
1010
to: id,
1111
})
12+
return {
13+
code,
14+
// @ts-ignore
15+
map,
16+
}
1217
}

packages/core/src/css/plugins.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@ export function isVueScoped(s: parser.ClassName): boolean {
2121
}
2222

2323
export const transformSelectorPostcssPlugin: PluginCreator<ICssHandlerOptions> = function (options) {
24-
const { ignoreVueScoped, ctx } = defu(options, {
24+
const { ignoreVueScoped, ctx, id } = defu(options, {
2525
ignoreVueScoped: true,
2626
})
27+
2728
const replaceMap = ctx.replaceMap
2829

2930
return {
@@ -42,6 +43,7 @@ export const transformSelectorPostcssPlugin: PluginCreator<ICssHandlerOptions> =
4243
rule.cloneBefore()
4344
}
4445
s.value = v
46+
ctx.addToUsedBy(v, id)
4547
}
4648
}
4749
})

packages/core/src/html/index.ts

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,35 @@
11
import { Parser } from 'htmlparser2'
22
import MagicString from 'magic-string'
3-
import type { IHtmlHandlerOptions } from '../types'
4-
import { makeRegex, splitCode } from '../shared'
3+
import { makeRegex, splitCode } from '@/shared'
4+
import type { IHandlerTransformResult, IHtmlHandlerOptions } from '@/types'
55

6-
export function htmlHandler(raw: string | MagicString, options: IHtmlHandlerOptions) {
7-
const { ctx } = options
8-
const { replaceMap } = ctx
6+
export function htmlHandler(raw: string | MagicString, options: IHtmlHandlerOptions): IHandlerTransformResult {
7+
const { ctx, id } = options
8+
const { replaceMap, classGenerator } = ctx
99
const ms: MagicString = typeof raw === 'string' ? new MagicString(raw) : raw
1010
const parser = new Parser({
1111
onattribute(name, value) {
1212
if (name === 'class') {
13+
let needUpdate = false
1314
const arr = splitCode(value, {
1415
splitQuote: false,
1516
})
1617
let rawValue = value
1718
for (const v of arr) {
1819
if (replaceMap.has(v)) {
19-
rawValue = rawValue.replace(makeRegex(v), ctx.classGenerator.generateClassName(v).name)
20+
const gen = classGenerator.generateClassName(v)
21+
rawValue = rawValue.replace(makeRegex(v), gen.name)
22+
ctx.addToUsedBy(gen.name, id)
23+
needUpdate = true
2024
}
2125
}
22-
ms.update(parser.startIndex + name.length + 2, parser.endIndex - 1, rawValue)
26+
needUpdate && ms.update(parser.startIndex + name.length + 2, parser.endIndex - 1, rawValue)
2327
}
24-
// if (isVue) {
25-
// if (name === ':class') {
26-
// const { code } = jsHandler(value, {
27-
// ctx,
28-
// })
29-
// ms.update(parser.startIndex + name.length + 2, parser.endIndex - 1, code)
30-
// }
31-
// }
3228
},
3329
})
3430
parser.write(ms.original)
3531
parser.end()
36-
return ms.toString()
32+
return {
33+
code: ms.toString(),
34+
}
3735
}

packages/core/src/js/index.ts

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import type { StringLiteral, TemplateElement } from '@babel/types'
22
import MagicString from 'magic-string'
33
import { jsStringEscape } from '@ast-core/escape'
4-
import type { IJsHandlerOptions } from '../types'
5-
import { makeRegex, splitCode } from '../shared'
4+
import { sort } from 'fast-sort'
5+
import type { IHandlerTransformResult, IJsHandlerOptions } from '@/types'
6+
import { makeRegex, splitCode } from '@/shared'
67
import { parse, traverse } from '@/babel'
78

89
export function handleValue(raw: string, node: StringLiteral | TemplateElement, options: IJsHandlerOptions, ms: MagicString, offset: number, escape: boolean) {
@@ -40,7 +41,7 @@ export function handleValue(raw: string, node: StringLiteral | TemplateElement,
4041
return rawString
4142
}
4243

43-
export function jsHandler(rawSource: string | MagicString, options: IJsHandlerOptions) {
44+
export function jsHandler(rawSource: string | MagicString, options: IJsHandlerOptions): IHandlerTransformResult {
4445
const ms: MagicString = typeof rawSource === 'string' ? new MagicString(rawSource) : rawSource
4546
let ast
4647
try {
@@ -53,6 +54,7 @@ export function jsHandler(rawSource: string | MagicString, options: IJsHandlerOp
5354
code: ms.original,
5455
}
5556
}
57+
const { ctx } = options
5658

5759
traverse(ast, {
5860
StringLiteral: {
@@ -67,6 +69,41 @@ export function jsHandler(rawSource: string | MagicString, options: IJsHandlerOp
6769
handleValue(n.value.raw, n, options, ms, 0, false)
6870
},
6971
},
72+
CallExpression: {
73+
enter(p) {
74+
const callee = p.get('callee')
75+
if (callee.isIdentifier() && ctx.isPreserveFunction(callee.node.name)) {
76+
p.traverse({
77+
StringLiteral: {
78+
enter(path) {
79+
const node = path.node
80+
const value = node.value
81+
const arr = sort(splitCode(value)).desc(x => x.length)
82+
83+
for (const str of arr) {
84+
if (ctx.replaceMap.has(str)) {
85+
ctx.addPreserveClass(str)
86+
}
87+
}
88+
},
89+
},
90+
TemplateElement: {
91+
enter(path) {
92+
const node = path.node
93+
const value = node.value.raw
94+
const arr = sort(splitCode(value)).desc(x => x.length)
95+
96+
for (const str of arr) {
97+
if (ctx.replaceMap.has(str)) {
98+
ctx.addPreserveClass(str)
99+
}
100+
}
101+
},
102+
},
103+
})
104+
}
105+
},
106+
},
70107
})
71108

72109
return {

packages/core/src/types.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type MagicString from 'magic-string'
1+
import type { TransformResult } from 'unplugin'
22
import type { Context } from './ctx'
33

44
export interface IClassGeneratorContextItem {
@@ -16,6 +16,12 @@ export interface IClassGeneratorOptions {
1616
classPrefix?: string
1717
}
1818

19+
export interface IHandler {
20+
(code: string, options: IHandlerOptions): IHandlerTransformResult
21+
}
22+
23+
export type IHandlerTransformResult = Exclude<TransformResult, null | undefined | string>
24+
1925
export interface IHandlerOptions {
2026
ctx: Context
2127
id?: string

packages/core/test/__snapshots__/js.test.ts.snap

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,19 @@ cn(\`tw-e tw-f bg-red-600 and bg-red-600/50\`)
667667
twMerge('tw-g tw-h tw-d and tw-b')"
668668
`;
669669
670+
exports[`js handler > preserve-fn-case0.js case 1 2`] = `
671+
Map {
672+
"bg-red-500/50" => "tw-a",
673+
"bg-red-400/50" => "tw-b",
674+
"bg-red-500" => "tw-c",
675+
"bg-red-400" => "tw-d",
676+
"w-2" => "tw-e",
677+
"h-2" => "tw-f",
678+
"w-1" => "tw-g",
679+
"h-1" => "tw-h",
680+
}
681+
`;
682+
670683
exports[`js handler > preserve-fn-case0.js case 2 1`] = `
671684
"import { clsx } from "clsx";
672685
import { twMerge } from "tailwind-merge";
@@ -682,6 +695,19 @@ cn(\`tw-e tw-f bg-red-600 and bg-red-600/50\`)
682695
twMerge('tw-g tw-h tw-d and tw-b')"
683696
`;
684697
698+
exports[`js handler > preserve-fn-case0.js case 2 2`] = `
699+
Map {
700+
"bg-red-500/50" => "tw-a",
701+
"bg-red-400/50" => "tw-b",
702+
"bg-red-500" => "tw-c",
703+
"bg-red-400" => "tw-d",
704+
"w-2" => "tw-e",
705+
"h-2" => "tw-f",
706+
"w-1" => "tw-g",
707+
"h-1" => "tw-h",
708+
}
709+
`;
710+
685711
exports[`js handler > preserve-fn-case0.js case 3 1`] = `
686712
"import { clsx } from "clsx";
687713
import { twMerge } from "tailwind-merge";
@@ -697,6 +723,19 @@ cn(\`tw-e tw-f bg-red-600 and bg-red-600/50\`)
697723
twMerge('tw-g tw-h tw-d and tw-b')"
698724
`;
699725
726+
exports[`js handler > preserve-fn-case0.js case 3 2`] = `
727+
Map {
728+
"bg-red-500/50" => "tw-a",
729+
"bg-red-400/50" => "tw-b",
730+
"bg-red-500" => "tw-c",
731+
"bg-red-400" => "tw-d",
732+
"w-2" => "tw-e",
733+
"h-2" => "tw-f",
734+
"w-1" => "tw-g",
735+
"h-1" => "tw-h",
736+
}
737+
`;
738+
700739
exports[`js handler > trailing slash case 0 1`] = `
701740
"document.getElementById('#app').classList.add('tw-a tw-b')
702741
"

packages/core/test/__snapshots__/vue.test.ts.snap

Lines changed: 0 additions & 135 deletions
This file was deleted.

0 commit comments

Comments
 (0)