Skip to content

Commit b1955e3

Browse files
committed
feat: commit more options
1 parent f638e28 commit b1955e3

File tree

14 files changed

+309
-30
lines changed

14 files changed

+309
-30
lines changed

packages/core/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
# tailwindcss-mangle-core
22

33
The core of tailwindcss-mangle
4+
5+
## Usage
6+
7+
// TODO

packages/core/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "tailwindcss-mangle-core",
3-
"version": "1.0.0",
3+
"version": "1.0.1",
44
"description": "The core of tailwindcss-mangle",
55
"main": "dist/index.js",
66
"module": "./dist/index.mjs",
@@ -13,7 +13,7 @@
1313
"build": "cross-env NODE_ENV=production rollup -c",
1414
"dev:tsc": "tsc -p tsconfig.json --sourceMap",
1515
"build:tsc": "tsc -p tsconfig.json",
16-
"test": "jest"
16+
"test": "yarn build && jest"
1717
},
1818
"keywords": [
1919
"tailwindcss",

packages/core/src/css/plugins.ts

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,28 @@
11
import { IClassGeneratorContextItem, ICssHandlerOptions } from '@/types'
22
import type { PluginCreator } from 'postcss'
3-
3+
import defu from 'defu'
44
import parser from 'postcss-selector-parser'
55
export type PostcssMangleTailwindcssPlugin = PluginCreator<ICssHandlerOptions>
66

77
const postcssPlugin = 'postcss-mangle-tailwindcss-plugin'
88

9+
export function isVueScoped(s: parser.ClassName): boolean {
10+
if (s.parent) {
11+
const idx = s.parent.nodes.indexOf(s)
12+
if (idx > -1) {
13+
const nextNode = s.parent.nodes[idx + 1]
14+
if (nextNode && nextNode.type === 'attribute' && nextNode.attribute.indexOf('data-v-') > -1) {
15+
return true
16+
}
17+
}
18+
}
19+
return false
20+
}
21+
922
const postcssMangleTailwindcssPlugin: PostcssMangleTailwindcssPlugin = (options) => {
23+
const { ignoreVueScoped } = defu(options, {
24+
ignoreVueScoped: true
25+
})
1026
if (options?.scene === 'loader') {
1127
// must set newClassMap options
1228
let set: Set<string> = new Set()
@@ -25,15 +41,8 @@ const postcssMangleTailwindcssPlugin: PostcssMangleTailwindcssPlugin = (options)
2541
const existed = set.has(s.value)
2642

2743
if (existed) {
28-
// vue scoped
29-
if (s.parent) {
30-
const idx = s.parent.nodes.indexOf(s)
31-
if (idx > -1) {
32-
const nextNode = s.parent.nodes[idx + 1]
33-
if (nextNode && nextNode.type === 'attribute' && nextNode.attribute.indexOf('data-v-') > -1) {
34-
return
35-
}
36-
}
44+
if (ignoreVueScoped && isVueScoped(s)) {
45+
return
3746
}
3847
s.value = options.classGenerator.generateClassName(s.value).name
3948
}
@@ -61,15 +70,8 @@ const postcssMangleTailwindcssPlugin: PostcssMangleTailwindcssPlugin = (options)
6170
const existed = Boolean(hit)
6271

6372
if (existed) {
64-
// vue scoped
65-
if (s.parent) {
66-
const idx = s.parent.nodes.indexOf(s)
67-
if (idx > -1) {
68-
const nextNode = s.parent.nodes[idx + 1]
69-
if (nextNode && nextNode.type === 'attribute' && nextNode.attribute.indexOf('data-v-') > -1) {
70-
return
71-
}
72-
}
73+
if (ignoreVueScoped && isVueScoped(s)) {
74+
return
7375
}
7476
s.value = hit.name
7577
}

packages/core/src/html/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { parse, serialize } from 'parse5'
22
import { traverse } from '@parse5/tools'
3-
import { IHandlerOptions } from '../types'
3+
import { IHtmlHandlerOptions } from '../types'
44

5-
export function htmlHandler(rawSource: string, options: IHandlerOptions) {
5+
export function htmlHandler(rawSource: string, options: IHtmlHandlerOptions) {
66
const { runtimeSet, classGenerator } = options
77
const fragment = parse(rawSource)
88
traverse(fragment, {

packages/core/src/js/index.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
import type { StringLiteral, TemplateElement, CallExpression } from '@babel/types'
22
import * as t from '@babel/types'
33
import { transformSync, type BabelFileResult, type NodePath } from '@babel/core'
4-
import type { IHandlerOptions } from '../types'
4+
import type { IJsHandlerOptions } from '../types'
55
import { escapeStringRegexp } from '../utils'
66
import { splitCode } from './split'
77

88
export function makeRegex(str: string) {
99
return new RegExp('(?<=^|[\\s"])' + escapeStringRegexp(str), 'g')
1010
}
1111

12-
export function handleValue(str: string, node: StringLiteral | TemplateElement, options: IHandlerOptions) {
13-
const set = options.runtimeSet
14-
const clsGen = options.classGenerator
15-
const arr = splitCode(str)
12+
export function handleValue(str: string, node: StringLiteral | TemplateElement, options: IJsHandlerOptions) {
13+
const { runtimeSet: set, classGenerator: clsGen, splitQuote = true } = options
14+
15+
const arr = splitCode(str, {
16+
splitQuote
17+
})
1618
let rawStr = str
1719
for (let i = 0; i < arr.length; i++) {
1820
const v = arr[i]
@@ -30,7 +32,7 @@ export function handleValue(str: string, node: StringLiteral | TemplateElement,
3032
return rawStr
3133
}
3234

33-
export function jsHandler(rawSource: string, options: IHandlerOptions) {
35+
export function jsHandler(rawSource: string, options: IJsHandlerOptions) {
3436
const result = transformSync(rawSource, {
3537
babelrc: false,
3638
ast: true,

packages/core/src/js/split.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,12 @@ export function isValidSelector(selector = ''): selector is string {
44
return validateFilterRE.test(selector)
55
}
66

7-
export const splitCode = (code: string) => code.split(/[\s"]+/).filter(isValidSelector)
7+
export const splitCode = (
8+
code: string,
9+
options: {
10+
splitQuote?: boolean
11+
} = { splitQuote: true }
12+
) => {
13+
const regex = options.splitQuote ? /[\s"]+/ : /[\s]+/
14+
return code.split(regex).filter(isValidSelector)
15+
}

packages/core/src/types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,15 @@ export interface IHandlerOptions {
2626
classGenerator: ClassGenerator
2727
}
2828

29+
export interface IHtmlHandlerOptions extends IHandlerOptions {}
30+
31+
export interface IJsHandlerOptions extends IHandlerOptions {
32+
splitQuote?: boolean
33+
}
34+
2935
export interface ICssHandlerOptions extends IHandlerOptions {
3036
scene?: 'loader' | 'process'
37+
ignoreVueScoped?: boolean
3138
}
3239

3340
export interface ClassSetOutputOptions {

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ exports[`css vue scoped .gap-y-4[data-v-0f84999b] 1`] = `
2222
}"
2323
`;
2424

25+
exports[`css vue scoped no ignore .gap-y-4[data-v-0f84999b] 1`] = `
26+
"@media (min-width: 768px) {
27+
.tw-a[data-v-0f84999b] {
28+
}
29+
}"
30+
`;
31+
2532
exports[`css vue.scoped.css 1`] = `
2633
".flex[data-v-0f84999b] {
2734
display: flex;

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
exports[`js handler common StringLiteral 1`] = `"element.innerHTML = "<div class=\\"tw-a tw-b\\">count is counter</div>";"`;
44
5+
exports[`js handler common StringLiteral with splitQuote false 1`] = `"element.innerHTML = '<div class="dark:bg-zinc-800/30 lg:dark:bg-zinc-800/30">count is counter</div>';"`;
6+
57
exports[`js handler common TemplateElement 1`] = `
68
"const counter = 0;
79
element.innerHTML = \`<div class="tw-a tw-b">count is \${counter}</div>\`;"
@@ -233,3 +235,9 @@ exports[`js handler z-10 not transform 1`] = `
233235
className: "tw-a tw-b tw-c tw-d tw-e tw-f tw-g tw-h";
234236
}"
235237
`;
238+
239+
exports[`js handler z-10 not transform with splitQuote false 1`] = `
240+
"{
241+
className: "tw-a tw-b tw-c tw-d tw-e tw-f tw-g tw-h";
242+
}"
243+
`;

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

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,178 @@ exports[`split code split vue static str 1`] = `
205205
"1),",
206206
]
207207
`;
208+
209+
exports[`split code split vue static str with splitQuote false 1`] = `
210+
[
211+
"tl",
212+
"=",
213+
"ai("<div",
214+
"class="mb-32",
215+
"grid",
216+
"tw-xb",
217+
"tw-yb",
218+
"tw-zb",
219+
"lg:text-left"",
220+
"data-v-988e8bc1><a",
221+
"href="https://nextjs.org/docs?utm_source=create-next-app&amp;utm_medium=default-template-tw&amp;utm_campaign=create-next-app"",
222+
"class="group",
223+
"tw-ac",
224+
"border",
225+
"tw-bc",
226+
"tw-cc",
227+
"tw-dc",
228+
"tw-ec",
229+
"tw-fc",
230+
"tw-gc",
231+
"tw-hc",
232+
"hover:dark:bg-neutral-800/30"",
233+
"target="_blank"",
234+
"rel="noopener",
235+
"noreferrer"",
236+
"data-v-988e8bc1><h2",
237+
"class="mb-3",
238+
"tw-ic",
239+
"font-semibold"",
240+
"data-v-988e8bc1>",
241+
"Docs",
242+
"<span",
243+
"class="inline-block",
244+
"tw-jc",
245+
"tw-kc",
246+
"motion-reduce:transform-none"",
247+
"data-v-988e8bc1>-&gt;</span></h2><p",
248+
"class="m-0",
249+
"tw-lc",
250+
"tw-k",
251+
"opacity-50"",
252+
"data-v-988e8bc1>Find",
253+
"in-depth",
254+
"information",
255+
"about",
256+
"Next.js",
257+
"features",
258+
"and",
259+
"API.</p></a><a",
260+
"href="https://nextjs.org/learn?utm_source=create-next-app&amp;utm_medium=default-template-tw&amp;utm_campaign=create-next-app"",
261+
"class="group",
262+
"tw-ac",
263+
"border",
264+
"tw-bc",
265+
"tw-cc",
266+
"tw-dc",
267+
"tw-ec",
268+
"tw-fc",
269+
"tw-gc",
270+
"tw-hc",
271+
"hover:dark:bg-neutral-800/30"",
272+
"target="_blank"",
273+
"rel="noopener",
274+
"noreferrer"",
275+
"data-v-988e8bc1><h2",
276+
"class="mb-3",
277+
"tw-ic",
278+
"font-semibold"",
279+
"data-v-988e8bc1>",
280+
"Learn",
281+
"<span",
282+
"class="inline-block",
283+
"tw-jc",
284+
"tw-kc",
285+
"motion-reduce:transform-none"",
286+
"data-v-988e8bc1>-&gt;</span></h2><p",
287+
"class="m-0",
288+
"tw-lc",
289+
"tw-k",
290+
"opacity-50"",
291+
"data-v-988e8bc1>Learn",
292+
"about",
293+
"Next.js",
294+
"in",
295+
"an",
296+
"interactive",
297+
"course",
298+
"with",
299+
"quizzes!</p></a><a",
300+
"href="https://vercel.com/templates?framework=next.js&amp;utm_source=create-next-app&amp;utm_medium=default-template-tw&amp;utm_campaign=create-next-app"",
301+
"class="group",
302+
"tw-ac",
303+
"border",
304+
"tw-bc",
305+
"tw-cc",
306+
"tw-dc",
307+
"tw-ec",
308+
"tw-fc",
309+
"tw-gc",
310+
"tw-hc",
311+
"hover:dark:bg-neutral-800/30"",
312+
"target="_blank"",
313+
"rel="noopener",
314+
"noreferrer"",
315+
"data-v-988e8bc1><h2",
316+
"class="mb-3",
317+
"tw-ic",
318+
"font-semibold"",
319+
"data-v-988e8bc1>",
320+
"Templates",
321+
"<span",
322+
"class="inline-block",
323+
"tw-jc",
324+
"tw-kc",
325+
"motion-reduce:transform-none"",
326+
"data-v-988e8bc1>-&gt;</span></h2><p",
327+
"class="m-0",
328+
"tw-lc",
329+
"tw-k",
330+
"opacity-50"",
331+
"data-v-988e8bc1>Discover",
332+
"and",
333+
"deploy",
334+
"boilerplate",
335+
"example",
336+
"Next.js",
337+
"projects.</p></a><a",
338+
"href="https://vercel.com/new?utm_source=create-next-app&amp;utm_medium=default-template-tw&amp;utm_campaign=create-next-app"",
339+
"class="group",
340+
"tw-ac",
341+
"border",
342+
"tw-bc",
343+
"tw-cc",
344+
"tw-dc",
345+
"tw-ec",
346+
"tw-fc",
347+
"tw-gc",
348+
"tw-hc",
349+
"hover:dark:bg-neutral-800/30"",
350+
"target="_blank"",
351+
"rel="noopener",
352+
"noreferrer"",
353+
"data-v-988e8bc1><h2",
354+
"class="mb-3",
355+
"tw-ic",
356+
"font-semibold"",
357+
"data-v-988e8bc1>",
358+
"Deploy",
359+
"<span",
360+
"class="inline-block",
361+
"tw-jc",
362+
"tw-kc",
363+
"motion-reduce:transform-none"",
364+
"data-v-988e8bc1>-&gt;</span></h2><p",
365+
"class="m-0",
366+
"tw-lc",
367+
"tw-k",
368+
"opacity-50"",
369+
"data-v-988e8bc1>Instantly",
370+
"deploy",
371+
"your",
372+
"Next.js",
373+
"site",
374+
"to",
375+
"a",
376+
"shareable",
377+
"URL",
378+
"with",
379+
"Vercel.</p></a></div>",",
380+
"1),",
381+
]
382+
`;

0 commit comments

Comments
 (0)