@tailwindcss-mangle/core 2.1.0 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +321 -158
- package/dist/index.d.cts +89 -0
- package/dist/index.d.mts +89 -0
- package/dist/index.d.ts +46 -8
- package/dist/index.mjs +320 -161
- package/package.json +23 -10
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import { resolve, isAbsolute } from 'node:path';
|
|
3
|
+
import { ClassGenerator, defaultMangleClassFilter, splitCode, makeRegex } from '@tailwindcss-mangle/shared';
|
|
4
|
+
export { ClassGenerator } from '@tailwindcss-mangle/shared';
|
|
5
|
+
import { getConfig } from '@tailwindcss-mangle/config';
|
|
6
|
+
import { sort } from 'fast-sort';
|
|
7
|
+
import micromatch from 'micromatch';
|
|
1
8
|
import postcss from 'postcss';
|
|
2
9
|
import parser from 'postcss-selector-parser';
|
|
3
10
|
import { html, defaultTreeAdapter, parse, serialize } from 'parse5';
|
|
4
|
-
import {
|
|
5
|
-
export { ClassGenerator } from '@tailwindcss-mangle/shared';
|
|
6
|
-
import babel, { transformSync } from '@babel/core';
|
|
11
|
+
import babel, { transformSync as transformSync$1 } from '@babel/core';
|
|
7
12
|
import { declare } from '@babel/helper-plugin-utils';
|
|
8
13
|
import MagicString from 'magic-string';
|
|
9
14
|
import { jsStringEscape } from '@ast-core/escape';
|
|
@@ -59,7 +64,126 @@ function createDefu(merger) {
|
|
|
59
64
|
}
|
|
60
65
|
const defu = createDefu();
|
|
61
66
|
|
|
67
|
+
const { isMatch } = micromatch;
|
|
68
|
+
function escapeStringRegexp(str) {
|
|
69
|
+
if (typeof str !== "string") {
|
|
70
|
+
throw new TypeError("Expected a string");
|
|
71
|
+
}
|
|
72
|
+
return str.replaceAll(/[$()*+.?[\\\]^{|}]/g, "\\$&").replaceAll("-", "\\x2d");
|
|
73
|
+
}
|
|
74
|
+
function createGlobMatcher(pattern, fallbackValue = false) {
|
|
75
|
+
if (pattern === void 0) {
|
|
76
|
+
return function() {
|
|
77
|
+
return fallbackValue;
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
return function(file) {
|
|
81
|
+
return isMatch(file, pattern);
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
var __defProp = Object.defineProperty;
|
|
86
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
87
|
+
var __publicField = (obj, key, value) => {
|
|
88
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
89
|
+
return value;
|
|
90
|
+
};
|
|
91
|
+
class Context {
|
|
92
|
+
constructor() {
|
|
93
|
+
__publicField(this, "options");
|
|
94
|
+
__publicField(this, "includeMatcher");
|
|
95
|
+
__publicField(this, "excludeMatcher");
|
|
96
|
+
__publicField(this, "replaceMap");
|
|
97
|
+
__publicField(this, "classSet");
|
|
98
|
+
__publicField(this, "classGenerator");
|
|
99
|
+
__publicField(this, "preserveFunctionSet");
|
|
100
|
+
__publicField(this, "preserveClassNamesSet");
|
|
101
|
+
__publicField(this, "preserveFunctionRegexs");
|
|
102
|
+
this.options = {};
|
|
103
|
+
this.classSet = /* @__PURE__ */ new Set();
|
|
104
|
+
this.replaceMap = /* @__PURE__ */ new Map();
|
|
105
|
+
this.includeMatcher = () => true;
|
|
106
|
+
this.excludeMatcher = () => false;
|
|
107
|
+
this.classGenerator = new ClassGenerator();
|
|
108
|
+
this.preserveFunctionSet = /* @__PURE__ */ new Set();
|
|
109
|
+
this.preserveClassNamesSet = /* @__PURE__ */ new Set();
|
|
110
|
+
this.preserveFunctionRegexs = [];
|
|
111
|
+
}
|
|
112
|
+
isPreserveClass(className) {
|
|
113
|
+
return this.preserveClassNamesSet.has(className);
|
|
114
|
+
}
|
|
115
|
+
addPreserveClass(className) {
|
|
116
|
+
return this.preserveClassNamesSet.add(className);
|
|
117
|
+
}
|
|
118
|
+
isPreserveFunction(calleeName) {
|
|
119
|
+
return this.preserveFunctionSet.has(calleeName);
|
|
120
|
+
}
|
|
121
|
+
mergeOptions(...opts) {
|
|
122
|
+
this.options = defu(this.options, ...opts);
|
|
123
|
+
this.includeMatcher = createGlobMatcher(this.options.include, true);
|
|
124
|
+
this.excludeMatcher = createGlobMatcher(this.options.exclude, false);
|
|
125
|
+
this.classGenerator = new ClassGenerator(this.options.classGenerator);
|
|
126
|
+
this.preserveFunctionSet = new Set(this.options?.preserveFunction ?? []);
|
|
127
|
+
this.preserveFunctionRegexs = [...this.preserveFunctionSet.values()].map((x) => {
|
|
128
|
+
return new RegExp(escapeStringRegexp(x) + "\\(([^)]*)\\)", "g");
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
isInclude(file) {
|
|
132
|
+
return this.includeMatcher(file) && !this.excludeMatcher(file);
|
|
133
|
+
}
|
|
134
|
+
currentMangleClassFilter(className) {
|
|
135
|
+
return (this.options.mangleClassFilter ?? defaultMangleClassFilter)(className);
|
|
136
|
+
}
|
|
137
|
+
getClassSet() {
|
|
138
|
+
return this.classSet;
|
|
139
|
+
}
|
|
140
|
+
getReplaceMap() {
|
|
141
|
+
return this.replaceMap;
|
|
142
|
+
}
|
|
143
|
+
addToUsedBy(key, file) {
|
|
144
|
+
const hit = this.classGenerator.newClassMap[key];
|
|
145
|
+
if (hit) {
|
|
146
|
+
hit.usedBy.add(file);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
loadClassSet(classList) {
|
|
150
|
+
const list = sort(classList).desc((c) => c.length);
|
|
151
|
+
for (const className of list) {
|
|
152
|
+
if (this.currentMangleClassFilter(className)) {
|
|
153
|
+
this.classSet.add(className);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async initConfig(opts = {}) {
|
|
158
|
+
const { cwd, classList: _classList, mangleOptions } = opts;
|
|
159
|
+
const { config, cwd: configCwd } = await getConfig(cwd);
|
|
160
|
+
this.mergeOptions(mangleOptions, config?.mangle);
|
|
161
|
+
if (_classList) {
|
|
162
|
+
this.loadClassSet(_classList);
|
|
163
|
+
} else {
|
|
164
|
+
let jsonPath = this.options.classListPath ?? resolve(process.cwd(), config?.patch?.output?.filename);
|
|
165
|
+
if (!isAbsolute(jsonPath)) {
|
|
166
|
+
jsonPath = resolve(configCwd ?? process.cwd(), jsonPath);
|
|
167
|
+
}
|
|
168
|
+
if (jsonPath && fs.existsSync(jsonPath)) {
|
|
169
|
+
const rawClassList = fs.readFileSync(jsonPath, "utf8");
|
|
170
|
+
const list = JSON.parse(rawClassList);
|
|
171
|
+
this.loadClassSet(list);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
for (const cls of this.classSet) {
|
|
175
|
+
this.classGenerator.generateClassName(cls);
|
|
176
|
+
}
|
|
177
|
+
for (const x of Object.entries(this.classGenerator.newClassMap)) {
|
|
178
|
+
this.replaceMap.set(x[0], x[1].name);
|
|
179
|
+
}
|
|
180
|
+
return config;
|
|
181
|
+
}
|
|
182
|
+
// ["clsx\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"]
|
|
183
|
+
}
|
|
184
|
+
|
|
62
185
|
const postcssPlugin = "postcss-mangle-tailwindcss-plugin";
|
|
186
|
+
const clonedKey = "__tw_mangle_cloned__";
|
|
63
187
|
function isVueScoped(s) {
|
|
64
188
|
if (s.parent) {
|
|
65
189
|
const index = s.parent.nodes.indexOf(s);
|
|
@@ -73,12 +197,15 @@ function isVueScoped(s) {
|
|
|
73
197
|
return false;
|
|
74
198
|
}
|
|
75
199
|
const transformSelectorPostcssPlugin = function(options) {
|
|
76
|
-
const { ignoreVueScoped, replaceMap } = defu(options, {
|
|
200
|
+
const { ignoreVueScoped, replaceMap, ctx } = defu(options, {
|
|
77
201
|
ignoreVueScoped: true
|
|
78
202
|
});
|
|
79
203
|
return {
|
|
80
204
|
postcssPlugin,
|
|
81
205
|
async Rule(rule) {
|
|
206
|
+
if (rule[clonedKey]) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
82
209
|
await parser((selectors) => {
|
|
83
210
|
selectors.walkClasses((s) => {
|
|
84
211
|
if (s.value && replaceMap && replaceMap.has(s.value)) {
|
|
@@ -87,6 +214,10 @@ const transformSelectorPostcssPlugin = function(options) {
|
|
|
87
214
|
}
|
|
88
215
|
const v = replaceMap.get(s.value);
|
|
89
216
|
if (v) {
|
|
217
|
+
if (ctx.isPreserveClass(s.value)) {
|
|
218
|
+
const r = rule.cloneBefore();
|
|
219
|
+
r[clonedKey] = true;
|
|
220
|
+
}
|
|
90
221
|
s.value = v;
|
|
91
222
|
}
|
|
92
223
|
}
|
|
@@ -203,7 +334,7 @@ function traverse(node, visitor, parent) {
|
|
|
203
334
|
}
|
|
204
335
|
|
|
205
336
|
function htmlHandler(rawSource, options) {
|
|
206
|
-
const { replaceMap,
|
|
337
|
+
const { replaceMap, ctx } = options;
|
|
207
338
|
const fragment = parse(rawSource);
|
|
208
339
|
traverse(fragment, {
|
|
209
340
|
element(node) {
|
|
@@ -214,7 +345,7 @@ function htmlHandler(rawSource, options) {
|
|
|
214
345
|
});
|
|
215
346
|
for (const v of array) {
|
|
216
347
|
if (replaceMap.has(v)) {
|
|
217
|
-
attribute.value = attribute.value.replace(makeRegex(v), classGenerator.generateClassName(v).name);
|
|
348
|
+
attribute.value = attribute.value.replace(makeRegex(v), ctx.classGenerator.generateClassName(v).name);
|
|
218
349
|
}
|
|
219
350
|
}
|
|
220
351
|
}
|
|
@@ -225,130 +356,26 @@ function htmlHandler(rawSource, options) {
|
|
|
225
356
|
|
|
226
357
|
const isProd = () => process.env.NODE_ENV === "production";
|
|
227
358
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
};
|
|
235
|
-
var unpackObjectSorter = function (sortByObj) {
|
|
236
|
-
var _a = sortByObj || {}, asc = _a.asc, desc = _a.desc;
|
|
237
|
-
var order = asc ? 1 : -1;
|
|
238
|
-
var sortBy = (asc || desc);
|
|
239
|
-
// Validate object config
|
|
240
|
-
throwInvalidConfigErrorIfTrue(!sortBy, 'Expected `asc` or `desc` property');
|
|
241
|
-
throwInvalidConfigErrorIfTrue(asc && desc, 'Ambiguous object with `asc` and `desc` config properties');
|
|
242
|
-
var comparer = sortByObj.comparer && castComparer(sortByObj.comparer);
|
|
243
|
-
return { order: order, sortBy: sortBy, comparer: comparer };
|
|
244
|
-
};
|
|
245
|
-
// >>> SORTERS <<<
|
|
246
|
-
var multiPropertySorterProvider = function (defaultComparer) {
|
|
247
|
-
return function multiPropertySorter(sortBy, sortByArr, depth, order, comparer, a, b) {
|
|
248
|
-
var valA;
|
|
249
|
-
var valB;
|
|
250
|
-
if (typeof sortBy === 'string') {
|
|
251
|
-
valA = a[sortBy];
|
|
252
|
-
valB = b[sortBy];
|
|
253
|
-
}
|
|
254
|
-
else if (typeof sortBy === 'function') {
|
|
255
|
-
valA = sortBy(a);
|
|
256
|
-
valB = sortBy(b);
|
|
257
|
-
}
|
|
258
|
-
else {
|
|
259
|
-
var objectSorterConfig = unpackObjectSorter(sortBy);
|
|
260
|
-
return multiPropertySorter(objectSorterConfig.sortBy, sortByArr, depth, objectSorterConfig.order, objectSorterConfig.comparer || defaultComparer, a, b);
|
|
261
|
-
}
|
|
262
|
-
var equality = comparer(valA, valB, order);
|
|
263
|
-
if ((equality === 0 || (valA == null && valB == null)) &&
|
|
264
|
-
sortByArr.length > depth) {
|
|
265
|
-
return multiPropertySorter(sortByArr[depth], sortByArr, depth + 1, order, comparer, a, b);
|
|
266
|
-
}
|
|
267
|
-
return equality;
|
|
268
|
-
};
|
|
269
|
-
};
|
|
270
|
-
function getSortStrategy(sortBy, comparer, order) {
|
|
271
|
-
// Flat array sorter
|
|
272
|
-
if (sortBy === undefined || sortBy === true) {
|
|
273
|
-
return function (a, b) { return comparer(a, b, order); };
|
|
274
|
-
}
|
|
275
|
-
// Sort list of objects by single object key
|
|
276
|
-
if (typeof sortBy === 'string') {
|
|
277
|
-
throwInvalidConfigErrorIfTrue(sortBy.includes('.'), 'String syntax not allowed for nested properties.');
|
|
278
|
-
return function (a, b) { return comparer(a[sortBy], b[sortBy], order); };
|
|
279
|
-
}
|
|
280
|
-
// Sort list of objects by single function sorter
|
|
281
|
-
if (typeof sortBy === 'function') {
|
|
282
|
-
return function (a, b) { return comparer(sortBy(a), sortBy(b), order); };
|
|
283
|
-
}
|
|
284
|
-
// Sort by multiple properties
|
|
285
|
-
if (Array.isArray(sortBy)) {
|
|
286
|
-
var multiPropSorter_1 = multiPropertySorterProvider(comparer);
|
|
287
|
-
return function (a, b) { return multiPropSorter_1(sortBy[0], sortBy, 1, order, comparer, a, b); };
|
|
288
|
-
}
|
|
289
|
-
// Unpack object config to get actual sorter strategy
|
|
290
|
-
var objectSorterConfig = unpackObjectSorter(sortBy);
|
|
291
|
-
return getSortStrategy(objectSorterConfig.sortBy, objectSorterConfig.comparer || comparer, objectSorterConfig.order);
|
|
292
|
-
}
|
|
293
|
-
var sortArray = function (order, ctx, sortBy, comparer) {
|
|
294
|
-
var _a;
|
|
295
|
-
if (!Array.isArray(ctx)) {
|
|
296
|
-
return ctx;
|
|
297
|
-
}
|
|
298
|
-
// Unwrap sortBy if array with only 1 value to get faster sort strategy
|
|
299
|
-
if (Array.isArray(sortBy) && sortBy.length < 2) {
|
|
300
|
-
_a = sortBy, sortBy = _a[0];
|
|
301
|
-
}
|
|
302
|
-
return ctx.sort(getSortStrategy(sortBy, comparer, order));
|
|
303
|
-
};
|
|
304
|
-
function createNewSortInstance(opts) {
|
|
305
|
-
var comparer = castComparer(opts.comparer);
|
|
306
|
-
return function (arrayToSort) {
|
|
307
|
-
var ctx = Array.isArray(arrayToSort) && !opts.inPlaceSorting
|
|
308
|
-
? arrayToSort.slice()
|
|
309
|
-
: arrayToSort;
|
|
310
|
-
return {
|
|
311
|
-
asc: function (sortBy) {
|
|
312
|
-
return sortArray(1, ctx, sortBy, comparer);
|
|
313
|
-
},
|
|
314
|
-
desc: function (sortBy) {
|
|
315
|
-
return sortArray(-1, ctx, sortBy, comparer);
|
|
316
|
-
},
|
|
317
|
-
by: function (sortBy) {
|
|
318
|
-
return sortArray(1, ctx, sortBy, comparer);
|
|
319
|
-
},
|
|
320
|
-
};
|
|
321
|
-
};
|
|
322
|
-
}
|
|
323
|
-
var defaultComparer = function (a, b, order) {
|
|
324
|
-
if (a == null)
|
|
325
|
-
return order;
|
|
326
|
-
if (b == null)
|
|
327
|
-
return -order;
|
|
328
|
-
if (typeof a !== typeof b) {
|
|
329
|
-
return typeof a < typeof b ? -1 : 1;
|
|
330
|
-
}
|
|
331
|
-
if (a < b)
|
|
332
|
-
return -1;
|
|
333
|
-
if (a > b)
|
|
334
|
-
return 1;
|
|
335
|
-
return 0;
|
|
336
|
-
};
|
|
337
|
-
var sort = createNewSortInstance({
|
|
338
|
-
comparer: defaultComparer,
|
|
339
|
-
});
|
|
340
|
-
createNewSortInstance({
|
|
341
|
-
comparer: defaultComparer,
|
|
342
|
-
inPlaceSorting: true,
|
|
343
|
-
});
|
|
359
|
+
function between(x, min, max, included = false) {
|
|
360
|
+
if (typeof x !== "number") {
|
|
361
|
+
return false;
|
|
362
|
+
}
|
|
363
|
+
return included ? x >= min && x <= max : x > min && x < max;
|
|
364
|
+
}
|
|
344
365
|
|
|
345
366
|
function handleValue$1(options) {
|
|
346
|
-
const {
|
|
367
|
+
const { ctx, id, path, magicString, raw, replaceMap, offset = 0, escape = false, markedArray } = options;
|
|
368
|
+
const node = path.node;
|
|
347
369
|
let value = raw;
|
|
370
|
+
for (const [s, e] of markedArray) {
|
|
371
|
+
if (between(node.start, s, e) || between(node.end, s, e)) {
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
348
375
|
const arr = sort(splitCode(value)).desc((x) => x.length);
|
|
349
376
|
for (const str of arr) {
|
|
350
377
|
if (replaceMap.has(str)) {
|
|
351
|
-
addToUsedBy(str, id);
|
|
378
|
+
ctx.addToUsedBy(str, id);
|
|
352
379
|
const v = replaceMap.get(str);
|
|
353
380
|
if (v) {
|
|
354
381
|
value = value.replaceAll(str, v);
|
|
@@ -363,76 +390,208 @@ function handleValue$1(options) {
|
|
|
363
390
|
}
|
|
364
391
|
}
|
|
365
392
|
}
|
|
366
|
-
const
|
|
393
|
+
const JsPlugin = declare((api, options) => {
|
|
367
394
|
api.assertVersion(7);
|
|
368
|
-
const { magicString, replaceMap, id,
|
|
395
|
+
const { magicString, replaceMap, id, ctx, markedArray } = options;
|
|
369
396
|
return {
|
|
370
397
|
visitor: {
|
|
371
398
|
StringLiteral: {
|
|
372
|
-
|
|
373
|
-
const
|
|
374
|
-
|
|
375
|
-
addToUsedBy,
|
|
399
|
+
exit(p) {
|
|
400
|
+
const opts = {
|
|
401
|
+
ctx,
|
|
376
402
|
id,
|
|
377
403
|
magicString,
|
|
378
|
-
|
|
379
|
-
raw: node.value,
|
|
404
|
+
path: p,
|
|
405
|
+
raw: p.node.value,
|
|
380
406
|
replaceMap,
|
|
381
407
|
offset: 1,
|
|
382
|
-
escape: true
|
|
383
|
-
|
|
408
|
+
escape: true,
|
|
409
|
+
markedArray
|
|
410
|
+
};
|
|
411
|
+
handleValue$1(opts);
|
|
384
412
|
}
|
|
385
413
|
},
|
|
386
414
|
TemplateElement: {
|
|
387
|
-
|
|
388
|
-
const
|
|
389
|
-
|
|
390
|
-
addToUsedBy,
|
|
415
|
+
exit(p) {
|
|
416
|
+
const opts = {
|
|
417
|
+
ctx,
|
|
391
418
|
id,
|
|
392
419
|
magicString,
|
|
393
|
-
|
|
394
|
-
raw: node.value.raw,
|
|
420
|
+
path: p,
|
|
421
|
+
raw: p.node.value.raw,
|
|
395
422
|
replaceMap,
|
|
396
423
|
offset: 0,
|
|
397
|
-
escape: false
|
|
398
|
-
|
|
424
|
+
escape: false,
|
|
425
|
+
markedArray
|
|
426
|
+
};
|
|
427
|
+
handleValue$1(opts);
|
|
399
428
|
}
|
|
400
429
|
}
|
|
401
430
|
}
|
|
402
431
|
};
|
|
403
432
|
});
|
|
433
|
+
function transformSync(ast, code, plugins, filename) {
|
|
434
|
+
babel.transformFromAstSync(ast, code, {
|
|
435
|
+
presets: loadPresets(),
|
|
436
|
+
plugins,
|
|
437
|
+
filename
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
function loadPresets() {
|
|
441
|
+
return [
|
|
442
|
+
[
|
|
443
|
+
require("@babel/preset-typescript"),
|
|
444
|
+
{
|
|
445
|
+
allExtensions: true,
|
|
446
|
+
isTSX: true
|
|
447
|
+
}
|
|
448
|
+
]
|
|
449
|
+
];
|
|
450
|
+
}
|
|
404
451
|
function preProcessJs(options) {
|
|
405
|
-
const { code, replaceMap, id,
|
|
452
|
+
const { code, replaceMap, id, ctx } = options;
|
|
406
453
|
const magicString = typeof code === "string" ? new MagicString(code) : code;
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
454
|
+
let ast;
|
|
455
|
+
try {
|
|
456
|
+
const file = babel.parseSync(magicString.original, {
|
|
457
|
+
sourceType: "unambiguous",
|
|
458
|
+
presets: loadPresets()
|
|
459
|
+
});
|
|
460
|
+
if (file) {
|
|
461
|
+
ast = file;
|
|
462
|
+
} else {
|
|
463
|
+
return code.toString();
|
|
464
|
+
}
|
|
465
|
+
} catch {
|
|
466
|
+
return code.toString();
|
|
467
|
+
}
|
|
468
|
+
const markedArray = [];
|
|
469
|
+
babel.traverse(ast, {
|
|
470
|
+
CallExpression: {
|
|
471
|
+
enter(p) {
|
|
472
|
+
const callee = p.get("callee");
|
|
473
|
+
if (callee.isIdentifier() && ctx.isPreserveFunction(callee.node.name)) {
|
|
474
|
+
if (p.node.start && p.node.end) {
|
|
475
|
+
markedArray.push([p.node.start, p.node.end]);
|
|
476
|
+
}
|
|
477
|
+
p.traverse({
|
|
478
|
+
StringLiteral: {
|
|
479
|
+
enter(path) {
|
|
480
|
+
const node = path.node;
|
|
481
|
+
const value = node.value;
|
|
482
|
+
const arr = sort(splitCode(value)).desc((x) => x.length);
|
|
483
|
+
for (const str of arr) {
|
|
484
|
+
if (replaceMap.has(str)) {
|
|
485
|
+
ctx.addPreserveClass(str);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
},
|
|
490
|
+
TemplateElement: {
|
|
491
|
+
enter(path) {
|
|
492
|
+
const node = path.node;
|
|
493
|
+
const value = node.value.raw;
|
|
494
|
+
const arr = sort(splitCode(value)).desc((x) => x.length);
|
|
495
|
+
for (const str of arr) {
|
|
496
|
+
if (replaceMap.has(str)) {
|
|
497
|
+
ctx.addPreserveClass(str);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
});
|
|
415
503
|
}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
});
|
|
507
|
+
transformSync(
|
|
508
|
+
ast,
|
|
509
|
+
magicString.original,
|
|
510
|
+
[
|
|
419
511
|
[
|
|
420
|
-
|
|
512
|
+
JsPlugin,
|
|
421
513
|
{
|
|
422
514
|
magicString,
|
|
423
515
|
replaceMap,
|
|
424
516
|
id,
|
|
425
|
-
|
|
517
|
+
ctx,
|
|
518
|
+
markedArray
|
|
426
519
|
}
|
|
427
520
|
]
|
|
428
521
|
],
|
|
429
|
-
|
|
430
|
-
|
|
522
|
+
id
|
|
523
|
+
);
|
|
524
|
+
return magicString.toString();
|
|
525
|
+
}
|
|
526
|
+
function preProcessRawCode(options) {
|
|
527
|
+
const { code, replaceMap, ctx } = options;
|
|
528
|
+
const magicString = typeof code === "string" ? new MagicString(code) : code;
|
|
529
|
+
const markArr = [];
|
|
530
|
+
for (const regex of ctx.preserveFunctionRegexs) {
|
|
531
|
+
const allArr = [];
|
|
532
|
+
let arr = null;
|
|
533
|
+
while ((arr = regex.exec(magicString.original)) !== null) {
|
|
534
|
+
allArr.push(arr);
|
|
535
|
+
markArr.push([arr.index, arr.index + arr[0].length]);
|
|
536
|
+
}
|
|
537
|
+
for (const regExpMatch of allArr) {
|
|
538
|
+
let ast;
|
|
539
|
+
try {
|
|
540
|
+
ast = babel.parseSync(regExpMatch[0], {
|
|
541
|
+
sourceType: "unambiguous"
|
|
542
|
+
});
|
|
543
|
+
ast && babel.traverse(ast, {
|
|
544
|
+
StringLiteral: {
|
|
545
|
+
enter(p) {
|
|
546
|
+
const arr2 = sort(splitCode(p.node.value)).desc((x) => x.length);
|
|
547
|
+
for (const v of arr2) {
|
|
548
|
+
if (replaceMap.has(v)) {
|
|
549
|
+
ctx.addPreserveClass(v);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
},
|
|
554
|
+
TemplateElement: {
|
|
555
|
+
enter(p) {
|
|
556
|
+
const arr2 = sort(splitCode(p.node.value.raw)).desc((x) => x.length);
|
|
557
|
+
for (const v of arr2) {
|
|
558
|
+
if (replaceMap.has(v)) {
|
|
559
|
+
ctx.addPreserveClass(v);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
});
|
|
565
|
+
} catch {
|
|
566
|
+
continue;
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
for (const [key, value] of replaceMap) {
|
|
571
|
+
const regex = new RegExp(escapeStringRegexp(key), "g");
|
|
572
|
+
let arr = null;
|
|
573
|
+
while ((arr = regex.exec(magicString.original)) !== null) {
|
|
574
|
+
const start = arr.index;
|
|
575
|
+
const end = arr.index + arr[0].length;
|
|
576
|
+
let shouldUpdate = true;
|
|
577
|
+
for (const [ps, pe] of markArr) {
|
|
578
|
+
if (between(start, ps, pe) || between(end, ps, pe)) {
|
|
579
|
+
shouldUpdate = false;
|
|
580
|
+
break;
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
if (shouldUpdate) {
|
|
584
|
+
magicString.update(start, end, value);
|
|
585
|
+
markArr.push([start, end]);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
}
|
|
431
589
|
return magicString.toString();
|
|
432
590
|
}
|
|
433
591
|
|
|
434
592
|
function handleValue(raw, node, options) {
|
|
435
|
-
const { replaceMap,
|
|
593
|
+
const { replaceMap, ctx, splitQuote = true } = options;
|
|
594
|
+
const clsGen = ctx.classGenerator;
|
|
436
595
|
const array = splitCode(raw, {
|
|
437
596
|
splitQuote
|
|
438
597
|
});
|
|
@@ -451,7 +610,7 @@ function handleValue(raw, node, options) {
|
|
|
451
610
|
return rawString;
|
|
452
611
|
}
|
|
453
612
|
function jsHandler(rawSource, options) {
|
|
454
|
-
const result = transformSync(rawSource, {
|
|
613
|
+
const result = transformSync$1(rawSource, {
|
|
455
614
|
babelrc: false,
|
|
456
615
|
ast: true,
|
|
457
616
|
plugins: [
|
|
@@ -499,4 +658,4 @@ function jsHandler(rawSource, options) {
|
|
|
499
658
|
return result;
|
|
500
659
|
}
|
|
501
660
|
|
|
502
|
-
export { cssHandler, handleValue, htmlHandler, jsHandler, preProcessJs };
|
|
661
|
+
export { Context, cssHandler, handleValue, htmlHandler, jsHandler, preProcessJs, preProcessRawCode };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tailwindcss-mangle/core",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "The core of tailwindcss-mangle",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -36,27 +36,40 @@
|
|
|
36
36
|
"registry": "https://registry.npmjs.org/"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@ast-core/escape": "^1.0.
|
|
40
|
-
"@babel/core": "^7.22.
|
|
39
|
+
"@ast-core/escape": "^1.0.1",
|
|
40
|
+
"@babel/core": "^7.22.19",
|
|
41
41
|
"@babel/helper-plugin-utils": "^7.22.5",
|
|
42
|
-
"@babel/preset-typescript": "^7.22.
|
|
43
|
-
"@babel/types": "^7.22.
|
|
44
|
-
"
|
|
42
|
+
"@babel/preset-typescript": "^7.22.15",
|
|
43
|
+
"@babel/types": "^7.22.19",
|
|
44
|
+
"fast-sort": "^3.4.0",
|
|
45
|
+
"magic-string": "^0.30.3",
|
|
46
|
+
"micromatch": "^4.0.5",
|
|
45
47
|
"parse5": "^7.1.2",
|
|
46
|
-
"postcss": "^8.4.
|
|
48
|
+
"postcss": "^8.4.29",
|
|
47
49
|
"postcss-selector-parser": "^6.0.13",
|
|
48
|
-
"@tailwindcss-mangle/
|
|
50
|
+
"@tailwindcss-mangle/config": "^2.2.1",
|
|
51
|
+
"@tailwindcss-mangle/shared": "^2.2.1"
|
|
49
52
|
},
|
|
50
53
|
"devDependencies": {
|
|
51
|
-
"@parse5/tools": "^0.
|
|
52
|
-
"@types/babel__core": "^7.20.1"
|
|
54
|
+
"@parse5/tools": "^0.3.0",
|
|
55
|
+
"@types/babel__core": "^7.20.1",
|
|
56
|
+
"@types/micromatch": "^4.0.2",
|
|
57
|
+
"@vue/compiler-core": "^3.3.4",
|
|
58
|
+
"@vue/compiler-sfc": "^3.3.4"
|
|
53
59
|
},
|
|
54
60
|
"homepage": "https://github.com/sonofmagic/tailwindcss-mangle",
|
|
55
61
|
"repository": {
|
|
56
62
|
"type": "git",
|
|
57
63
|
"url": "git+https://github.com/sonofmagic/tailwindcss-mangle.git"
|
|
58
64
|
},
|
|
65
|
+
"bugs": {
|
|
66
|
+
"url": "https://github.com/sonofmagic/tailwindcss-mangle/issues"
|
|
67
|
+
},
|
|
68
|
+
"directories": {
|
|
69
|
+
"test": "test"
|
|
70
|
+
},
|
|
59
71
|
"scripts": {
|
|
72
|
+
"dev": "unbuild --sourcemap",
|
|
60
73
|
"build": "unbuild",
|
|
61
74
|
"test": "vitest run --coverage.enabled",
|
|
62
75
|
"test:dev": "vitest",
|