unplugin-tailwindcss-mangle 0.0.5 → 0.1.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/README.md +21 -4
- package/dist/constants.d.ts +1 -0
- package/dist/esbuild.js +5 -4
- package/dist/esbuild.mjs +5 -4
- package/dist/index.js +368 -164
- package/dist/index.mjs +363 -160
- package/dist/js/index.d.ts +2 -1
- package/dist/nuxt.js +9 -33
- package/dist/nuxt.mjs +9 -33
- package/dist/options.d.ts +11 -0
- package/dist/rollup.js +5 -4
- package/dist/rollup.mjs +5 -4
- package/dist/types.d.ts +13 -1
- package/dist/utils.d.ts +5 -0
- package/dist/vite.js +5 -4
- package/dist/vite.mjs +5 -4
- package/dist/webpack.js +5 -4
- package/dist/webpack.mjs +5 -4
- package/package.json +17 -15
package/dist/index.mjs
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { createUnplugin } from 'unplugin';
|
|
2
|
-
import
|
|
2
|
+
import micromatch from 'micromatch';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
3
5
|
import { html, defaultTreeAdapter, parse, serialize } from 'parse5';
|
|
4
|
-
import
|
|
5
|
-
import { parse as parse$1 } from '@babel/parser';
|
|
6
|
-
import _traverse from '@babel/traverse';
|
|
6
|
+
import { transformSync } from '@babel/core';
|
|
7
7
|
import postcss from 'postcss';
|
|
8
8
|
import parser from 'postcss-selector-parser';
|
|
9
|
+
import { getClassCacheSet } from 'tailwindcss-patch';
|
|
9
10
|
|
|
10
11
|
const pluginName = 'unplugin-tailwindcss-mangle';
|
|
11
12
|
|
|
13
|
+
const { isMatch } = micromatch;
|
|
14
|
+
const isMangleClass = (className) => {
|
|
15
|
+
return /[-:]/.test(className);
|
|
16
|
+
};
|
|
12
17
|
function groupBy(arr, cb) {
|
|
13
18
|
if (!Array.isArray(arr)) {
|
|
14
19
|
throw new Error('expected an array for first argument');
|
|
@@ -38,7 +43,7 @@ function getGroupedEntries(entries, options = {
|
|
|
38
43
|
return /\.html?$/.test(file);
|
|
39
44
|
},
|
|
40
45
|
jsMatcher(file) {
|
|
41
|
-
return /\.js$/.test(file);
|
|
46
|
+
return /\.[cm]?js$/.test(file);
|
|
42
47
|
}
|
|
43
48
|
}) {
|
|
44
49
|
const { cssMatcher, htmlMatcher, jsMatcher } = options;
|
|
@@ -56,6 +61,18 @@ function getGroupedEntries(entries, options = {
|
|
|
56
61
|
return 'other';
|
|
57
62
|
}
|
|
58
63
|
});
|
|
64
|
+
if (!groupedEntries.css) {
|
|
65
|
+
groupedEntries.css = [];
|
|
66
|
+
}
|
|
67
|
+
if (!groupedEntries.html) {
|
|
68
|
+
groupedEntries.html = [];
|
|
69
|
+
}
|
|
70
|
+
if (!groupedEntries.js) {
|
|
71
|
+
groupedEntries.js = [];
|
|
72
|
+
}
|
|
73
|
+
if (!groupedEntries.other) {
|
|
74
|
+
groupedEntries.other = [];
|
|
75
|
+
}
|
|
59
76
|
return groupedEntries;
|
|
60
77
|
}
|
|
61
78
|
const acceptChars = 'abcdefghijklmnopqrstuvwxyz'.split('');
|
|
@@ -91,97 +108,36 @@ function escapeStringRegexp(str) {
|
|
|
91
108
|
}
|
|
92
109
|
return str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d');
|
|
93
110
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
this.newClassSize = 0;
|
|
100
|
-
this.context = {};
|
|
101
|
-
this.opts = opts;
|
|
102
|
-
this.classPrefix = (_a = opts.classPrefix) !== null && _a !== void 0 ? _a : 'tw-';
|
|
103
|
-
}
|
|
104
|
-
defaultClassGenerate() {
|
|
105
|
-
const chars = [];
|
|
106
|
-
let rest = (this.newClassSize - (this.newClassSize % acceptChars.length)) / acceptChars.length;
|
|
107
|
-
if (rest > 0) {
|
|
108
|
-
while (true) {
|
|
109
|
-
rest -= 1;
|
|
110
|
-
const m = rest % acceptChars.length;
|
|
111
|
-
const c = acceptChars[m];
|
|
112
|
-
chars.push(c);
|
|
113
|
-
rest -= m;
|
|
114
|
-
if (rest === 0) {
|
|
115
|
-
break;
|
|
116
|
-
}
|
|
117
|
-
rest /= acceptChars.length;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
const prefixIndex = this.newClassSize % acceptChars.length;
|
|
121
|
-
const newClassName = `${this.classPrefix}${acceptChars[prefixIndex]}${chars.join('')}`;
|
|
122
|
-
return newClassName;
|
|
123
|
-
}
|
|
124
|
-
ignoreClassName(className) {
|
|
125
|
-
return regExpTest(this.opts.ignoreClass, className);
|
|
126
|
-
}
|
|
127
|
-
includeFilePath(filePath) {
|
|
128
|
-
const { include } = this.opts;
|
|
129
|
-
if (Array.isArray(include)) {
|
|
130
|
-
return regExpTest(include, filePath);
|
|
131
|
-
}
|
|
132
|
-
else {
|
|
133
|
-
return true;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
excludeFilePath(filePath) {
|
|
137
|
-
const { exclude } = this.opts;
|
|
138
|
-
if (Array.isArray(exclude)) {
|
|
139
|
-
return regExpTest(exclude, filePath);
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
return false;
|
|
143
|
-
}
|
|
111
|
+
function createGlobMatcher(pattern, fallbackValue = false) {
|
|
112
|
+
if (typeof pattern === 'undefined') {
|
|
113
|
+
return function (file) {
|
|
114
|
+
return fallbackValue;
|
|
115
|
+
};
|
|
144
116
|
}
|
|
145
|
-
|
|
146
|
-
return
|
|
117
|
+
return function (file) {
|
|
118
|
+
return isMatch(file, pattern);
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function getCacheDir(basedir = process.cwd()) {
|
|
122
|
+
return path.resolve(basedir, 'node_modules/.cache', pluginName);
|
|
123
|
+
}
|
|
124
|
+
function mkCacheDirectory(cwd = process.cwd()) {
|
|
125
|
+
const cacheDirectory = getCacheDir(cwd);
|
|
126
|
+
const exists = fs.existsSync(cacheDirectory);
|
|
127
|
+
if (!exists) {
|
|
128
|
+
fs.mkdirSync(cacheDirectory, {
|
|
129
|
+
recursive: true
|
|
130
|
+
});
|
|
147
131
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
132
|
+
return cacheDirectory;
|
|
133
|
+
}
|
|
134
|
+
function cacheDump(filename, data, basedir) {
|
|
135
|
+
try {
|
|
136
|
+
const dir = mkCacheDirectory(basedir);
|
|
137
|
+
fs.writeFileSync(path.resolve(dir, filename), JSON.stringify(Array.from(data), null, 2), 'utf-8');
|
|
154
138
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
original = stripEscapeSequence(original);
|
|
158
|
-
const cn = this.newClassMap[original];
|
|
159
|
-
if (cn)
|
|
160
|
-
return cn;
|
|
161
|
-
let newClassName;
|
|
162
|
-
if (opts.customGenerate && typeof opts.customGenerate === 'function') {
|
|
163
|
-
newClassName = opts.customGenerate(original, opts, this.context);
|
|
164
|
-
}
|
|
165
|
-
if (!newClassName) {
|
|
166
|
-
newClassName = this.defaultClassGenerate();
|
|
167
|
-
}
|
|
168
|
-
if (opts.reserveClassName && regExpTest(opts.reserveClassName, newClassName)) {
|
|
169
|
-
if (opts.log) {
|
|
170
|
-
console.log(`The class name has been reserved. ${newClassName}`);
|
|
171
|
-
}
|
|
172
|
-
this.newClassSize++;
|
|
173
|
-
return this.generateClassName(original);
|
|
174
|
-
}
|
|
175
|
-
if (opts.log) {
|
|
176
|
-
console.log(`Minify class name from ${original} to ${newClassName}`);
|
|
177
|
-
}
|
|
178
|
-
const newClass = {
|
|
179
|
-
name: newClassName,
|
|
180
|
-
usedBy: []
|
|
181
|
-
};
|
|
182
|
-
this.newClassMap[original] = newClass;
|
|
183
|
-
this.newClassSize++;
|
|
184
|
-
return newClass;
|
|
139
|
+
catch (error) {
|
|
140
|
+
console.log(error);
|
|
185
141
|
}
|
|
186
142
|
}
|
|
187
143
|
|
|
@@ -243,12 +199,12 @@ defaultTreeAdapter.appendChild;
|
|
|
243
199
|
* @param {ParentNode=} parent Parent node of the current node
|
|
244
200
|
* @return {void}
|
|
245
201
|
*/
|
|
246
|
-
function traverse
|
|
202
|
+
function traverse(node, visitor, parent) {
|
|
247
203
|
const shouldVisitChildren = typeof visitor['pre:node'] !== 'function' ||
|
|
248
204
|
visitor['pre:node'](node, parent) !== false;
|
|
249
205
|
if (shouldVisitChildren && isParentNode(node)) {
|
|
250
206
|
for (const child of node.childNodes) {
|
|
251
|
-
traverse
|
|
207
|
+
traverse(child, visitor, node);
|
|
252
208
|
}
|
|
253
209
|
}
|
|
254
210
|
if (typeof visitor.node === 'function') {
|
|
@@ -281,7 +237,7 @@ function traverse$1(node, visitor, parent) {
|
|
|
281
237
|
function htmlHandler(rawSource, options) {
|
|
282
238
|
const { runtimeSet, classGenerator } = options;
|
|
283
239
|
const fragment = parse(rawSource);
|
|
284
|
-
traverse
|
|
240
|
+
traverse(fragment, {
|
|
285
241
|
element(node, parent) {
|
|
286
242
|
const attr = node.attrs.find((x) => x.name === 'class');
|
|
287
243
|
if (attr) {
|
|
@@ -306,11 +262,6 @@ function isValidSelector(selector = '') {
|
|
|
306
262
|
}
|
|
307
263
|
const splitCode = (code) => code.split(/[\s"]+/).filter(isValidSelector);
|
|
308
264
|
|
|
309
|
-
function getDefaultExportFromNamespaceIfPresent(n) {
|
|
310
|
-
return n && Object.prototype.hasOwnProperty.call(n, 'default') ? n.default : n;
|
|
311
|
-
}
|
|
312
|
-
const generate = getDefaultExportFromNamespaceIfPresent(_generate);
|
|
313
|
-
const traverse = getDefaultExportFromNamespaceIfPresent(_traverse);
|
|
314
265
|
function makeRegex(str) {
|
|
315
266
|
return new RegExp('(?<=^|[\\s"])' + escapeStringRegexp(str), 'g');
|
|
316
267
|
}
|
|
@@ -334,24 +285,33 @@ function handleValue(str, node, options) {
|
|
|
334
285
|
return rawStr;
|
|
335
286
|
}
|
|
336
287
|
function jsHandler(rawSource, options) {
|
|
337
|
-
const
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
288
|
+
const result = transformSync(rawSource, {
|
|
289
|
+
babelrc: false,
|
|
290
|
+
ast: true,
|
|
291
|
+
plugins: [
|
|
292
|
+
() => {
|
|
293
|
+
return {
|
|
294
|
+
visitor: {
|
|
295
|
+
StringLiteral: {
|
|
296
|
+
enter(p) {
|
|
297
|
+
const n = p.node;
|
|
298
|
+
n.value = handleValue(n.value, n, options);
|
|
299
|
+
}
|
|
300
|
+
},
|
|
301
|
+
TemplateElement: {
|
|
302
|
+
enter(p) {
|
|
303
|
+
const n = p.node;
|
|
304
|
+
n.value.raw = handleValue(n.value.raw, n, options);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
};
|
|
349
309
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
return
|
|
310
|
+
],
|
|
311
|
+
sourceMaps: false,
|
|
312
|
+
configFile: false
|
|
313
|
+
});
|
|
314
|
+
return result;
|
|
355
315
|
}
|
|
356
316
|
|
|
357
317
|
const postcssPlugin = 'postcss-mangle-tailwindcss-plugin';
|
|
@@ -366,10 +326,19 @@ const postcssMangleTailwindcssPlugin = (options) => {
|
|
|
366
326
|
postcssPlugin,
|
|
367
327
|
Rule(rule, helper) {
|
|
368
328
|
rule.selector = parser((selectors) => {
|
|
369
|
-
selectors.
|
|
329
|
+
selectors.walkClasses((s) => {
|
|
370
330
|
if (s.value) {
|
|
371
331
|
const hit = newClassMap[s.value];
|
|
372
332
|
if (hit) {
|
|
333
|
+
if (s.parent) {
|
|
334
|
+
const idx = s.parent.nodes.indexOf(s);
|
|
335
|
+
if (idx > -1) {
|
|
336
|
+
const nextNode = s.parent.nodes[idx + 1];
|
|
337
|
+
if (nextNode && nextNode.type === 'attribute' && nextNode.attribute.indexOf('data-v-') > -1) {
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
373
342
|
s.value = hit.name;
|
|
374
343
|
}
|
|
375
344
|
}
|
|
@@ -388,22 +357,155 @@ function cssHandler(rawSource, options) {
|
|
|
388
357
|
]).process(rawSource).css;
|
|
389
358
|
}
|
|
390
359
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
360
|
+
class ClassGenerator {
|
|
361
|
+
newClassMap;
|
|
362
|
+
newClassSize;
|
|
363
|
+
context;
|
|
364
|
+
opts;
|
|
365
|
+
classPrefix;
|
|
366
|
+
constructor(opts = {}) {
|
|
367
|
+
this.newClassMap = {};
|
|
368
|
+
this.newClassSize = 0;
|
|
369
|
+
this.context = {};
|
|
370
|
+
this.opts = opts;
|
|
371
|
+
this.classPrefix = opts.classPrefix ?? 'tw-';
|
|
372
|
+
}
|
|
373
|
+
defaultClassGenerate() {
|
|
374
|
+
const chars = [];
|
|
375
|
+
let rest = (this.newClassSize - (this.newClassSize % acceptChars.length)) / acceptChars.length;
|
|
376
|
+
if (rest > 0) {
|
|
377
|
+
while (true) {
|
|
378
|
+
rest -= 1;
|
|
379
|
+
const m = rest % acceptChars.length;
|
|
380
|
+
const c = acceptChars[m];
|
|
381
|
+
chars.push(c);
|
|
382
|
+
rest -= m;
|
|
383
|
+
if (rest === 0) {
|
|
384
|
+
break;
|
|
385
|
+
}
|
|
386
|
+
rest /= acceptChars.length;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
const prefixIndex = this.newClassSize % acceptChars.length;
|
|
390
|
+
const newClassName = `${this.classPrefix}${acceptChars[prefixIndex]}${chars.join('')}`;
|
|
391
|
+
return newClassName;
|
|
392
|
+
}
|
|
393
|
+
ignoreClassName(className) {
|
|
394
|
+
return regExpTest(this.opts.ignoreClass, className);
|
|
395
|
+
}
|
|
396
|
+
includeFilePath(filePath) {
|
|
397
|
+
const { include } = this.opts;
|
|
398
|
+
if (Array.isArray(include)) {
|
|
399
|
+
return regExpTest(include, filePath);
|
|
400
|
+
}
|
|
401
|
+
else {
|
|
402
|
+
return true;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
excludeFilePath(filePath) {
|
|
406
|
+
const { exclude } = this.opts;
|
|
407
|
+
if (Array.isArray(exclude)) {
|
|
408
|
+
return regExpTest(exclude, filePath);
|
|
409
|
+
}
|
|
410
|
+
else {
|
|
411
|
+
return false;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
isFileIncluded(filePath) {
|
|
415
|
+
return this.includeFilePath(filePath) && !this.excludeFilePath(filePath);
|
|
416
|
+
}
|
|
417
|
+
transformCssClass(className) {
|
|
418
|
+
const key = stripEscapeSequence(className);
|
|
419
|
+
const cn = this.newClassMap[key];
|
|
420
|
+
if (cn)
|
|
421
|
+
return cn.name;
|
|
422
|
+
return className;
|
|
423
|
+
}
|
|
424
|
+
generateClassName(original) {
|
|
425
|
+
const opts = this.opts;
|
|
426
|
+
original = stripEscapeSequence(original);
|
|
427
|
+
const cn = this.newClassMap[original];
|
|
428
|
+
if (cn)
|
|
429
|
+
return cn;
|
|
430
|
+
let newClassName;
|
|
431
|
+
if (opts.customGenerate && typeof opts.customGenerate === 'function') {
|
|
432
|
+
newClassName = opts.customGenerate(original, opts, this.context);
|
|
433
|
+
}
|
|
434
|
+
if (!newClassName) {
|
|
435
|
+
newClassName = this.defaultClassGenerate();
|
|
436
|
+
}
|
|
437
|
+
if (opts.reserveClassName && regExpTest(opts.reserveClassName, newClassName)) {
|
|
438
|
+
if (opts.log) {
|
|
439
|
+
console.log(`The class name has been reserved. ${newClassName}`);
|
|
440
|
+
}
|
|
441
|
+
this.newClassSize++;
|
|
442
|
+
return this.generateClassName(original);
|
|
443
|
+
}
|
|
444
|
+
if (opts.log) {
|
|
445
|
+
console.log(`Minify class name from ${original} to ${newClassName}`);
|
|
446
|
+
}
|
|
447
|
+
const newClass = {
|
|
448
|
+
name: newClassName,
|
|
449
|
+
usedBy: []
|
|
450
|
+
};
|
|
451
|
+
this.newClassMap[original] = newClass;
|
|
452
|
+
this.newClassSize++;
|
|
453
|
+
return newClass;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
function getOptions(options = {}) {
|
|
458
|
+
const includeMatcher = createGlobMatcher(options.include, true);
|
|
459
|
+
const excludeMatcher = createGlobMatcher(options.exclude, false);
|
|
460
|
+
function isInclude(file) {
|
|
461
|
+
return includeMatcher(file) && !excludeMatcher(file);
|
|
462
|
+
}
|
|
395
463
|
let classSet;
|
|
464
|
+
const classSetOutputOptions = {
|
|
465
|
+
filename: 'classSet.json',
|
|
466
|
+
type: 'partial'
|
|
467
|
+
};
|
|
468
|
+
const classMapOutputOptions = {
|
|
469
|
+
filename: 'classMap.json'
|
|
470
|
+
};
|
|
471
|
+
if (typeof options.classSetOutput === 'object') {
|
|
472
|
+
Object.assign(classSetOutputOptions, options.classSetOutput);
|
|
473
|
+
}
|
|
474
|
+
if (typeof options.classMapOutput === 'object') {
|
|
475
|
+
Object.assign(classMapOutputOptions, options.classMapOutput);
|
|
476
|
+
}
|
|
396
477
|
const classGenerator = new ClassGenerator(options.classGenerator);
|
|
397
478
|
function getCachedClassSet() {
|
|
398
479
|
const set = getClassCacheSet();
|
|
480
|
+
const isOutput = set.size && options.classSetOutput;
|
|
481
|
+
if (isOutput && classSetOutputOptions.type === 'all') {
|
|
482
|
+
cacheDump(classSetOutputOptions.filename, set, classSetOutputOptions.dir);
|
|
483
|
+
}
|
|
399
484
|
set.forEach((c) => {
|
|
400
485
|
if (!isMangleClass(c)) {
|
|
401
486
|
set.delete(c);
|
|
402
487
|
}
|
|
403
488
|
});
|
|
489
|
+
if (isOutput && classSetOutputOptions.type === 'partial') {
|
|
490
|
+
cacheDump(classSetOutputOptions.filename, set, classSetOutputOptions.dir);
|
|
491
|
+
}
|
|
404
492
|
classSet = set;
|
|
405
493
|
return classSet;
|
|
406
494
|
}
|
|
495
|
+
return {
|
|
496
|
+
getCachedClassSet,
|
|
497
|
+
classGenerator,
|
|
498
|
+
includeMatcher,
|
|
499
|
+
excludeMatcher,
|
|
500
|
+
isInclude,
|
|
501
|
+
classSetOutputOptions,
|
|
502
|
+
classMapOutputOptions
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
const outputCachedMap = new Map();
|
|
507
|
+
const unplugin = createUnplugin((options = {}, meta) => {
|
|
508
|
+
const { classGenerator, getCachedClassSet, isInclude, classMapOutputOptions } = getOptions(options);
|
|
407
509
|
return {
|
|
408
510
|
name: pluginName,
|
|
409
511
|
enforce: 'post',
|
|
@@ -417,29 +519,38 @@ const unplugin = createUnplugin((options = {}, meta) => {
|
|
|
417
519
|
const groupedEntries = getGroupedEntries(Object.entries(bundle));
|
|
418
520
|
if (Array.isArray(groupedEntries.html) && groupedEntries.html.length) {
|
|
419
521
|
for (let i = 0; i < groupedEntries.html.length; i++) {
|
|
420
|
-
const [, asset] = groupedEntries.html[i];
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
522
|
+
const [file, asset] = groupedEntries.html[i];
|
|
523
|
+
if (isInclude(file)) {
|
|
524
|
+
asset.source = htmlHandler(asset.source.toString(), {
|
|
525
|
+
classGenerator,
|
|
526
|
+
runtimeSet
|
|
527
|
+
});
|
|
528
|
+
}
|
|
425
529
|
}
|
|
426
530
|
}
|
|
427
531
|
if (Array.isArray(groupedEntries.js) && groupedEntries.js.length) {
|
|
428
532
|
for (let i = 0; i < groupedEntries.js.length; i++) {
|
|
429
|
-
const [, chunk] = groupedEntries.js[i];
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
533
|
+
const [file, chunk] = groupedEntries.js[i];
|
|
534
|
+
if (isInclude(file)) {
|
|
535
|
+
const code = jsHandler(chunk.code, {
|
|
536
|
+
runtimeSet,
|
|
537
|
+
classGenerator
|
|
538
|
+
}).code;
|
|
539
|
+
if (code) {
|
|
540
|
+
chunk.code = code;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
434
543
|
}
|
|
435
544
|
}
|
|
436
545
|
if (Array.isArray(groupedEntries.css) && groupedEntries.css.length) {
|
|
437
546
|
for (let i = 0; i < groupedEntries.css.length; i++) {
|
|
438
|
-
const [, css] = groupedEntries.css[i];
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
547
|
+
const [file, css] = groupedEntries.css[i];
|
|
548
|
+
if (isInclude(file)) {
|
|
549
|
+
css.source = cssHandler(css.source.toString(), {
|
|
550
|
+
classGenerator,
|
|
551
|
+
runtimeSet
|
|
552
|
+
});
|
|
553
|
+
}
|
|
443
554
|
}
|
|
444
555
|
}
|
|
445
556
|
}
|
|
@@ -448,51 +559,143 @@ const unplugin = createUnplugin((options = {}, meta) => {
|
|
|
448
559
|
webpack(compiler) {
|
|
449
560
|
const Compilation = compiler.webpack.Compilation;
|
|
450
561
|
const { ConcatSource } = compiler.webpack.sources;
|
|
562
|
+
function getAssetPath(outputPath, file, abs = true) {
|
|
563
|
+
const fn = abs ? path.resolve : path.relative;
|
|
564
|
+
return fn(compiler.context, path.resolve(outputPath, file));
|
|
565
|
+
}
|
|
566
|
+
function overwriteServerSideAsset(outputPath, file, data) {
|
|
567
|
+
const abs = getAssetPath(outputPath, file);
|
|
568
|
+
const rel = getAssetPath(outputPath, file, false);
|
|
569
|
+
try {
|
|
570
|
+
fs.writeFileSync(abs, data, 'utf-8');
|
|
571
|
+
console.log('[tailwindcss-mangle]: ' + rel + ' overwrited successfully');
|
|
572
|
+
}
|
|
573
|
+
catch (error) {
|
|
574
|
+
console.log('[tailwindcss-mangle]: ' + rel + ' overwrited fail!');
|
|
575
|
+
console.log(error);
|
|
576
|
+
}
|
|
577
|
+
}
|
|
451
578
|
compiler.hooks.compilation.tap(pluginName, (compilation) => {
|
|
452
579
|
compilation.hooks.processAssets.tap({
|
|
453
580
|
name: pluginName,
|
|
454
581
|
stage: Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE
|
|
455
582
|
}, (assets) => {
|
|
456
583
|
const runtimeSet = getCachedClassSet();
|
|
584
|
+
const groupedEntries = getGroupedEntries(Object.entries(assets));
|
|
457
585
|
if (!runtimeSet.size) {
|
|
586
|
+
const css = new Map();
|
|
587
|
+
const html = new Map();
|
|
588
|
+
const js = new Map();
|
|
589
|
+
groupedEntries.css.forEach(([file, source]) => {
|
|
590
|
+
css.set(file, source);
|
|
591
|
+
});
|
|
592
|
+
groupedEntries.html.forEach(([file, source]) => {
|
|
593
|
+
html.set(file, source);
|
|
594
|
+
});
|
|
595
|
+
groupedEntries.js.forEach(([file, source]) => {
|
|
596
|
+
js.set(file, source);
|
|
597
|
+
});
|
|
598
|
+
if (js.size || css.size || html.size) {
|
|
599
|
+
outputCachedMap.set(compiler.outputPath, {
|
|
600
|
+
css,
|
|
601
|
+
html,
|
|
602
|
+
js
|
|
603
|
+
});
|
|
604
|
+
}
|
|
458
605
|
return;
|
|
459
606
|
}
|
|
460
|
-
|
|
461
|
-
if (Array.isArray(groupedEntries.html) && groupedEntries.html.length) {
|
|
607
|
+
if (groupedEntries.html.length) {
|
|
462
608
|
for (let i = 0; i < groupedEntries.html.length; i++) {
|
|
463
609
|
const [file, asset] = groupedEntries.html[i];
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
610
|
+
if (isInclude(file)) {
|
|
611
|
+
const html = htmlHandler(asset.source().toString(), {
|
|
612
|
+
classGenerator,
|
|
613
|
+
runtimeSet
|
|
614
|
+
});
|
|
615
|
+
const source = new ConcatSource(html);
|
|
616
|
+
compilation.updateAsset(file, source);
|
|
617
|
+
}
|
|
470
618
|
}
|
|
471
619
|
}
|
|
472
|
-
if (
|
|
620
|
+
if (groupedEntries.js.length) {
|
|
473
621
|
for (let i = 0; i < groupedEntries.js.length; i++) {
|
|
474
622
|
const [file, chunk] = groupedEntries.js[i];
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
623
|
+
if (isInclude(file)) {
|
|
624
|
+
const code = jsHandler(chunk.source().toString(), {
|
|
625
|
+
runtimeSet,
|
|
626
|
+
classGenerator
|
|
627
|
+
}).code;
|
|
628
|
+
if (code) {
|
|
629
|
+
const source = new ConcatSource(code);
|
|
630
|
+
compilation.updateAsset(file, source);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
481
633
|
}
|
|
482
634
|
}
|
|
483
|
-
if (
|
|
635
|
+
if (groupedEntries.css.length) {
|
|
484
636
|
for (let i = 0; i < groupedEntries.css.length; i++) {
|
|
485
637
|
const [file, css] = groupedEntries.css[i];
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
638
|
+
if (isInclude(file)) {
|
|
639
|
+
const newCss = cssHandler(css.source().toString(), {
|
|
640
|
+
classGenerator,
|
|
641
|
+
runtimeSet
|
|
642
|
+
});
|
|
643
|
+
const source = new ConcatSource(newCss);
|
|
644
|
+
compilation.updateAsset(file, source);
|
|
645
|
+
}
|
|
492
646
|
}
|
|
493
647
|
}
|
|
648
|
+
outputCachedMap.forEach(({ js, html, css }, key) => {
|
|
649
|
+
if (html.size) {
|
|
650
|
+
html.forEach((asset, file) => {
|
|
651
|
+
if (isInclude(file)) {
|
|
652
|
+
const html = htmlHandler(asset.source().toString(), {
|
|
653
|
+
classGenerator,
|
|
654
|
+
runtimeSet
|
|
655
|
+
});
|
|
656
|
+
overwriteServerSideAsset(key, file, html);
|
|
657
|
+
}
|
|
658
|
+
});
|
|
659
|
+
html.clear();
|
|
660
|
+
}
|
|
661
|
+
if (js.size) {
|
|
662
|
+
js.forEach((chunk, file) => {
|
|
663
|
+
if (isInclude(file)) {
|
|
664
|
+
const rawCode = chunk.source().toString();
|
|
665
|
+
const code = jsHandler(rawCode, {
|
|
666
|
+
runtimeSet,
|
|
667
|
+
classGenerator
|
|
668
|
+
}).code;
|
|
669
|
+
if (code) {
|
|
670
|
+
overwriteServerSideAsset(key, file, code);
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
});
|
|
674
|
+
js.clear();
|
|
675
|
+
}
|
|
676
|
+
if (css.size) {
|
|
677
|
+
css.forEach((style, file) => {
|
|
678
|
+
if (isInclude(file)) {
|
|
679
|
+
const newCss = cssHandler(style.source().toString(), {
|
|
680
|
+
classGenerator,
|
|
681
|
+
runtimeSet
|
|
682
|
+
});
|
|
683
|
+
overwriteServerSideAsset(key, file, newCss);
|
|
684
|
+
}
|
|
685
|
+
});
|
|
686
|
+
css.clear();
|
|
687
|
+
}
|
|
688
|
+
});
|
|
494
689
|
});
|
|
495
690
|
});
|
|
691
|
+
},
|
|
692
|
+
writeBundle() {
|
|
693
|
+
const entries = Object.entries(classGenerator.newClassMap);
|
|
694
|
+
if (entries.length && classMapOutputOptions) {
|
|
695
|
+
cacheDump(classMapOutputOptions.filename, entries.map((x) => {
|
|
696
|
+
return [x[0], x[1].name];
|
|
697
|
+
}), classMapOutputOptions.dir);
|
|
698
|
+
}
|
|
496
699
|
}
|
|
497
700
|
};
|
|
498
701
|
});
|
package/dist/js/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { StringLiteral, TemplateElement } from '@babel/types';
|
|
2
|
+
import { type BabelFileResult } from '@babel/core';
|
|
2
3
|
import type { IHandlerOptions } from '../types';
|
|
3
4
|
export declare function makeRegex(str: string): RegExp;
|
|
4
5
|
export declare function handleValue(str: string, node: StringLiteral | TemplateElement, options: IHandlerOptions): string;
|
|
5
|
-
export declare function jsHandler(rawSource: string, options: IHandlerOptions):
|
|
6
|
+
export declare function jsHandler(rawSource: string, options: IHandlerOptions): BabelFileResult;
|