@tailwindcss-mangle/core 2.1.0 → 2.2.0
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 +280 -149
- 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 +278 -152
- package/package.json +26 -10
package/dist/index.cjs
CHANGED
|
@@ -1,20 +1,30 @@
|
|
|
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');
|
|
10
15
|
const escape = require('@ast-core/escape');
|
|
16
|
+
const parser$1 = require('@babel/parser');
|
|
17
|
+
const traverse$1 = require('@babel/traverse');
|
|
11
18
|
|
|
12
19
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
13
20
|
|
|
21
|
+
const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
|
22
|
+
const micromatch__default = /*#__PURE__*/_interopDefaultCompat(micromatch);
|
|
14
23
|
const postcss__default = /*#__PURE__*/_interopDefaultCompat(postcss);
|
|
15
24
|
const parser__default = /*#__PURE__*/_interopDefaultCompat(parser);
|
|
16
25
|
const babel__default = /*#__PURE__*/_interopDefaultCompat(babel);
|
|
17
26
|
const MagicString__default = /*#__PURE__*/_interopDefaultCompat(MagicString);
|
|
27
|
+
const traverse__default = /*#__PURE__*/_interopDefaultCompat(traverse$1);
|
|
18
28
|
|
|
19
29
|
function isObject(value) {
|
|
20
30
|
return value !== null && typeof value === "object";
|
|
@@ -58,7 +68,126 @@ function createDefu(merger) {
|
|
|
58
68
|
}
|
|
59
69
|
const defu = createDefu();
|
|
60
70
|
|
|
71
|
+
const { isMatch } = micromatch__default;
|
|
72
|
+
function escapeStringRegexp(str) {
|
|
73
|
+
if (typeof str !== "string") {
|
|
74
|
+
throw new TypeError("Expected a string");
|
|
75
|
+
}
|
|
76
|
+
return str.replaceAll(/[$()*+.?[\\\]^{|}]/g, "\\$&").replaceAll("-", "\\x2d");
|
|
77
|
+
}
|
|
78
|
+
function createGlobMatcher(pattern, fallbackValue = false) {
|
|
79
|
+
if (pattern === void 0) {
|
|
80
|
+
return function() {
|
|
81
|
+
return fallbackValue;
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
return function(file) {
|
|
85
|
+
return isMatch(file, pattern);
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
var __defProp = Object.defineProperty;
|
|
90
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
91
|
+
var __publicField = (obj, key, value) => {
|
|
92
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
93
|
+
return value;
|
|
94
|
+
};
|
|
95
|
+
class Context {
|
|
96
|
+
constructor() {
|
|
97
|
+
__publicField(this, "options");
|
|
98
|
+
__publicField(this, "includeMatcher");
|
|
99
|
+
__publicField(this, "excludeMatcher");
|
|
100
|
+
__publicField(this, "replaceMap");
|
|
101
|
+
__publicField(this, "classSet");
|
|
102
|
+
__publicField(this, "classGenerator");
|
|
103
|
+
__publicField(this, "preserveFunctionSet");
|
|
104
|
+
__publicField(this, "preserveClassNamesSet");
|
|
105
|
+
__publicField(this, "preserveFunctionRegexs");
|
|
106
|
+
this.options = {};
|
|
107
|
+
this.classSet = /* @__PURE__ */ new Set();
|
|
108
|
+
this.replaceMap = /* @__PURE__ */ new Map();
|
|
109
|
+
this.includeMatcher = () => true;
|
|
110
|
+
this.excludeMatcher = () => false;
|
|
111
|
+
this.classGenerator = new shared.ClassGenerator();
|
|
112
|
+
this.preserveFunctionSet = /* @__PURE__ */ new Set();
|
|
113
|
+
this.preserveClassNamesSet = /* @__PURE__ */ new Set();
|
|
114
|
+
this.preserveFunctionRegexs = [];
|
|
115
|
+
}
|
|
116
|
+
isPreserveClass(className) {
|
|
117
|
+
return this.preserveClassNamesSet.has(className);
|
|
118
|
+
}
|
|
119
|
+
addPreserveClass(className) {
|
|
120
|
+
return this.preserveClassNamesSet.add(className);
|
|
121
|
+
}
|
|
122
|
+
isPreserveFunction(calleeName) {
|
|
123
|
+
return this.preserveFunctionSet.has(calleeName);
|
|
124
|
+
}
|
|
125
|
+
mergeOptions(...opts) {
|
|
126
|
+
this.options = defu(this.options, ...opts);
|
|
127
|
+
this.includeMatcher = createGlobMatcher(this.options.include, true);
|
|
128
|
+
this.excludeMatcher = createGlobMatcher(this.options.exclude, false);
|
|
129
|
+
this.classGenerator = new shared.ClassGenerator(this.options.classGenerator);
|
|
130
|
+
this.preserveFunctionSet = new Set(this.options?.preserveFunction ?? []);
|
|
131
|
+
this.preserveFunctionRegexs = [...this.preserveFunctionSet.values()].map((x) => {
|
|
132
|
+
return new RegExp(escapeStringRegexp(x) + "\\(([^)]*)\\)", "g");
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
isInclude(file) {
|
|
136
|
+
return this.includeMatcher(file) && !this.excludeMatcher(file);
|
|
137
|
+
}
|
|
138
|
+
currentMangleClassFilter(className) {
|
|
139
|
+
return (this.options.mangleClassFilter ?? shared.defaultMangleClassFilter)(className);
|
|
140
|
+
}
|
|
141
|
+
getClassSet() {
|
|
142
|
+
return this.classSet;
|
|
143
|
+
}
|
|
144
|
+
getReplaceMap() {
|
|
145
|
+
return this.replaceMap;
|
|
146
|
+
}
|
|
147
|
+
addToUsedBy(key, file) {
|
|
148
|
+
const hit = this.classGenerator.newClassMap[key];
|
|
149
|
+
if (hit) {
|
|
150
|
+
hit.usedBy.add(file);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
loadClassSet(classList) {
|
|
154
|
+
const list = fastSort.sort(classList).desc((c) => c.length);
|
|
155
|
+
for (const className of list) {
|
|
156
|
+
if (this.currentMangleClassFilter(className)) {
|
|
157
|
+
this.classSet.add(className);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
async initConfig(opts = {}) {
|
|
162
|
+
const { cwd, classList: _classList, mangleOptions } = opts;
|
|
163
|
+
const { config: config$1, cwd: configCwd } = await config.getConfig(cwd);
|
|
164
|
+
this.mergeOptions(mangleOptions, config$1?.mangle);
|
|
165
|
+
if (_classList) {
|
|
166
|
+
this.loadClassSet(_classList);
|
|
167
|
+
} else {
|
|
168
|
+
let jsonPath = this.options.classListPath ?? node_path.resolve(process.cwd(), config$1?.patch?.output?.filename);
|
|
169
|
+
if (!node_path.isAbsolute(jsonPath)) {
|
|
170
|
+
jsonPath = node_path.resolve(configCwd ?? process.cwd(), jsonPath);
|
|
171
|
+
}
|
|
172
|
+
if (jsonPath && fs__default.existsSync(jsonPath)) {
|
|
173
|
+
const rawClassList = fs__default.readFileSync(jsonPath, "utf8");
|
|
174
|
+
const list = JSON.parse(rawClassList);
|
|
175
|
+
this.loadClassSet(list);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
for (const cls of this.classSet) {
|
|
179
|
+
this.classGenerator.generateClassName(cls);
|
|
180
|
+
}
|
|
181
|
+
for (const x of Object.entries(this.classGenerator.newClassMap)) {
|
|
182
|
+
this.replaceMap.set(x[0], x[1].name);
|
|
183
|
+
}
|
|
184
|
+
return config$1;
|
|
185
|
+
}
|
|
186
|
+
// ["clsx\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"]
|
|
187
|
+
}
|
|
188
|
+
|
|
61
189
|
const postcssPlugin = "postcss-mangle-tailwindcss-plugin";
|
|
190
|
+
const clonedKey = "__tw_mangle_cloned__";
|
|
62
191
|
function isVueScoped(s) {
|
|
63
192
|
if (s.parent) {
|
|
64
193
|
const index = s.parent.nodes.indexOf(s);
|
|
@@ -72,12 +201,15 @@ function isVueScoped(s) {
|
|
|
72
201
|
return false;
|
|
73
202
|
}
|
|
74
203
|
const transformSelectorPostcssPlugin = function(options) {
|
|
75
|
-
const { ignoreVueScoped, replaceMap } = defu(options, {
|
|
204
|
+
const { ignoreVueScoped, replaceMap, ctx } = defu(options, {
|
|
76
205
|
ignoreVueScoped: true
|
|
77
206
|
});
|
|
78
207
|
return {
|
|
79
208
|
postcssPlugin,
|
|
80
209
|
async Rule(rule) {
|
|
210
|
+
if (rule[clonedKey]) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
81
213
|
await parser__default((selectors) => {
|
|
82
214
|
selectors.walkClasses((s) => {
|
|
83
215
|
if (s.value && replaceMap && replaceMap.has(s.value)) {
|
|
@@ -86,6 +218,10 @@ const transformSelectorPostcssPlugin = function(options) {
|
|
|
86
218
|
}
|
|
87
219
|
const v = replaceMap.get(s.value);
|
|
88
220
|
if (v) {
|
|
221
|
+
if (ctx.isPreserveClass(s.value)) {
|
|
222
|
+
const r = rule.cloneBefore();
|
|
223
|
+
r[clonedKey] = true;
|
|
224
|
+
}
|
|
89
225
|
s.value = v;
|
|
90
226
|
}
|
|
91
227
|
}
|
|
@@ -202,7 +338,7 @@ function traverse(node, visitor, parent) {
|
|
|
202
338
|
}
|
|
203
339
|
|
|
204
340
|
function htmlHandler(rawSource, options) {
|
|
205
|
-
const { replaceMap,
|
|
341
|
+
const { replaceMap, ctx } = options;
|
|
206
342
|
const fragment = parse5.parse(rawSource);
|
|
207
343
|
traverse(fragment, {
|
|
208
344
|
element(node) {
|
|
@@ -213,7 +349,7 @@ function htmlHandler(rawSource, options) {
|
|
|
213
349
|
});
|
|
214
350
|
for (const v of array) {
|
|
215
351
|
if (replaceMap.has(v)) {
|
|
216
|
-
attribute.value = attribute.value.replace(shared.makeRegex(v), classGenerator.generateClassName(v).name);
|
|
352
|
+
attribute.value = attribute.value.replace(shared.makeRegex(v), ctx.classGenerator.generateClassName(v).name);
|
|
217
353
|
}
|
|
218
354
|
}
|
|
219
355
|
}
|
|
@@ -224,136 +360,46 @@ function htmlHandler(rawSource, options) {
|
|
|
224
360
|
|
|
225
361
|
const isProd = () => process.env.NODE_ENV === "production";
|
|
226
362
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
|
|
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
|
-
});
|
|
363
|
+
function getStringLiteralCalleeName(path) {
|
|
364
|
+
if (path.parentPath.isCallExpression()) {
|
|
365
|
+
const callee = path.parentPath.get("callee");
|
|
366
|
+
if (callee.isIdentifier()) {
|
|
367
|
+
return callee.node.name;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
function getTemplateElementCalleeName(path) {
|
|
372
|
+
if (path.parentPath.isTemplateLiteral()) {
|
|
373
|
+
const pp = path.parentPath;
|
|
374
|
+
if (pp.parentPath.isCallExpression()) {
|
|
375
|
+
const callee = pp.parentPath.get("callee");
|
|
376
|
+
if (callee.isIdentifier()) {
|
|
377
|
+
return callee.node.name;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
343
382
|
|
|
344
383
|
function handleValue$1(options) {
|
|
345
|
-
const {
|
|
384
|
+
const { ctx, id, path, magicString, raw, replaceMap, offset = 0, escape: escape$1 = false, preserve = false } = options;
|
|
385
|
+
const node = path.node;
|
|
346
386
|
let value = raw;
|
|
347
|
-
const arr = sort(shared.splitCode(value)).desc((x) => x.length);
|
|
387
|
+
const arr = fastSort.sort(shared.splitCode(value)).desc((x) => x.length);
|
|
348
388
|
for (const str of arr) {
|
|
349
389
|
if (replaceMap.has(str)) {
|
|
350
|
-
addToUsedBy(str, id);
|
|
390
|
+
ctx.addToUsedBy(str, id);
|
|
391
|
+
if (preserve) {
|
|
392
|
+
ctx.addPreserveClass(str);
|
|
393
|
+
}
|
|
351
394
|
const v = replaceMap.get(str);
|
|
352
395
|
if (v) {
|
|
353
396
|
value = value.replaceAll(str, v);
|
|
354
397
|
}
|
|
355
398
|
}
|
|
356
399
|
}
|
|
400
|
+
if (preserve) {
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
357
403
|
if (typeof node.start === "number" && typeof node.end === "number" && value) {
|
|
358
404
|
const start = node.start + offset;
|
|
359
405
|
const end = node.end - offset;
|
|
@@ -362,48 +408,56 @@ function handleValue$1(options) {
|
|
|
362
408
|
}
|
|
363
409
|
}
|
|
364
410
|
}
|
|
365
|
-
const
|
|
411
|
+
const JsPlugin = helperPluginUtils.declare((api, options) => {
|
|
366
412
|
api.assertVersion(7);
|
|
367
|
-
const { magicString, replaceMap, id,
|
|
413
|
+
const { magicString, replaceMap, id, ctx } = options;
|
|
368
414
|
return {
|
|
369
415
|
visitor: {
|
|
370
416
|
StringLiteral: {
|
|
371
417
|
enter(p) {
|
|
372
|
-
const
|
|
373
|
-
|
|
374
|
-
addToUsedBy,
|
|
418
|
+
const opts = {
|
|
419
|
+
ctx,
|
|
375
420
|
id,
|
|
376
421
|
magicString,
|
|
377
|
-
|
|
378
|
-
raw: node.value,
|
|
422
|
+
path: p,
|
|
423
|
+
raw: p.node.value,
|
|
379
424
|
replaceMap,
|
|
380
425
|
offset: 1,
|
|
381
|
-
escape: true
|
|
382
|
-
|
|
426
|
+
escape: true,
|
|
427
|
+
preserve: false
|
|
428
|
+
};
|
|
429
|
+
const calleeName = getStringLiteralCalleeName(p);
|
|
430
|
+
if (calleeName && ctx.isPreserveFunction(calleeName)) {
|
|
431
|
+
opts.preserve = true;
|
|
432
|
+
}
|
|
433
|
+
handleValue$1(opts);
|
|
383
434
|
}
|
|
384
435
|
},
|
|
385
436
|
TemplateElement: {
|
|
386
437
|
enter(p) {
|
|
387
|
-
const
|
|
388
|
-
|
|
389
|
-
addToUsedBy,
|
|
438
|
+
const opts = {
|
|
439
|
+
ctx,
|
|
390
440
|
id,
|
|
391
441
|
magicString,
|
|
392
|
-
|
|
393
|
-
raw: node.value.raw,
|
|
442
|
+
path: p,
|
|
443
|
+
raw: p.node.value.raw,
|
|
394
444
|
replaceMap,
|
|
395
445
|
offset: 0,
|
|
396
|
-
escape: false
|
|
397
|
-
|
|
446
|
+
escape: false,
|
|
447
|
+
preserve: false
|
|
448
|
+
};
|
|
449
|
+
const calleeName = getTemplateElementCalleeName(p);
|
|
450
|
+
if (calleeName && ctx.isPreserveFunction(calleeName)) {
|
|
451
|
+
opts.preserve = true;
|
|
452
|
+
}
|
|
453
|
+
handleValue$1(opts);
|
|
398
454
|
}
|
|
399
455
|
}
|
|
400
456
|
}
|
|
401
457
|
};
|
|
402
458
|
});
|
|
403
|
-
function
|
|
404
|
-
|
|
405
|
-
const magicString = typeof code === "string" ? new MagicString__default(code) : code;
|
|
406
|
-
babel__default.transformSync(magicString.original, {
|
|
459
|
+
function transformSync(code, plugins, filename) {
|
|
460
|
+
babel__default.transformSync(code, {
|
|
407
461
|
presets: [
|
|
408
462
|
// ['@babel/preset-react', {}],
|
|
409
463
|
[
|
|
@@ -414,24 +468,99 @@ function preProcessJs(options) {
|
|
|
414
468
|
}
|
|
415
469
|
]
|
|
416
470
|
],
|
|
417
|
-
plugins
|
|
471
|
+
plugins,
|
|
472
|
+
filename
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
function preProcessJs(options) {
|
|
476
|
+
const { code, replaceMap, id, ctx } = options;
|
|
477
|
+
const magicString = typeof code === "string" ? new MagicString__default(code) : code;
|
|
478
|
+
transformSync(
|
|
479
|
+
magicString.original,
|
|
480
|
+
[
|
|
418
481
|
[
|
|
419
|
-
|
|
482
|
+
JsPlugin,
|
|
420
483
|
{
|
|
421
484
|
magicString,
|
|
422
485
|
replaceMap,
|
|
423
486
|
id,
|
|
424
|
-
|
|
487
|
+
ctx
|
|
425
488
|
}
|
|
426
489
|
]
|
|
427
490
|
],
|
|
428
|
-
|
|
429
|
-
|
|
491
|
+
id
|
|
492
|
+
);
|
|
493
|
+
return magicString.toString();
|
|
494
|
+
}
|
|
495
|
+
function preProcessRawCode(options) {
|
|
496
|
+
const { code, replaceMap, ctx } = options;
|
|
497
|
+
const magicString = typeof code === "string" ? new MagicString__default(code) : code;
|
|
498
|
+
const markArr = [];
|
|
499
|
+
for (const regex of ctx.preserveFunctionRegexs) {
|
|
500
|
+
const allArr = [];
|
|
501
|
+
let arr = null;
|
|
502
|
+
while ((arr = regex.exec(magicString.original)) !== null) {
|
|
503
|
+
allArr.push(arr);
|
|
504
|
+
markArr.push([arr.index, arr.index + arr[0].length]);
|
|
505
|
+
}
|
|
506
|
+
for (const regExpMatch of allArr) {
|
|
507
|
+
let ast;
|
|
508
|
+
try {
|
|
509
|
+
ast = parser$1.parse(regExpMatch[0], {
|
|
510
|
+
sourceType: "unambiguous"
|
|
511
|
+
});
|
|
512
|
+
traverse__default(ast, {
|
|
513
|
+
StringLiteral: {
|
|
514
|
+
enter(p) {
|
|
515
|
+
const arr2 = fastSort.sort(shared.splitCode(p.node.value)).desc((x) => x.length);
|
|
516
|
+
for (const v of arr2) {
|
|
517
|
+
if (replaceMap.has(v)) {
|
|
518
|
+
ctx.addPreserveClass(v);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
},
|
|
523
|
+
TemplateElement: {
|
|
524
|
+
enter(p) {
|
|
525
|
+
const arr2 = fastSort.sort(shared.splitCode(p.node.value.raw)).desc((x) => x.length);
|
|
526
|
+
for (const v of arr2) {
|
|
527
|
+
if (replaceMap.has(v)) {
|
|
528
|
+
ctx.addPreserveClass(v);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
});
|
|
534
|
+
} catch {
|
|
535
|
+
continue;
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
for (const [key, value] of replaceMap) {
|
|
540
|
+
const regex = new RegExp(escapeStringRegexp(key), "g");
|
|
541
|
+
let arr = null;
|
|
542
|
+
while ((arr = regex.exec(magicString.original)) !== null) {
|
|
543
|
+
const start = arr.index;
|
|
544
|
+
const end = arr.index + arr[0].length;
|
|
545
|
+
let shouldUpdate = true;
|
|
546
|
+
for (const [ps, pe] of markArr) {
|
|
547
|
+
if (start > ps && start < pe || end < pe && end > ps) {
|
|
548
|
+
shouldUpdate = false;
|
|
549
|
+
break;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
if (shouldUpdate) {
|
|
553
|
+
magicString.update(start, end, value);
|
|
554
|
+
markArr.push([start, end]);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
}
|
|
430
558
|
return magicString.toString();
|
|
431
559
|
}
|
|
432
560
|
|
|
433
561
|
function handleValue(raw, node, options) {
|
|
434
|
-
const { replaceMap,
|
|
562
|
+
const { replaceMap, ctx, splitQuote = true } = options;
|
|
563
|
+
const clsGen = ctx.classGenerator;
|
|
435
564
|
const array = shared.splitCode(raw, {
|
|
436
565
|
splitQuote
|
|
437
566
|
});
|
|
@@ -499,8 +628,10 @@ function jsHandler(rawSource, options) {
|
|
|
499
628
|
}
|
|
500
629
|
|
|
501
630
|
exports.ClassGenerator = shared.ClassGenerator;
|
|
631
|
+
exports.Context = Context;
|
|
502
632
|
exports.cssHandler = cssHandler;
|
|
503
633
|
exports.handleValue = handleValue;
|
|
504
634
|
exports.htmlHandler = htmlHandler;
|
|
505
635
|
exports.jsHandler = jsHandler;
|
|
506
636
|
exports.preProcessJs = preProcessJs;
|
|
637
|
+
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 };
|