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