@tailwindcss-mangle/core 1.2.7 → 2.0.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 +253 -80
- package/dist/index.d.ts +15 -6
- package/dist/index.mjs +259 -67
- package/package.json +6 -3
package/dist/index.cjs
CHANGED
|
@@ -4,26 +4,16 @@ const postcss = require('postcss');
|
|
|
4
4
|
const parser = require('postcss-selector-parser');
|
|
5
5
|
const parse5 = require('parse5');
|
|
6
6
|
const shared = require('@tailwindcss-mangle/shared');
|
|
7
|
-
const
|
|
8
|
-
const
|
|
7
|
+
const babel = require('@babel/core');
|
|
8
|
+
const helperPluginUtils = require('@babel/helper-plugin-utils');
|
|
9
|
+
const MagicString = require('magic-string');
|
|
9
10
|
|
|
10
11
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
11
12
|
|
|
12
|
-
function _interopNamespaceCompat(e) {
|
|
13
|
-
if (e && typeof e === 'object' && 'default' in e) return e;
|
|
14
|
-
const n = Object.create(null);
|
|
15
|
-
if (e) {
|
|
16
|
-
for (const k in e) {
|
|
17
|
-
n[k] = e[k];
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
n.default = e;
|
|
21
|
-
return n;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
13
|
const postcss__default = /*#__PURE__*/_interopDefaultCompat(postcss);
|
|
25
14
|
const parser__default = /*#__PURE__*/_interopDefaultCompat(parser);
|
|
26
|
-
const
|
|
15
|
+
const babel__default = /*#__PURE__*/_interopDefaultCompat(babel);
|
|
16
|
+
const MagicString__default = /*#__PURE__*/_interopDefaultCompat(MagicString);
|
|
27
17
|
|
|
28
18
|
function isObject(value) {
|
|
29
19
|
return value !== null && typeof value === "object";
|
|
@@ -80,64 +70,41 @@ function isVueScoped(s) {
|
|
|
80
70
|
}
|
|
81
71
|
return false;
|
|
82
72
|
}
|
|
83
|
-
const
|
|
84
|
-
const { ignoreVueScoped } = defu(options, {
|
|
73
|
+
const transformSelectorPostcssPlugin = function(options) {
|
|
74
|
+
const { ignoreVueScoped, replaceMap } = defu(options, {
|
|
85
75
|
ignoreVueScoped: true
|
|
86
76
|
});
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
rule.selector = parser__default((selectors) => {
|
|
96
|
-
selectors.walkClasses((s) => {
|
|
97
|
-
if (s.value) {
|
|
98
|
-
const existed = set.has(s.value);
|
|
99
|
-
if (existed) {
|
|
100
|
-
if (ignoreVueScoped && isVueScoped(s)) {
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
s.value = options.classGenerator.generateClassName(s.value).name;
|
|
104
|
-
}
|
|
77
|
+
return {
|
|
78
|
+
postcssPlugin,
|
|
79
|
+
async Rule(rule) {
|
|
80
|
+
await parser__default((selectors) => {
|
|
81
|
+
selectors.walkClasses((s) => {
|
|
82
|
+
if (s.value && replaceMap && replaceMap.has(s.value)) {
|
|
83
|
+
if (ignoreVueScoped && isVueScoped(s)) {
|
|
84
|
+
return;
|
|
105
85
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
};
|
|
110
|
-
} else {
|
|
111
|
-
let newClassMap = {};
|
|
112
|
-
if (options && options.classGenerator) {
|
|
113
|
-
newClassMap = options.classGenerator.newClassMap;
|
|
114
|
-
}
|
|
115
|
-
return {
|
|
116
|
-
postcssPlugin,
|
|
117
|
-
Rule(rule) {
|
|
118
|
-
rule.selector = parser__default((selectors) => {
|
|
119
|
-
selectors.walkClasses((s) => {
|
|
120
|
-
if (s.value) {
|
|
121
|
-
const hit = newClassMap[s.value];
|
|
122
|
-
const existed = Boolean(hit);
|
|
123
|
-
if (existed) {
|
|
124
|
-
if (ignoreVueScoped && isVueScoped(s)) {
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
s.value = hit.name;
|
|
128
|
-
}
|
|
86
|
+
const v = replaceMap.get(s.value);
|
|
87
|
+
if (v) {
|
|
88
|
+
s.value = v;
|
|
129
89
|
}
|
|
130
|
-
}
|
|
131
|
-
})
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}).transform(rule, {
|
|
93
|
+
lossless: false,
|
|
94
|
+
updateSelector: true
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
};
|
|
135
98
|
};
|
|
136
|
-
|
|
99
|
+
transformSelectorPostcssPlugin.postcss = true;
|
|
137
100
|
|
|
138
101
|
function cssHandler(rawSource, options) {
|
|
139
|
-
const acceptedPlugins = [
|
|
140
|
-
|
|
102
|
+
const acceptedPlugins = [transformSelectorPostcssPlugin(options)];
|
|
103
|
+
const { file } = options;
|
|
104
|
+
return postcss__default(acceptedPlugins).process(rawSource, {
|
|
105
|
+
from: file,
|
|
106
|
+
to: file
|
|
107
|
+
});
|
|
141
108
|
}
|
|
142
109
|
|
|
143
110
|
({
|
|
@@ -234,7 +201,7 @@ function traverse(node, visitor, parent) {
|
|
|
234
201
|
}
|
|
235
202
|
|
|
236
203
|
function htmlHandler(rawSource, options) {
|
|
237
|
-
const {
|
|
204
|
+
const { replaceMap, classGenerator } = options;
|
|
238
205
|
const fragment = parse5.parse(rawSource);
|
|
239
206
|
traverse(fragment, {
|
|
240
207
|
element(node) {
|
|
@@ -244,7 +211,7 @@ function htmlHandler(rawSource, options) {
|
|
|
244
211
|
splitQuote: false
|
|
245
212
|
});
|
|
246
213
|
for (const v of array) {
|
|
247
|
-
if (
|
|
214
|
+
if (replaceMap.has(v)) {
|
|
248
215
|
attribute.value = attribute.value.replace(shared.makeRegex(v), classGenerator.generateClassName(v).name);
|
|
249
216
|
}
|
|
250
217
|
}
|
|
@@ -256,14 +223,213 @@ function htmlHandler(rawSource, options) {
|
|
|
256
223
|
|
|
257
224
|
const isProd = () => process.env.NODE_ENV === "production";
|
|
258
225
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
226
|
+
// >>> INTERFACES <<<
|
|
227
|
+
// >>> HELPERS <<<
|
|
228
|
+
var castComparer = function (comparer) { return function (a, b, order) { return comparer(a, b, order) * order; }; };
|
|
229
|
+
var throwInvalidConfigErrorIfTrue = function (condition, context) {
|
|
230
|
+
if (condition)
|
|
231
|
+
throw Error("Invalid sort config: " + context);
|
|
232
|
+
};
|
|
233
|
+
var unpackObjectSorter = function (sortByObj) {
|
|
234
|
+
var _a = sortByObj || {}, asc = _a.asc, desc = _a.desc;
|
|
235
|
+
var order = asc ? 1 : -1;
|
|
236
|
+
var sortBy = (asc || desc);
|
|
237
|
+
// Validate object config
|
|
238
|
+
throwInvalidConfigErrorIfTrue(!sortBy, 'Expected `asc` or `desc` property');
|
|
239
|
+
throwInvalidConfigErrorIfTrue(asc && desc, 'Ambiguous object with `asc` and `desc` config properties');
|
|
240
|
+
var comparer = sortByObj.comparer && castComparer(sortByObj.comparer);
|
|
241
|
+
return { order: order, sortBy: sortBy, comparer: comparer };
|
|
242
|
+
};
|
|
243
|
+
// >>> SORTERS <<<
|
|
244
|
+
var multiPropertySorterProvider = function (defaultComparer) {
|
|
245
|
+
return function multiPropertySorter(sortBy, sortByArr, depth, order, comparer, a, b) {
|
|
246
|
+
var valA;
|
|
247
|
+
var valB;
|
|
248
|
+
if (typeof sortBy === 'string') {
|
|
249
|
+
valA = a[sortBy];
|
|
250
|
+
valB = b[sortBy];
|
|
251
|
+
}
|
|
252
|
+
else if (typeof sortBy === 'function') {
|
|
253
|
+
valA = sortBy(a);
|
|
254
|
+
valB = sortBy(b);
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
var objectSorterConfig = unpackObjectSorter(sortBy);
|
|
258
|
+
return multiPropertySorter(objectSorterConfig.sortBy, sortByArr, depth, objectSorterConfig.order, objectSorterConfig.comparer || defaultComparer, a, b);
|
|
259
|
+
}
|
|
260
|
+
var equality = comparer(valA, valB, order);
|
|
261
|
+
if ((equality === 0 || (valA == null && valB == null)) &&
|
|
262
|
+
sortByArr.length > depth) {
|
|
263
|
+
return multiPropertySorter(sortByArr[depth], sortByArr, depth + 1, order, comparer, a, b);
|
|
264
|
+
}
|
|
265
|
+
return equality;
|
|
266
|
+
};
|
|
267
|
+
};
|
|
268
|
+
function getSortStrategy(sortBy, comparer, order) {
|
|
269
|
+
// Flat array sorter
|
|
270
|
+
if (sortBy === undefined || sortBy === true) {
|
|
271
|
+
return function (a, b) { return comparer(a, b, order); };
|
|
272
|
+
}
|
|
273
|
+
// Sort list of objects by single object key
|
|
274
|
+
if (typeof sortBy === 'string') {
|
|
275
|
+
throwInvalidConfigErrorIfTrue(sortBy.includes('.'), 'String syntax not allowed for nested properties.');
|
|
276
|
+
return function (a, b) { return comparer(a[sortBy], b[sortBy], order); };
|
|
277
|
+
}
|
|
278
|
+
// Sort list of objects by single function sorter
|
|
279
|
+
if (typeof sortBy === 'function') {
|
|
280
|
+
return function (a, b) { return comparer(sortBy(a), sortBy(b), order); };
|
|
281
|
+
}
|
|
282
|
+
// Sort by multiple properties
|
|
283
|
+
if (Array.isArray(sortBy)) {
|
|
284
|
+
var multiPropSorter_1 = multiPropertySorterProvider(comparer);
|
|
285
|
+
return function (a, b) { return multiPropSorter_1(sortBy[0], sortBy, 1, order, comparer, a, b); };
|
|
286
|
+
}
|
|
287
|
+
// Unpack object config to get actual sorter strategy
|
|
288
|
+
var objectSorterConfig = unpackObjectSorter(sortBy);
|
|
289
|
+
return getSortStrategy(objectSorterConfig.sortBy, objectSorterConfig.comparer || comparer, objectSorterConfig.order);
|
|
290
|
+
}
|
|
291
|
+
var sortArray = function (order, ctx, sortBy, comparer) {
|
|
292
|
+
var _a;
|
|
293
|
+
if (!Array.isArray(ctx)) {
|
|
294
|
+
return ctx;
|
|
295
|
+
}
|
|
296
|
+
// Unwrap sortBy if array with only 1 value to get faster sort strategy
|
|
297
|
+
if (Array.isArray(sortBy) && sortBy.length < 2) {
|
|
298
|
+
_a = sortBy, sortBy = _a[0];
|
|
299
|
+
}
|
|
300
|
+
return ctx.sort(getSortStrategy(sortBy, comparer, order));
|
|
301
|
+
};
|
|
302
|
+
function createNewSortInstance(opts) {
|
|
303
|
+
var comparer = castComparer(opts.comparer);
|
|
304
|
+
return function (arrayToSort) {
|
|
305
|
+
var ctx = Array.isArray(arrayToSort) && !opts.inPlaceSorting
|
|
306
|
+
? arrayToSort.slice()
|
|
307
|
+
: arrayToSort;
|
|
308
|
+
return {
|
|
309
|
+
asc: function (sortBy) {
|
|
310
|
+
return sortArray(1, ctx, sortBy, comparer);
|
|
311
|
+
},
|
|
312
|
+
desc: function (sortBy) {
|
|
313
|
+
return sortArray(-1, ctx, sortBy, comparer);
|
|
314
|
+
},
|
|
315
|
+
by: function (sortBy) {
|
|
316
|
+
return sortArray(1, ctx, sortBy, comparer);
|
|
317
|
+
},
|
|
318
|
+
};
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
var defaultComparer = function (a, b, order) {
|
|
322
|
+
if (a == null)
|
|
323
|
+
return order;
|
|
324
|
+
if (b == null)
|
|
325
|
+
return -order;
|
|
326
|
+
if (typeof a !== typeof b) {
|
|
327
|
+
return typeof a < typeof b ? -1 : 1;
|
|
328
|
+
}
|
|
329
|
+
if (a < b)
|
|
330
|
+
return -1;
|
|
331
|
+
if (a > b)
|
|
332
|
+
return 1;
|
|
333
|
+
return 0;
|
|
334
|
+
};
|
|
335
|
+
var sort = createNewSortInstance({
|
|
336
|
+
comparer: defaultComparer,
|
|
337
|
+
});
|
|
338
|
+
createNewSortInstance({
|
|
339
|
+
comparer: defaultComparer,
|
|
340
|
+
inPlaceSorting: true,
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
function handleValue$1(options) {
|
|
344
|
+
const { addToUsedBy, id, magicString, node, raw, replaceMap, offset = 0 } = options;
|
|
345
|
+
let value = raw;
|
|
346
|
+
const arr = sort(shared.splitCode(value)).desc((x) => x.length);
|
|
347
|
+
for (const str of arr) {
|
|
348
|
+
if (replaceMap.has(str)) {
|
|
349
|
+
addToUsedBy(str, id);
|
|
350
|
+
const v = replaceMap.get(str);
|
|
351
|
+
if (v) {
|
|
352
|
+
value = value.replaceAll(str, v);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
if (typeof node.start === "number" && typeof node.end === "number" && value) {
|
|
357
|
+
magicString.update(node.start + offset, node.end - offset, value);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
const plugin = helperPluginUtils.declare((api, options) => {
|
|
361
|
+
api.assertVersion(7);
|
|
362
|
+
const { magicString, replaceMap, id, addToUsedBy } = options;
|
|
363
|
+
return {
|
|
364
|
+
visitor: {
|
|
365
|
+
StringLiteral: {
|
|
366
|
+
enter(p) {
|
|
367
|
+
const node = p.node;
|
|
368
|
+
handleValue$1({
|
|
369
|
+
addToUsedBy,
|
|
370
|
+
id,
|
|
371
|
+
magicString,
|
|
372
|
+
node,
|
|
373
|
+
raw: node.value,
|
|
374
|
+
replaceMap,
|
|
375
|
+
offset: 1
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
},
|
|
379
|
+
TemplateElement: {
|
|
380
|
+
enter(p) {
|
|
381
|
+
const node = p.node;
|
|
382
|
+
handleValue$1({
|
|
383
|
+
addToUsedBy,
|
|
384
|
+
id,
|
|
385
|
+
magicString,
|
|
386
|
+
node,
|
|
387
|
+
raw: node.value.raw,
|
|
388
|
+
replaceMap,
|
|
389
|
+
offset: 0
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
};
|
|
395
|
+
});
|
|
396
|
+
function preProcessJs(options) {
|
|
397
|
+
const { code, replaceMap, id, addToUsedBy } = options;
|
|
398
|
+
const magicString = new MagicString__default(code);
|
|
399
|
+
babel__default.transformSync(code, {
|
|
400
|
+
presets: [
|
|
401
|
+
// ['@babel/preset-react', {}],
|
|
402
|
+
[
|
|
403
|
+
require("@babel/preset-typescript"),
|
|
404
|
+
{
|
|
405
|
+
allExtensions: true,
|
|
406
|
+
isTSX: true
|
|
407
|
+
}
|
|
408
|
+
]
|
|
409
|
+
],
|
|
410
|
+
plugins: [
|
|
411
|
+
[
|
|
412
|
+
plugin,
|
|
413
|
+
{
|
|
414
|
+
magicString,
|
|
415
|
+
replaceMap,
|
|
416
|
+
id,
|
|
417
|
+
addToUsedBy
|
|
418
|
+
}
|
|
419
|
+
]
|
|
420
|
+
]
|
|
421
|
+
});
|
|
422
|
+
return magicString.toString();
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
function handleValue(raw, node, options) {
|
|
426
|
+
const { replaceMap, classGenerator: clsGen, splitQuote = true } = options;
|
|
427
|
+
const array = shared.splitCode(raw, {
|
|
262
428
|
splitQuote
|
|
263
429
|
});
|
|
264
|
-
let rawString =
|
|
430
|
+
let rawString = raw;
|
|
265
431
|
for (const v of array) {
|
|
266
|
-
if (
|
|
432
|
+
if (replaceMap.has(v)) {
|
|
267
433
|
let ignoreFlag = false;
|
|
268
434
|
if (Array.isArray(node.leadingComments)) {
|
|
269
435
|
ignoreFlag = node.leadingComments.findIndex((x) => x.value.includes("tw-mangle") && x.value.includes("ignore")) > -1;
|
|
@@ -276,7 +442,7 @@ function handleValue(string_, node, options) {
|
|
|
276
442
|
return rawString;
|
|
277
443
|
}
|
|
278
444
|
function jsHandler(rawSource, options) {
|
|
279
|
-
const result =
|
|
445
|
+
const result = babel.transformSync(rawSource, {
|
|
280
446
|
babelrc: false,
|
|
281
447
|
ast: true,
|
|
282
448
|
plugins: [
|
|
@@ -297,12 +463,18 @@ function jsHandler(rawSource, options) {
|
|
|
297
463
|
},
|
|
298
464
|
CallExpression: {
|
|
299
465
|
enter(p) {
|
|
300
|
-
const
|
|
301
|
-
if (
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
466
|
+
const calleePath = p.get("callee");
|
|
467
|
+
if (calleePath.isIdentifier() && calleePath.node.name === "eval") {
|
|
468
|
+
p.traverse({
|
|
469
|
+
StringLiteral: {
|
|
470
|
+
enter(s) {
|
|
471
|
+
const res = jsHandler(s.node.value, options);
|
|
472
|
+
if (res.code) {
|
|
473
|
+
s.node.value = res.code;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
});
|
|
306
478
|
}
|
|
307
479
|
}
|
|
308
480
|
}
|
|
@@ -323,3 +495,4 @@ exports.cssHandler = cssHandler;
|
|
|
323
495
|
exports.handleValue = handleValue;
|
|
324
496
|
exports.htmlHandler = htmlHandler;
|
|
325
497
|
exports.jsHandler = jsHandler;
|
|
498
|
+
exports.preProcessJs = preProcessJs;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as postcss_lib_no_work_result from 'postcss/lib/no-work-result';
|
|
2
|
+
import postcss from 'postcss';
|
|
1
3
|
import { ClassGenerator } from '@tailwindcss-mangle/shared';
|
|
2
4
|
export { ClassGenerator } from '@tailwindcss-mangle/shared';
|
|
3
5
|
import { StringLiteral, TemplateElement } from '@babel/types';
|
|
@@ -5,7 +7,7 @@ import { BabelFileResult } from '@babel/core';
|
|
|
5
7
|
|
|
6
8
|
interface IClassGeneratorContextItem {
|
|
7
9
|
name: string;
|
|
8
|
-
usedBy:
|
|
10
|
+
usedBy: string[];
|
|
9
11
|
}
|
|
10
12
|
interface IClassGeneratorOptions {
|
|
11
13
|
reserveClassName?: (string | RegExp)[];
|
|
@@ -17,8 +19,8 @@ interface IClassGeneratorOptions {
|
|
|
17
19
|
classPrefix?: string;
|
|
18
20
|
}
|
|
19
21
|
interface IHandlerOptions {
|
|
20
|
-
runtimeSet: Set<string>;
|
|
21
22
|
classGenerator: ClassGenerator;
|
|
23
|
+
replaceMap: Map<string, string>;
|
|
22
24
|
}
|
|
23
25
|
interface IHtmlHandlerOptions extends IHandlerOptions {
|
|
24
26
|
}
|
|
@@ -27,8 +29,8 @@ interface IJsHandlerOptions extends IHandlerOptions {
|
|
|
27
29
|
minified?: boolean;
|
|
28
30
|
}
|
|
29
31
|
interface ICssHandlerOptions extends IHandlerOptions {
|
|
30
|
-
scene?: 'loader' | 'process';
|
|
31
32
|
ignoreVueScoped?: boolean;
|
|
33
|
+
file?: string;
|
|
32
34
|
}
|
|
33
35
|
interface ClassSetOutputOptions {
|
|
34
36
|
filename: string;
|
|
@@ -47,11 +49,18 @@ interface Options {
|
|
|
47
49
|
classMapOutput?: boolean | ClassMapOutputOptions;
|
|
48
50
|
}
|
|
49
51
|
|
|
50
|
-
declare function cssHandler(rawSource: string, options: ICssHandlerOptions):
|
|
52
|
+
declare function cssHandler(rawSource: string, options: ICssHandlerOptions): postcss.LazyResult | postcss_lib_no_work_result.default;
|
|
51
53
|
|
|
52
54
|
declare function htmlHandler(rawSource: string, options: IHtmlHandlerOptions): string;
|
|
53
55
|
|
|
54
|
-
declare function
|
|
56
|
+
declare function preProcessJs(options: {
|
|
57
|
+
code: string;
|
|
58
|
+
replaceMap: Map<string, string>;
|
|
59
|
+
id: string;
|
|
60
|
+
addToUsedBy: (key: string, file: string) => void;
|
|
61
|
+
}): string;
|
|
62
|
+
|
|
63
|
+
declare function handleValue(raw: string, node: StringLiteral | TemplateElement, options: IJsHandlerOptions): string;
|
|
55
64
|
declare function jsHandler(rawSource: string, options: IJsHandlerOptions): BabelFileResult;
|
|
56
65
|
|
|
57
|
-
export { ClassMapOutputOptions, ClassSetOutputOptions, IClassGeneratorContextItem, IClassGeneratorOptions, ICssHandlerOptions, IHandlerOptions, IHtmlHandlerOptions, IJsHandlerOptions, Options, cssHandler, handleValue, htmlHandler, jsHandler };
|
|
66
|
+
export { ClassMapOutputOptions, ClassSetOutputOptions, IClassGeneratorContextItem, IClassGeneratorOptions, ICssHandlerOptions, IHandlerOptions, IHtmlHandlerOptions, IJsHandlerOptions, Options, cssHandler, handleValue, htmlHandler, jsHandler, preProcessJs };
|
package/dist/index.mjs
CHANGED
|
@@ -3,9 +3,19 @@ import parser from 'postcss-selector-parser';
|
|
|
3
3
|
import { html, defaultTreeAdapter, parse, serialize } from 'parse5';
|
|
4
4
|
import { splitCode, makeRegex } from '@tailwindcss-mangle/shared';
|
|
5
5
|
export { ClassGenerator } from '@tailwindcss-mangle/shared';
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
6
|
+
import babel, { transformSync } from '@babel/core';
|
|
7
|
+
import { declare } from '@babel/helper-plugin-utils';
|
|
8
|
+
import MagicString from 'magic-string';
|
|
8
9
|
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
// -- Unbuild CommonJS Shims --
|
|
13
|
+
import __cjs_url__ from 'url';
|
|
14
|
+
import __cjs_path__ from 'path';
|
|
15
|
+
import __cjs_mod__ from 'module';
|
|
16
|
+
const __filename = __cjs_url__.fileURLToPath(import.meta.url);
|
|
17
|
+
const __dirname = __cjs_path__.dirname(__filename);
|
|
18
|
+
const require = __cjs_mod__.createRequire(import.meta.url);
|
|
9
19
|
function isObject(value) {
|
|
10
20
|
return value !== null && typeof value === "object";
|
|
11
21
|
}
|
|
@@ -61,64 +71,41 @@ function isVueScoped(s) {
|
|
|
61
71
|
}
|
|
62
72
|
return false;
|
|
63
73
|
}
|
|
64
|
-
const
|
|
65
|
-
const { ignoreVueScoped } = defu(options, {
|
|
74
|
+
const transformSelectorPostcssPlugin = function(options) {
|
|
75
|
+
const { ignoreVueScoped, replaceMap } = defu(options, {
|
|
66
76
|
ignoreVueScoped: true
|
|
67
77
|
});
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
rule.selector = parser((selectors) => {
|
|
77
|
-
selectors.walkClasses((s) => {
|
|
78
|
-
if (s.value) {
|
|
79
|
-
const existed = set.has(s.value);
|
|
80
|
-
if (existed) {
|
|
81
|
-
if (ignoreVueScoped && isVueScoped(s)) {
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
s.value = options.classGenerator.generateClassName(s.value).name;
|
|
85
|
-
}
|
|
78
|
+
return {
|
|
79
|
+
postcssPlugin,
|
|
80
|
+
async Rule(rule) {
|
|
81
|
+
await parser((selectors) => {
|
|
82
|
+
selectors.walkClasses((s) => {
|
|
83
|
+
if (s.value && replaceMap && replaceMap.has(s.value)) {
|
|
84
|
+
if (ignoreVueScoped && isVueScoped(s)) {
|
|
85
|
+
return;
|
|
86
86
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
};
|
|
91
|
-
} else {
|
|
92
|
-
let newClassMap = {};
|
|
93
|
-
if (options && options.classGenerator) {
|
|
94
|
-
newClassMap = options.classGenerator.newClassMap;
|
|
95
|
-
}
|
|
96
|
-
return {
|
|
97
|
-
postcssPlugin,
|
|
98
|
-
Rule(rule) {
|
|
99
|
-
rule.selector = parser((selectors) => {
|
|
100
|
-
selectors.walkClasses((s) => {
|
|
101
|
-
if (s.value) {
|
|
102
|
-
const hit = newClassMap[s.value];
|
|
103
|
-
const existed = Boolean(hit);
|
|
104
|
-
if (existed) {
|
|
105
|
-
if (ignoreVueScoped && isVueScoped(s)) {
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
s.value = hit.name;
|
|
109
|
-
}
|
|
87
|
+
const v = replaceMap.get(s.value);
|
|
88
|
+
if (v) {
|
|
89
|
+
s.value = v;
|
|
110
90
|
}
|
|
111
|
-
}
|
|
112
|
-
})
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}).transform(rule, {
|
|
94
|
+
lossless: false,
|
|
95
|
+
updateSelector: true
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
};
|
|
116
99
|
};
|
|
117
|
-
|
|
100
|
+
transformSelectorPostcssPlugin.postcss = true;
|
|
118
101
|
|
|
119
102
|
function cssHandler(rawSource, options) {
|
|
120
|
-
const acceptedPlugins = [
|
|
121
|
-
|
|
103
|
+
const acceptedPlugins = [transformSelectorPostcssPlugin(options)];
|
|
104
|
+
const { file } = options;
|
|
105
|
+
return postcss(acceptedPlugins).process(rawSource, {
|
|
106
|
+
from: file,
|
|
107
|
+
to: file
|
|
108
|
+
});
|
|
122
109
|
}
|
|
123
110
|
|
|
124
111
|
({
|
|
@@ -215,7 +202,7 @@ function traverse(node, visitor, parent) {
|
|
|
215
202
|
}
|
|
216
203
|
|
|
217
204
|
function htmlHandler(rawSource, options) {
|
|
218
|
-
const {
|
|
205
|
+
const { replaceMap, classGenerator } = options;
|
|
219
206
|
const fragment = parse(rawSource);
|
|
220
207
|
traverse(fragment, {
|
|
221
208
|
element(node) {
|
|
@@ -225,7 +212,7 @@ function htmlHandler(rawSource, options) {
|
|
|
225
212
|
splitQuote: false
|
|
226
213
|
});
|
|
227
214
|
for (const v of array) {
|
|
228
|
-
if (
|
|
215
|
+
if (replaceMap.has(v)) {
|
|
229
216
|
attribute.value = attribute.value.replace(makeRegex(v), classGenerator.generateClassName(v).name);
|
|
230
217
|
}
|
|
231
218
|
}
|
|
@@ -237,14 +224,213 @@ function htmlHandler(rawSource, options) {
|
|
|
237
224
|
|
|
238
225
|
const isProd = () => process.env.NODE_ENV === "production";
|
|
239
226
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
227
|
+
// >>> INTERFACES <<<
|
|
228
|
+
// >>> HELPERS <<<
|
|
229
|
+
var castComparer = function (comparer) { return function (a, b, order) { return comparer(a, b, order) * order; }; };
|
|
230
|
+
var throwInvalidConfigErrorIfTrue = function (condition, context) {
|
|
231
|
+
if (condition)
|
|
232
|
+
throw Error("Invalid sort config: " + context);
|
|
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
|
+
});
|
|
343
|
+
|
|
344
|
+
function handleValue$1(options) {
|
|
345
|
+
const { addToUsedBy, id, magicString, node, raw, replaceMap, offset = 0 } = options;
|
|
346
|
+
let value = raw;
|
|
347
|
+
const arr = sort(splitCode(value)).desc((x) => x.length);
|
|
348
|
+
for (const str of arr) {
|
|
349
|
+
if (replaceMap.has(str)) {
|
|
350
|
+
addToUsedBy(str, id);
|
|
351
|
+
const v = replaceMap.get(str);
|
|
352
|
+
if (v) {
|
|
353
|
+
value = value.replaceAll(str, v);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
if (typeof node.start === "number" && typeof node.end === "number" && value) {
|
|
358
|
+
magicString.update(node.start + offset, node.end - offset, value);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
const plugin = declare((api, options) => {
|
|
362
|
+
api.assertVersion(7);
|
|
363
|
+
const { magicString, replaceMap, id, addToUsedBy } = options;
|
|
364
|
+
return {
|
|
365
|
+
visitor: {
|
|
366
|
+
StringLiteral: {
|
|
367
|
+
enter(p) {
|
|
368
|
+
const node = p.node;
|
|
369
|
+
handleValue$1({
|
|
370
|
+
addToUsedBy,
|
|
371
|
+
id,
|
|
372
|
+
magicString,
|
|
373
|
+
node,
|
|
374
|
+
raw: node.value,
|
|
375
|
+
replaceMap,
|
|
376
|
+
offset: 1
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
TemplateElement: {
|
|
381
|
+
enter(p) {
|
|
382
|
+
const node = p.node;
|
|
383
|
+
handleValue$1({
|
|
384
|
+
addToUsedBy,
|
|
385
|
+
id,
|
|
386
|
+
magicString,
|
|
387
|
+
node,
|
|
388
|
+
raw: node.value.raw,
|
|
389
|
+
replaceMap,
|
|
390
|
+
offset: 0
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
});
|
|
397
|
+
function preProcessJs(options) {
|
|
398
|
+
const { code, replaceMap, id, addToUsedBy } = options;
|
|
399
|
+
const magicString = new MagicString(code);
|
|
400
|
+
babel.transformSync(code, {
|
|
401
|
+
presets: [
|
|
402
|
+
// ['@babel/preset-react', {}],
|
|
403
|
+
[
|
|
404
|
+
require("@babel/preset-typescript"),
|
|
405
|
+
{
|
|
406
|
+
allExtensions: true,
|
|
407
|
+
isTSX: true
|
|
408
|
+
}
|
|
409
|
+
]
|
|
410
|
+
],
|
|
411
|
+
plugins: [
|
|
412
|
+
[
|
|
413
|
+
plugin,
|
|
414
|
+
{
|
|
415
|
+
magicString,
|
|
416
|
+
replaceMap,
|
|
417
|
+
id,
|
|
418
|
+
addToUsedBy
|
|
419
|
+
}
|
|
420
|
+
]
|
|
421
|
+
]
|
|
422
|
+
});
|
|
423
|
+
return magicString.toString();
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
function handleValue(raw, node, options) {
|
|
427
|
+
const { replaceMap, classGenerator: clsGen, splitQuote = true } = options;
|
|
428
|
+
const array = splitCode(raw, {
|
|
243
429
|
splitQuote
|
|
244
430
|
});
|
|
245
|
-
let rawString =
|
|
431
|
+
let rawString = raw;
|
|
246
432
|
for (const v of array) {
|
|
247
|
-
if (
|
|
433
|
+
if (replaceMap.has(v)) {
|
|
248
434
|
let ignoreFlag = false;
|
|
249
435
|
if (Array.isArray(node.leadingComments)) {
|
|
250
436
|
ignoreFlag = node.leadingComments.findIndex((x) => x.value.includes("tw-mangle") && x.value.includes("ignore")) > -1;
|
|
@@ -278,12 +464,18 @@ function jsHandler(rawSource, options) {
|
|
|
278
464
|
},
|
|
279
465
|
CallExpression: {
|
|
280
466
|
enter(p) {
|
|
281
|
-
const
|
|
282
|
-
if (
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
467
|
+
const calleePath = p.get("callee");
|
|
468
|
+
if (calleePath.isIdentifier() && calleePath.node.name === "eval") {
|
|
469
|
+
p.traverse({
|
|
470
|
+
StringLiteral: {
|
|
471
|
+
enter(s) {
|
|
472
|
+
const res = jsHandler(s.node.value, options);
|
|
473
|
+
if (res.code) {
|
|
474
|
+
s.node.value = res.code;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
});
|
|
287
479
|
}
|
|
288
480
|
}
|
|
289
481
|
}
|
|
@@ -299,4 +491,4 @@ function jsHandler(rawSource, options) {
|
|
|
299
491
|
return result;
|
|
300
492
|
}
|
|
301
493
|
|
|
302
|
-
export { cssHandler, handleValue, htmlHandler, jsHandler };
|
|
494
|
+
export { cssHandler, handleValue, htmlHandler, jsHandler, preProcessJs };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tailwindcss-mangle/core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "The core of tailwindcss-mangle",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -36,12 +36,15 @@
|
|
|
36
36
|
"registry": "https://registry.npmjs.org/"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
+
"@babel/helper-plugin-utils": "^7.22.5",
|
|
40
|
+
"@babel/preset-typescript": "^7.22.5",
|
|
39
41
|
"@babel/core": "^7.22.10",
|
|
40
42
|
"@babel/types": "^7.22.10",
|
|
41
43
|
"parse5": "^7.1.2",
|
|
42
44
|
"postcss": "^8.4.27",
|
|
43
45
|
"postcss-selector-parser": "^6.0.13",
|
|
44
|
-
"
|
|
46
|
+
"magic-string": "^0.30.2",
|
|
47
|
+
"@tailwindcss-mangle/shared": "^2.0.0"
|
|
45
48
|
},
|
|
46
49
|
"devDependencies": {
|
|
47
50
|
"@parse5/tools": "^0.2.0",
|
|
@@ -54,7 +57,7 @@
|
|
|
54
57
|
},
|
|
55
58
|
"scripts": {
|
|
56
59
|
"build": "unbuild",
|
|
57
|
-
"test": "vitest run",
|
|
60
|
+
"test": "vitest run --coverage.enabled",
|
|
58
61
|
"test:dev": "vitest",
|
|
59
62
|
"coverage": "vitest run --coverage"
|
|
60
63
|
}
|