unplugin-tailwindcss-mangle 0.1.2 → 0.1.4
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 +2 -0
- package/dist/esbuild.js +1 -4
- package/dist/esbuild.mjs +1 -4
- package/dist/index.js +31 -365
- package/dist/index.mjs +22 -354
- package/dist/loader/twm-css.d.ts +6 -0
- package/dist/nuxt.js +1 -4
- package/dist/nuxt.mjs +1 -4
- package/dist/options.d.ts +3 -1
- package/dist/rollup.js +1 -4
- package/dist/rollup.mjs +1 -4
- package/dist/twm-css.js +19 -0
- package/dist/twm-css.mjs +17 -0
- package/dist/types.d.ts +4 -1
- package/dist/vite.js +1 -4
- package/dist/vite.mjs +1 -4
- package/dist/webpack.js +1 -4
- package/dist/webpack.mjs +1 -4
- package/package.json +7 -16
- package/dist/classGenerator.d.ts +0 -17
- package/dist/css/index.d.ts +0 -2
- package/dist/css/plugins.d.ts +0 -7
- package/dist/html/index.d.ts +0 -2
- package/dist/js/index.d.ts +0 -6
- package/dist/js/split.d.ts +0 -3
package/README.md
CHANGED
|
@@ -105,11 +105,13 @@ custom class generator, if you want to custom class name (default 'tw-*'), use t
|
|
|
105
105
|
```js
|
|
106
106
|
export interface IClassGeneratorOptions {
|
|
107
107
|
reserveClassName?: (string | RegExp)[]
|
|
108
|
+
// custom generate class name
|
|
108
109
|
customGenerate?: (original: string, opts: IClassGeneratorOptions, context: Record<string, any>) => string | undefined
|
|
109
110
|
log?: boolean
|
|
110
111
|
exclude?: (string | RegExp)[]
|
|
111
112
|
include?: (string | RegExp)[]
|
|
112
113
|
ignoreClass?: (string | RegExp)[]
|
|
114
|
+
// default 'tw-',for example: tw-a,tw-b, you can set any you want, like '','ice-'
|
|
113
115
|
classPrefix?: string
|
|
114
116
|
}
|
|
115
117
|
```
|
package/dist/esbuild.js
CHANGED
|
@@ -5,10 +5,7 @@ require('unplugin');
|
|
|
5
5
|
require('micromatch');
|
|
6
6
|
require('fs');
|
|
7
7
|
require('path');
|
|
8
|
-
require('
|
|
9
|
-
require('@babel/core');
|
|
10
|
-
require('postcss');
|
|
11
|
-
require('postcss-selector-parser');
|
|
8
|
+
require('tailwindcss-mangle-core');
|
|
12
9
|
require('tailwindcss-patch');
|
|
13
10
|
|
|
14
11
|
var esbuild = index.unplugin.esbuild;
|
package/dist/esbuild.mjs
CHANGED
|
@@ -3,10 +3,7 @@ import 'unplugin';
|
|
|
3
3
|
import 'micromatch';
|
|
4
4
|
import 'fs';
|
|
5
5
|
import 'path';
|
|
6
|
-
import '
|
|
7
|
-
import '@babel/core';
|
|
8
|
-
import 'postcss';
|
|
9
|
-
import 'postcss-selector-parser';
|
|
6
|
+
import 'tailwindcss-mangle-core';
|
|
10
7
|
import 'tailwindcss-patch';
|
|
11
8
|
|
|
12
9
|
var esbuild = unplugin.esbuild;
|
package/dist/index.js
CHANGED
|
@@ -6,10 +6,7 @@ var unplugin$1 = require('unplugin');
|
|
|
6
6
|
var micromatch = require('micromatch');
|
|
7
7
|
var fs = require('fs');
|
|
8
8
|
var path = require('path');
|
|
9
|
-
var
|
|
10
|
-
var core = require('@babel/core');
|
|
11
|
-
var postcss = require('postcss');
|
|
12
|
-
var parser = require('postcss-selector-parser');
|
|
9
|
+
var tailwindcssMangleCore = require('tailwindcss-mangle-core');
|
|
13
10
|
var tailwindcssPatch = require('tailwindcss-patch');
|
|
14
11
|
|
|
15
12
|
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
@@ -17,8 +14,6 @@ function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e };
|
|
|
17
14
|
var micromatch__default = /*#__PURE__*/_interopDefault(micromatch);
|
|
18
15
|
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
19
16
|
var path__default = /*#__PURE__*/_interopDefault(path);
|
|
20
|
-
var postcss__default = /*#__PURE__*/_interopDefault(postcss);
|
|
21
|
-
var parser__default = /*#__PURE__*/_interopDefault(parser);
|
|
22
17
|
|
|
23
18
|
const pluginName = 'unplugin-tailwindcss-mangle';
|
|
24
19
|
|
|
@@ -87,39 +82,6 @@ function getGroupedEntries(entries, options = {
|
|
|
87
82
|
}
|
|
88
83
|
return groupedEntries;
|
|
89
84
|
}
|
|
90
|
-
const acceptChars = 'abcdefghijklmnopqrstuvwxyz'.split('');
|
|
91
|
-
function stripEscapeSequence(words) {
|
|
92
|
-
return words.replace(/\\/g, '');
|
|
93
|
-
}
|
|
94
|
-
function isRegexp(value) {
|
|
95
|
-
return Object.prototype.toString.call(value) === '[object RegExp]';
|
|
96
|
-
}
|
|
97
|
-
function regExpTest(arr = [], str) {
|
|
98
|
-
if (Array.isArray(arr)) {
|
|
99
|
-
for (let i = 0; i < arr.length; i++) {
|
|
100
|
-
const item = arr[i];
|
|
101
|
-
if (typeof item === 'string') {
|
|
102
|
-
if (item === str) {
|
|
103
|
-
return true;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
else if (isRegexp(item)) {
|
|
107
|
-
item.lastIndex = 0;
|
|
108
|
-
if (item.test(str)) {
|
|
109
|
-
return true;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
return false;
|
|
114
|
-
}
|
|
115
|
-
throw new TypeError("paramater 'arr' should be a Array of Regexp | String !");
|
|
116
|
-
}
|
|
117
|
-
function escapeStringRegexp(str) {
|
|
118
|
-
if (typeof str !== 'string') {
|
|
119
|
-
throw new TypeError('Expected a string');
|
|
120
|
-
}
|
|
121
|
-
return str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d');
|
|
122
|
-
}
|
|
123
85
|
function createGlobMatcher(pattern, fallbackValue = false) {
|
|
124
86
|
if (typeof pattern === 'undefined') {
|
|
125
87
|
return function (file) {
|
|
@@ -153,319 +115,6 @@ function cacheDump(filename, data, basedir) {
|
|
|
153
115
|
}
|
|
154
116
|
}
|
|
155
117
|
|
|
156
|
-
({
|
|
157
|
-
HTML: parse5.html.NS.HTML,
|
|
158
|
-
XML: parse5.html.NS.XML,
|
|
159
|
-
MATHML: parse5.html.NS.MATHML,
|
|
160
|
-
SVG: parse5.html.NS.SVG,
|
|
161
|
-
XLINK: parse5.html.NS.XLINK,
|
|
162
|
-
XMLNS: parse5.html.NS.XMLNS
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Determines if a given node is a document or not
|
|
167
|
-
* @param {Node} node Node to test
|
|
168
|
-
* @return {boolean}
|
|
169
|
-
*/
|
|
170
|
-
function isDocument(node) {
|
|
171
|
-
return node.nodeName === '#document';
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Determines if a given node is a document fragment or not
|
|
175
|
-
* @param {Node} node Node to test
|
|
176
|
-
* @return {boolean}
|
|
177
|
-
*/
|
|
178
|
-
function isDocumentFragment(node) {
|
|
179
|
-
return node.nodeName === '#document-fragment';
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Determines if a given node is a template node or not
|
|
183
|
-
* @param {Node} node Node to test
|
|
184
|
-
* @return {boolean}
|
|
185
|
-
*/
|
|
186
|
-
function isTemplateNode(node) {
|
|
187
|
-
return node.nodeName === 'template';
|
|
188
|
-
}
|
|
189
|
-
const isElementNode = parse5.defaultTreeAdapter.isElementNode;
|
|
190
|
-
const isCommentNode = parse5.defaultTreeAdapter.isCommentNode;
|
|
191
|
-
const isDocumentTypeNode = parse5.defaultTreeAdapter.isDocumentTypeNode;
|
|
192
|
-
const isTextNode = parse5.defaultTreeAdapter.isTextNode;
|
|
193
|
-
/**
|
|
194
|
-
* Determines if a given node is a parent or not
|
|
195
|
-
* @param {Node} node Node to test
|
|
196
|
-
* @return {boolean}
|
|
197
|
-
*/
|
|
198
|
-
function isParentNode(node) {
|
|
199
|
-
return (isDocument(node) ||
|
|
200
|
-
isDocumentFragment(node) ||
|
|
201
|
-
isElementNode(node) ||
|
|
202
|
-
isTemplateNode(node));
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
parse5.defaultTreeAdapter.appendChild;
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Traverses the tree of a given node
|
|
209
|
-
* @param {Node} node Node to traverse
|
|
210
|
-
* @param {Visitor} visitor Visitor to apply
|
|
211
|
-
* @param {ParentNode=} parent Parent node of the current node
|
|
212
|
-
* @return {void}
|
|
213
|
-
*/
|
|
214
|
-
function traverse(node, visitor, parent) {
|
|
215
|
-
const shouldVisitChildren = typeof visitor['pre:node'] !== 'function' ||
|
|
216
|
-
visitor['pre:node'](node, parent) !== false;
|
|
217
|
-
if (shouldVisitChildren && isParentNode(node)) {
|
|
218
|
-
for (const child of node.childNodes) {
|
|
219
|
-
traverse(child, visitor, node);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
if (typeof visitor.node === 'function') {
|
|
223
|
-
visitor.node(node, parent);
|
|
224
|
-
}
|
|
225
|
-
if (typeof visitor.document === 'function' && isDocument(node)) {
|
|
226
|
-
visitor.document(node);
|
|
227
|
-
}
|
|
228
|
-
if (typeof visitor.documentFragment === 'function' &&
|
|
229
|
-
isDocumentFragment(node)) {
|
|
230
|
-
visitor.documentFragment(node, parent);
|
|
231
|
-
}
|
|
232
|
-
if (typeof visitor.element === 'function' && isElementNode(node)) {
|
|
233
|
-
visitor.element(node, parent);
|
|
234
|
-
}
|
|
235
|
-
if (typeof visitor.template === 'function' && isTemplateNode(node)) {
|
|
236
|
-
visitor.template(node, parent);
|
|
237
|
-
}
|
|
238
|
-
if (typeof visitor.comment === 'function' && isCommentNode(node)) {
|
|
239
|
-
visitor.comment(node, parent);
|
|
240
|
-
}
|
|
241
|
-
if (typeof visitor.text === 'function' && isTextNode(node)) {
|
|
242
|
-
visitor.text(node, parent);
|
|
243
|
-
}
|
|
244
|
-
if (typeof visitor.documentType === 'function' && isDocumentTypeNode(node)) {
|
|
245
|
-
visitor.documentType(node, parent);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
function htmlHandler(rawSource, options) {
|
|
250
|
-
const { runtimeSet, classGenerator } = options;
|
|
251
|
-
const fragment = parse5.parse(rawSource);
|
|
252
|
-
traverse(fragment, {
|
|
253
|
-
element(node, parent) {
|
|
254
|
-
const attr = node.attrs.find((x) => x.name === 'class');
|
|
255
|
-
if (attr) {
|
|
256
|
-
const arr = attr.value.split(/\s/).filter((x) => x);
|
|
257
|
-
attr.value = arr
|
|
258
|
-
.map((x) => {
|
|
259
|
-
if (runtimeSet.has(x)) {
|
|
260
|
-
return classGenerator.generateClassName(x).name;
|
|
261
|
-
}
|
|
262
|
-
return x;
|
|
263
|
-
})
|
|
264
|
-
.join(' ');
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
});
|
|
268
|
-
return parse5.serialize(fragment);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
const validateFilterRE = /[\w\u00A0-\uFFFF-_:%-?]/;
|
|
272
|
-
function isValidSelector(selector = '') {
|
|
273
|
-
return validateFilterRE.test(selector);
|
|
274
|
-
}
|
|
275
|
-
const splitCode = (code) => code.split(/[\s"]+/).filter(isValidSelector);
|
|
276
|
-
|
|
277
|
-
function makeRegex(str) {
|
|
278
|
-
return new RegExp('(?<=^|[\\s"])' + escapeStringRegexp(str), 'g');
|
|
279
|
-
}
|
|
280
|
-
function handleValue(str, node, options) {
|
|
281
|
-
const set = options.runtimeSet;
|
|
282
|
-
const clsGen = options.classGenerator;
|
|
283
|
-
const arr = splitCode(str);
|
|
284
|
-
let rawStr = str;
|
|
285
|
-
for (let i = 0; i < arr.length; i++) {
|
|
286
|
-
const v = arr[i];
|
|
287
|
-
if (set.has(v)) {
|
|
288
|
-
let ignoreFlag = false;
|
|
289
|
-
if (Array.isArray(node.leadingComments)) {
|
|
290
|
-
ignoreFlag = node.leadingComments.findIndex((x) => x.value.includes('tw-mangle') && x.value.includes('ignore')) > -1;
|
|
291
|
-
}
|
|
292
|
-
if (!ignoreFlag) {
|
|
293
|
-
rawStr = rawStr.replace(makeRegex(v), clsGen.generateClassName(v).name);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
return rawStr;
|
|
298
|
-
}
|
|
299
|
-
function jsHandler(rawSource, options) {
|
|
300
|
-
const result = core.transformSync(rawSource, {
|
|
301
|
-
babelrc: false,
|
|
302
|
-
ast: true,
|
|
303
|
-
plugins: [
|
|
304
|
-
() => {
|
|
305
|
-
return {
|
|
306
|
-
visitor: {
|
|
307
|
-
StringLiteral: {
|
|
308
|
-
enter(p) {
|
|
309
|
-
const n = p.node;
|
|
310
|
-
n.value = handleValue(n.value, n, options);
|
|
311
|
-
}
|
|
312
|
-
},
|
|
313
|
-
TemplateElement: {
|
|
314
|
-
enter(p) {
|
|
315
|
-
const n = p.node;
|
|
316
|
-
n.value.raw = handleValue(n.value.raw, n, options);
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
};
|
|
321
|
-
}
|
|
322
|
-
],
|
|
323
|
-
sourceMaps: false,
|
|
324
|
-
configFile: false
|
|
325
|
-
});
|
|
326
|
-
return result;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
const postcssPlugin = 'postcss-mangle-tailwindcss-plugin';
|
|
330
|
-
const postcssMangleTailwindcssPlugin = (options) => {
|
|
331
|
-
let newClassMap = {};
|
|
332
|
-
if (options) {
|
|
333
|
-
if (options.newClassMap) {
|
|
334
|
-
newClassMap = options.newClassMap;
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
return {
|
|
338
|
-
postcssPlugin,
|
|
339
|
-
Rule(rule, helper) {
|
|
340
|
-
rule.selector = parser__default["default"]((selectors) => {
|
|
341
|
-
selectors.walkClasses((s) => {
|
|
342
|
-
if (s.value) {
|
|
343
|
-
const hit = newClassMap[s.value];
|
|
344
|
-
if (hit) {
|
|
345
|
-
if (s.parent) {
|
|
346
|
-
const idx = s.parent.nodes.indexOf(s);
|
|
347
|
-
if (idx > -1) {
|
|
348
|
-
const nextNode = s.parent.nodes[idx + 1];
|
|
349
|
-
if (nextNode && nextNode.type === 'attribute' && nextNode.attribute.indexOf('data-v-') > -1) {
|
|
350
|
-
return;
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
s.value = hit.name;
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
});
|
|
358
|
-
}).processSync(rule.selector);
|
|
359
|
-
}
|
|
360
|
-
};
|
|
361
|
-
};
|
|
362
|
-
postcssMangleTailwindcssPlugin.postcss = true;
|
|
363
|
-
|
|
364
|
-
function cssHandler(rawSource, options) {
|
|
365
|
-
return postcss__default["default"]([
|
|
366
|
-
postcssMangleTailwindcssPlugin({
|
|
367
|
-
newClassMap: options.classGenerator.newClassMap
|
|
368
|
-
})
|
|
369
|
-
]).process(rawSource).css;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
class ClassGenerator {
|
|
373
|
-
newClassMap;
|
|
374
|
-
newClassSize;
|
|
375
|
-
context;
|
|
376
|
-
opts;
|
|
377
|
-
classPrefix;
|
|
378
|
-
constructor(opts = {}) {
|
|
379
|
-
this.newClassMap = {};
|
|
380
|
-
this.newClassSize = 0;
|
|
381
|
-
this.context = {};
|
|
382
|
-
this.opts = opts;
|
|
383
|
-
this.classPrefix = opts.classPrefix ?? 'tw-';
|
|
384
|
-
}
|
|
385
|
-
defaultClassGenerate() {
|
|
386
|
-
const chars = [];
|
|
387
|
-
let rest = (this.newClassSize - (this.newClassSize % acceptChars.length)) / acceptChars.length;
|
|
388
|
-
if (rest > 0) {
|
|
389
|
-
while (true) {
|
|
390
|
-
rest -= 1;
|
|
391
|
-
const m = rest % acceptChars.length;
|
|
392
|
-
const c = acceptChars[m];
|
|
393
|
-
chars.push(c);
|
|
394
|
-
rest -= m;
|
|
395
|
-
if (rest === 0) {
|
|
396
|
-
break;
|
|
397
|
-
}
|
|
398
|
-
rest /= acceptChars.length;
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
const prefixIndex = this.newClassSize % acceptChars.length;
|
|
402
|
-
const newClassName = `${this.classPrefix}${acceptChars[prefixIndex]}${chars.join('')}`;
|
|
403
|
-
return newClassName;
|
|
404
|
-
}
|
|
405
|
-
ignoreClassName(className) {
|
|
406
|
-
return regExpTest(this.opts.ignoreClass, className);
|
|
407
|
-
}
|
|
408
|
-
includeFilePath(filePath) {
|
|
409
|
-
const { include } = this.opts;
|
|
410
|
-
if (Array.isArray(include)) {
|
|
411
|
-
return regExpTest(include, filePath);
|
|
412
|
-
}
|
|
413
|
-
else {
|
|
414
|
-
return true;
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
excludeFilePath(filePath) {
|
|
418
|
-
const { exclude } = this.opts;
|
|
419
|
-
if (Array.isArray(exclude)) {
|
|
420
|
-
return regExpTest(exclude, filePath);
|
|
421
|
-
}
|
|
422
|
-
else {
|
|
423
|
-
return false;
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
isFileIncluded(filePath) {
|
|
427
|
-
return this.includeFilePath(filePath) && !this.excludeFilePath(filePath);
|
|
428
|
-
}
|
|
429
|
-
transformCssClass(className) {
|
|
430
|
-
const key = stripEscapeSequence(className);
|
|
431
|
-
const cn = this.newClassMap[key];
|
|
432
|
-
if (cn)
|
|
433
|
-
return cn.name;
|
|
434
|
-
return className;
|
|
435
|
-
}
|
|
436
|
-
generateClassName(original) {
|
|
437
|
-
const opts = this.opts;
|
|
438
|
-
original = stripEscapeSequence(original);
|
|
439
|
-
const cn = this.newClassMap[original];
|
|
440
|
-
if (cn)
|
|
441
|
-
return cn;
|
|
442
|
-
let newClassName;
|
|
443
|
-
if (opts.customGenerate && typeof opts.customGenerate === 'function') {
|
|
444
|
-
newClassName = opts.customGenerate(original, opts, this.context);
|
|
445
|
-
}
|
|
446
|
-
if (!newClassName) {
|
|
447
|
-
newClassName = this.defaultClassGenerate();
|
|
448
|
-
}
|
|
449
|
-
if (opts.reserveClassName && regExpTest(opts.reserveClassName, newClassName)) {
|
|
450
|
-
if (opts.log) {
|
|
451
|
-
console.log(`The class name has been reserved. ${newClassName}`);
|
|
452
|
-
}
|
|
453
|
-
this.newClassSize++;
|
|
454
|
-
return this.generateClassName(original);
|
|
455
|
-
}
|
|
456
|
-
if (opts.log) {
|
|
457
|
-
console.log(`Minify class name from ${original} to ${newClassName}`);
|
|
458
|
-
}
|
|
459
|
-
const newClass = {
|
|
460
|
-
name: newClassName,
|
|
461
|
-
usedBy: []
|
|
462
|
-
};
|
|
463
|
-
this.newClassMap[original] = newClass;
|
|
464
|
-
this.newClassSize++;
|
|
465
|
-
return newClass;
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
|
|
469
118
|
function getOptions(options = {}) {
|
|
470
119
|
const includeMatcher = createGlobMatcher(options.include, true);
|
|
471
120
|
const excludeMatcher = createGlobMatcher(options.exclude, false);
|
|
@@ -473,6 +122,7 @@ function getOptions(options = {}) {
|
|
|
473
122
|
return includeMatcher(file) && !excludeMatcher(file);
|
|
474
123
|
}
|
|
475
124
|
let classSet;
|
|
125
|
+
const twPatcher = new tailwindcssPatch.TailwindcssPatcher();
|
|
476
126
|
const classSetOutputOptions = {
|
|
477
127
|
filename: 'classSet.json',
|
|
478
128
|
type: 'partial'
|
|
@@ -486,9 +136,9 @@ function getOptions(options = {}) {
|
|
|
486
136
|
if (typeof options.classMapOutput === 'object') {
|
|
487
137
|
Object.assign(classMapOutputOptions, options.classMapOutput);
|
|
488
138
|
}
|
|
489
|
-
const classGenerator = new ClassGenerator(options.classGenerator);
|
|
139
|
+
const classGenerator = new tailwindcssMangleCore.ClassGenerator(options.classGenerator);
|
|
490
140
|
function getCachedClassSet() {
|
|
491
|
-
const set =
|
|
141
|
+
const set = twPatcher.getClassSet();
|
|
492
142
|
const isOutput = set.size && options.classSetOutput;
|
|
493
143
|
if (isOutput && classSetOutputOptions.type === 'all') {
|
|
494
144
|
cacheDump(classSetOutputOptions.filename, set, classSetOutputOptions.dir);
|
|
@@ -511,7 +161,8 @@ function getOptions(options = {}) {
|
|
|
511
161
|
excludeMatcher,
|
|
512
162
|
isInclude,
|
|
513
163
|
classSetOutputOptions,
|
|
514
|
-
classMapOutputOptions
|
|
164
|
+
classMapOutputOptions,
|
|
165
|
+
twPatcher
|
|
515
166
|
};
|
|
516
167
|
}
|
|
517
168
|
|
|
@@ -533,7 +184,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
|
|
|
533
184
|
for (let i = 0; i < groupedEntries.html.length; i++) {
|
|
534
185
|
const [file, asset] = groupedEntries.html[i];
|
|
535
186
|
if (isInclude(file)) {
|
|
536
|
-
asset.source = htmlHandler(asset.source.toString(), {
|
|
187
|
+
asset.source = tailwindcssMangleCore.htmlHandler(asset.source.toString(), {
|
|
537
188
|
classGenerator,
|
|
538
189
|
runtimeSet
|
|
539
190
|
});
|
|
@@ -544,7 +195,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
|
|
|
544
195
|
for (let i = 0; i < groupedEntries.js.length; i++) {
|
|
545
196
|
const [file, chunk] = groupedEntries.js[i];
|
|
546
197
|
if (isInclude(file)) {
|
|
547
|
-
const code = jsHandler(chunk.code, {
|
|
198
|
+
const code = tailwindcssMangleCore.jsHandler(chunk.code, {
|
|
548
199
|
runtimeSet,
|
|
549
200
|
classGenerator
|
|
550
201
|
}).code;
|
|
@@ -558,7 +209,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
|
|
|
558
209
|
for (let i = 0; i < groupedEntries.css.length; i++) {
|
|
559
210
|
const [file, css] = groupedEntries.css[i];
|
|
560
211
|
if (isInclude(file)) {
|
|
561
|
-
css.source = cssHandler(css.source.toString(), {
|
|
212
|
+
css.source = tailwindcssMangleCore.cssHandler(css.source.toString(), {
|
|
562
213
|
classGenerator,
|
|
563
214
|
runtimeSet
|
|
564
215
|
});
|
|
@@ -569,7 +220,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
|
|
|
569
220
|
}
|
|
570
221
|
},
|
|
571
222
|
webpack(compiler) {
|
|
572
|
-
const Compilation = compiler.webpack
|
|
223
|
+
const { NormalModule, Compilation } = compiler.webpack;
|
|
573
224
|
const { ConcatSource } = compiler.webpack.sources;
|
|
574
225
|
function getAssetPath(outputPath, file, abs = true) {
|
|
575
226
|
const fn = abs ? path__default["default"].resolve : path__default["default"].relative;
|
|
@@ -587,7 +238,22 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
|
|
|
587
238
|
console.log(error);
|
|
588
239
|
}
|
|
589
240
|
}
|
|
241
|
+
const twmCssloader = path__default["default"].resolve(__dirname, 'twm-css.js');
|
|
590
242
|
compiler.hooks.compilation.tap(pluginName, (compilation) => {
|
|
243
|
+
NormalModule.getCompilationHooks(compilation).loader.tap(pluginName, (loaderContext, module) => {
|
|
244
|
+
const idx = module.loaders.findIndex((x) => x.loader.includes('css-loader'));
|
|
245
|
+
if (idx > -1) {
|
|
246
|
+
module.loaders.splice(idx + 1, 0, {
|
|
247
|
+
loader: twmCssloader,
|
|
248
|
+
options: {
|
|
249
|
+
classGenerator,
|
|
250
|
+
getCachedClassSet
|
|
251
|
+
},
|
|
252
|
+
ident: null,
|
|
253
|
+
type: null
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
});
|
|
591
257
|
compilation.hooks.processAssets.tap({
|
|
592
258
|
name: pluginName,
|
|
593
259
|
stage: Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE
|
|
@@ -620,7 +286,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
|
|
|
620
286
|
for (let i = 0; i < groupedEntries.html.length; i++) {
|
|
621
287
|
const [file, asset] = groupedEntries.html[i];
|
|
622
288
|
if (isInclude(file)) {
|
|
623
|
-
const html = htmlHandler(asset.source().toString(), {
|
|
289
|
+
const html = tailwindcssMangleCore.htmlHandler(asset.source().toString(), {
|
|
624
290
|
classGenerator,
|
|
625
291
|
runtimeSet
|
|
626
292
|
});
|
|
@@ -633,7 +299,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
|
|
|
633
299
|
for (let i = 0; i < groupedEntries.js.length; i++) {
|
|
634
300
|
const [file, chunk] = groupedEntries.js[i];
|
|
635
301
|
if (isInclude(file)) {
|
|
636
|
-
const code = jsHandler(chunk.source().toString(), {
|
|
302
|
+
const code = tailwindcssMangleCore.jsHandler(chunk.source().toString(), {
|
|
637
303
|
runtimeSet,
|
|
638
304
|
classGenerator
|
|
639
305
|
}).code;
|
|
@@ -648,7 +314,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
|
|
|
648
314
|
for (let i = 0; i < groupedEntries.css.length; i++) {
|
|
649
315
|
const [file, css] = groupedEntries.css[i];
|
|
650
316
|
if (isInclude(file)) {
|
|
651
|
-
const newCss = cssHandler(css.source().toString(), {
|
|
317
|
+
const newCss = tailwindcssMangleCore.cssHandler(css.source().toString(), {
|
|
652
318
|
classGenerator,
|
|
653
319
|
runtimeSet
|
|
654
320
|
});
|
|
@@ -661,7 +327,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
|
|
|
661
327
|
if (html.size) {
|
|
662
328
|
html.forEach((asset, file) => {
|
|
663
329
|
if (isInclude(file)) {
|
|
664
|
-
const html = htmlHandler(asset.source().toString(), {
|
|
330
|
+
const html = tailwindcssMangleCore.htmlHandler(asset.source().toString(), {
|
|
665
331
|
classGenerator,
|
|
666
332
|
runtimeSet
|
|
667
333
|
});
|
|
@@ -674,7 +340,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
|
|
|
674
340
|
js.forEach((chunk, file) => {
|
|
675
341
|
if (isInclude(file)) {
|
|
676
342
|
const rawCode = chunk.source().toString();
|
|
677
|
-
const code = jsHandler(rawCode, {
|
|
343
|
+
const code = tailwindcssMangleCore.jsHandler(rawCode, {
|
|
678
344
|
runtimeSet,
|
|
679
345
|
classGenerator
|
|
680
346
|
}).code;
|
|
@@ -688,7 +354,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
|
|
|
688
354
|
if (css.size) {
|
|
689
355
|
css.forEach((style, file) => {
|
|
690
356
|
if (isInclude(file)) {
|
|
691
|
-
const newCss = cssHandler(style.source().toString(), {
|
|
357
|
+
const newCss = tailwindcssMangleCore.cssHandler(style.source().toString(), {
|
|
692
358
|
classGenerator,
|
|
693
359
|
runtimeSet
|
|
694
360
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -2,11 +2,8 @@ import { createUnplugin } from 'unplugin';
|
|
|
2
2
|
import micromatch from 'micromatch';
|
|
3
3
|
import fs from 'fs';
|
|
4
4
|
import path from 'path';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import postcss from 'postcss';
|
|
8
|
-
import parser from 'postcss-selector-parser';
|
|
9
|
-
import { getClassCacheSet } from 'tailwindcss-patch';
|
|
5
|
+
import { ClassGenerator, htmlHandler, jsHandler, cssHandler } from 'tailwindcss-mangle-core';
|
|
6
|
+
import { TailwindcssPatcher } from 'tailwindcss-patch';
|
|
10
7
|
|
|
11
8
|
const pluginName = 'unplugin-tailwindcss-mangle';
|
|
12
9
|
|
|
@@ -75,39 +72,6 @@ function getGroupedEntries(entries, options = {
|
|
|
75
72
|
}
|
|
76
73
|
return groupedEntries;
|
|
77
74
|
}
|
|
78
|
-
const acceptChars = 'abcdefghijklmnopqrstuvwxyz'.split('');
|
|
79
|
-
function stripEscapeSequence(words) {
|
|
80
|
-
return words.replace(/\\/g, '');
|
|
81
|
-
}
|
|
82
|
-
function isRegexp(value) {
|
|
83
|
-
return Object.prototype.toString.call(value) === '[object RegExp]';
|
|
84
|
-
}
|
|
85
|
-
function regExpTest(arr = [], str) {
|
|
86
|
-
if (Array.isArray(arr)) {
|
|
87
|
-
for (let i = 0; i < arr.length; i++) {
|
|
88
|
-
const item = arr[i];
|
|
89
|
-
if (typeof item === 'string') {
|
|
90
|
-
if (item === str) {
|
|
91
|
-
return true;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
else if (isRegexp(item)) {
|
|
95
|
-
item.lastIndex = 0;
|
|
96
|
-
if (item.test(str)) {
|
|
97
|
-
return true;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
return false;
|
|
102
|
-
}
|
|
103
|
-
throw new TypeError("paramater 'arr' should be a Array of Regexp | String !");
|
|
104
|
-
}
|
|
105
|
-
function escapeStringRegexp(str) {
|
|
106
|
-
if (typeof str !== 'string') {
|
|
107
|
-
throw new TypeError('Expected a string');
|
|
108
|
-
}
|
|
109
|
-
return str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d');
|
|
110
|
-
}
|
|
111
75
|
function createGlobMatcher(pattern, fallbackValue = false) {
|
|
112
76
|
if (typeof pattern === 'undefined') {
|
|
113
77
|
return function (file) {
|
|
@@ -141,319 +105,6 @@ function cacheDump(filename, data, basedir) {
|
|
|
141
105
|
}
|
|
142
106
|
}
|
|
143
107
|
|
|
144
|
-
({
|
|
145
|
-
HTML: html.NS.HTML,
|
|
146
|
-
XML: html.NS.XML,
|
|
147
|
-
MATHML: html.NS.MATHML,
|
|
148
|
-
SVG: html.NS.SVG,
|
|
149
|
-
XLINK: html.NS.XLINK,
|
|
150
|
-
XMLNS: html.NS.XMLNS
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Determines if a given node is a document or not
|
|
155
|
-
* @param {Node} node Node to test
|
|
156
|
-
* @return {boolean}
|
|
157
|
-
*/
|
|
158
|
-
function isDocument(node) {
|
|
159
|
-
return node.nodeName === '#document';
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Determines if a given node is a document fragment or not
|
|
163
|
-
* @param {Node} node Node to test
|
|
164
|
-
* @return {boolean}
|
|
165
|
-
*/
|
|
166
|
-
function isDocumentFragment(node) {
|
|
167
|
-
return node.nodeName === '#document-fragment';
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Determines if a given node is a template node or not
|
|
171
|
-
* @param {Node} node Node to test
|
|
172
|
-
* @return {boolean}
|
|
173
|
-
*/
|
|
174
|
-
function isTemplateNode(node) {
|
|
175
|
-
return node.nodeName === 'template';
|
|
176
|
-
}
|
|
177
|
-
const isElementNode = defaultTreeAdapter.isElementNode;
|
|
178
|
-
const isCommentNode = defaultTreeAdapter.isCommentNode;
|
|
179
|
-
const isDocumentTypeNode = defaultTreeAdapter.isDocumentTypeNode;
|
|
180
|
-
const isTextNode = defaultTreeAdapter.isTextNode;
|
|
181
|
-
/**
|
|
182
|
-
* Determines if a given node is a parent or not
|
|
183
|
-
* @param {Node} node Node to test
|
|
184
|
-
* @return {boolean}
|
|
185
|
-
*/
|
|
186
|
-
function isParentNode(node) {
|
|
187
|
-
return (isDocument(node) ||
|
|
188
|
-
isDocumentFragment(node) ||
|
|
189
|
-
isElementNode(node) ||
|
|
190
|
-
isTemplateNode(node));
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
defaultTreeAdapter.appendChild;
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Traverses the tree of a given node
|
|
197
|
-
* @param {Node} node Node to traverse
|
|
198
|
-
* @param {Visitor} visitor Visitor to apply
|
|
199
|
-
* @param {ParentNode=} parent Parent node of the current node
|
|
200
|
-
* @return {void}
|
|
201
|
-
*/
|
|
202
|
-
function traverse(node, visitor, parent) {
|
|
203
|
-
const shouldVisitChildren = typeof visitor['pre:node'] !== 'function' ||
|
|
204
|
-
visitor['pre:node'](node, parent) !== false;
|
|
205
|
-
if (shouldVisitChildren && isParentNode(node)) {
|
|
206
|
-
for (const child of node.childNodes) {
|
|
207
|
-
traverse(child, visitor, node);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
if (typeof visitor.node === 'function') {
|
|
211
|
-
visitor.node(node, parent);
|
|
212
|
-
}
|
|
213
|
-
if (typeof visitor.document === 'function' && isDocument(node)) {
|
|
214
|
-
visitor.document(node);
|
|
215
|
-
}
|
|
216
|
-
if (typeof visitor.documentFragment === 'function' &&
|
|
217
|
-
isDocumentFragment(node)) {
|
|
218
|
-
visitor.documentFragment(node, parent);
|
|
219
|
-
}
|
|
220
|
-
if (typeof visitor.element === 'function' && isElementNode(node)) {
|
|
221
|
-
visitor.element(node, parent);
|
|
222
|
-
}
|
|
223
|
-
if (typeof visitor.template === 'function' && isTemplateNode(node)) {
|
|
224
|
-
visitor.template(node, parent);
|
|
225
|
-
}
|
|
226
|
-
if (typeof visitor.comment === 'function' && isCommentNode(node)) {
|
|
227
|
-
visitor.comment(node, parent);
|
|
228
|
-
}
|
|
229
|
-
if (typeof visitor.text === 'function' && isTextNode(node)) {
|
|
230
|
-
visitor.text(node, parent);
|
|
231
|
-
}
|
|
232
|
-
if (typeof visitor.documentType === 'function' && isDocumentTypeNode(node)) {
|
|
233
|
-
visitor.documentType(node, parent);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
function htmlHandler(rawSource, options) {
|
|
238
|
-
const { runtimeSet, classGenerator } = options;
|
|
239
|
-
const fragment = parse(rawSource);
|
|
240
|
-
traverse(fragment, {
|
|
241
|
-
element(node, parent) {
|
|
242
|
-
const attr = node.attrs.find((x) => x.name === 'class');
|
|
243
|
-
if (attr) {
|
|
244
|
-
const arr = attr.value.split(/\s/).filter((x) => x);
|
|
245
|
-
attr.value = arr
|
|
246
|
-
.map((x) => {
|
|
247
|
-
if (runtimeSet.has(x)) {
|
|
248
|
-
return classGenerator.generateClassName(x).name;
|
|
249
|
-
}
|
|
250
|
-
return x;
|
|
251
|
-
})
|
|
252
|
-
.join(' ');
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
});
|
|
256
|
-
return serialize(fragment);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
const validateFilterRE = /[\w\u00A0-\uFFFF-_:%-?]/;
|
|
260
|
-
function isValidSelector(selector = '') {
|
|
261
|
-
return validateFilterRE.test(selector);
|
|
262
|
-
}
|
|
263
|
-
const splitCode = (code) => code.split(/[\s"]+/).filter(isValidSelector);
|
|
264
|
-
|
|
265
|
-
function makeRegex(str) {
|
|
266
|
-
return new RegExp('(?<=^|[\\s"])' + escapeStringRegexp(str), 'g');
|
|
267
|
-
}
|
|
268
|
-
function handleValue(str, node, options) {
|
|
269
|
-
const set = options.runtimeSet;
|
|
270
|
-
const clsGen = options.classGenerator;
|
|
271
|
-
const arr = splitCode(str);
|
|
272
|
-
let rawStr = str;
|
|
273
|
-
for (let i = 0; i < arr.length; i++) {
|
|
274
|
-
const v = arr[i];
|
|
275
|
-
if (set.has(v)) {
|
|
276
|
-
let ignoreFlag = false;
|
|
277
|
-
if (Array.isArray(node.leadingComments)) {
|
|
278
|
-
ignoreFlag = node.leadingComments.findIndex((x) => x.value.includes('tw-mangle') && x.value.includes('ignore')) > -1;
|
|
279
|
-
}
|
|
280
|
-
if (!ignoreFlag) {
|
|
281
|
-
rawStr = rawStr.replace(makeRegex(v), clsGen.generateClassName(v).name);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
return rawStr;
|
|
286
|
-
}
|
|
287
|
-
function jsHandler(rawSource, options) {
|
|
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
|
-
};
|
|
309
|
-
}
|
|
310
|
-
],
|
|
311
|
-
sourceMaps: false,
|
|
312
|
-
configFile: false
|
|
313
|
-
});
|
|
314
|
-
return result;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
const postcssPlugin = 'postcss-mangle-tailwindcss-plugin';
|
|
318
|
-
const postcssMangleTailwindcssPlugin = (options) => {
|
|
319
|
-
let newClassMap = {};
|
|
320
|
-
if (options) {
|
|
321
|
-
if (options.newClassMap) {
|
|
322
|
-
newClassMap = options.newClassMap;
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
return {
|
|
326
|
-
postcssPlugin,
|
|
327
|
-
Rule(rule, helper) {
|
|
328
|
-
rule.selector = parser((selectors) => {
|
|
329
|
-
selectors.walkClasses((s) => {
|
|
330
|
-
if (s.value) {
|
|
331
|
-
const hit = newClassMap[s.value];
|
|
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
|
-
}
|
|
342
|
-
s.value = hit.name;
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
});
|
|
346
|
-
}).processSync(rule.selector);
|
|
347
|
-
}
|
|
348
|
-
};
|
|
349
|
-
};
|
|
350
|
-
postcssMangleTailwindcssPlugin.postcss = true;
|
|
351
|
-
|
|
352
|
-
function cssHandler(rawSource, options) {
|
|
353
|
-
return postcss([
|
|
354
|
-
postcssMangleTailwindcssPlugin({
|
|
355
|
-
newClassMap: options.classGenerator.newClassMap
|
|
356
|
-
})
|
|
357
|
-
]).process(rawSource).css;
|
|
358
|
-
}
|
|
359
|
-
|
|
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
108
|
function getOptions(options = {}) {
|
|
458
109
|
const includeMatcher = createGlobMatcher(options.include, true);
|
|
459
110
|
const excludeMatcher = createGlobMatcher(options.exclude, false);
|
|
@@ -461,6 +112,7 @@ function getOptions(options = {}) {
|
|
|
461
112
|
return includeMatcher(file) && !excludeMatcher(file);
|
|
462
113
|
}
|
|
463
114
|
let classSet;
|
|
115
|
+
const twPatcher = new TailwindcssPatcher();
|
|
464
116
|
const classSetOutputOptions = {
|
|
465
117
|
filename: 'classSet.json',
|
|
466
118
|
type: 'partial'
|
|
@@ -476,7 +128,7 @@ function getOptions(options = {}) {
|
|
|
476
128
|
}
|
|
477
129
|
const classGenerator = new ClassGenerator(options.classGenerator);
|
|
478
130
|
function getCachedClassSet() {
|
|
479
|
-
const set =
|
|
131
|
+
const set = twPatcher.getClassSet();
|
|
480
132
|
const isOutput = set.size && options.classSetOutput;
|
|
481
133
|
if (isOutput && classSetOutputOptions.type === 'all') {
|
|
482
134
|
cacheDump(classSetOutputOptions.filename, set, classSetOutputOptions.dir);
|
|
@@ -499,7 +151,8 @@ function getOptions(options = {}) {
|
|
|
499
151
|
excludeMatcher,
|
|
500
152
|
isInclude,
|
|
501
153
|
classSetOutputOptions,
|
|
502
|
-
classMapOutputOptions
|
|
154
|
+
classMapOutputOptions,
|
|
155
|
+
twPatcher
|
|
503
156
|
};
|
|
504
157
|
}
|
|
505
158
|
|
|
@@ -557,7 +210,7 @@ const unplugin = createUnplugin((options = {}, meta) => {
|
|
|
557
210
|
}
|
|
558
211
|
},
|
|
559
212
|
webpack(compiler) {
|
|
560
|
-
const Compilation = compiler.webpack
|
|
213
|
+
const { NormalModule, Compilation } = compiler.webpack;
|
|
561
214
|
const { ConcatSource } = compiler.webpack.sources;
|
|
562
215
|
function getAssetPath(outputPath, file, abs = true) {
|
|
563
216
|
const fn = abs ? path.resolve : path.relative;
|
|
@@ -575,7 +228,22 @@ const unplugin = createUnplugin((options = {}, meta) => {
|
|
|
575
228
|
console.log(error);
|
|
576
229
|
}
|
|
577
230
|
}
|
|
231
|
+
const twmCssloader = path.resolve(__dirname, 'twm-css.js');
|
|
578
232
|
compiler.hooks.compilation.tap(pluginName, (compilation) => {
|
|
233
|
+
NormalModule.getCompilationHooks(compilation).loader.tap(pluginName, (loaderContext, module) => {
|
|
234
|
+
const idx = module.loaders.findIndex((x) => x.loader.includes('css-loader'));
|
|
235
|
+
if (idx > -1) {
|
|
236
|
+
module.loaders.splice(idx + 1, 0, {
|
|
237
|
+
loader: twmCssloader,
|
|
238
|
+
options: {
|
|
239
|
+
classGenerator,
|
|
240
|
+
getCachedClassSet
|
|
241
|
+
},
|
|
242
|
+
ident: null,
|
|
243
|
+
type: null
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
});
|
|
579
247
|
compilation.hooks.processAssets.tap({
|
|
580
248
|
name: pluginName,
|
|
581
249
|
stage: Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as webpack from 'webpack';
|
|
2
|
+
import { ClassGenerator } from 'tailwindcss-mangle-core';
|
|
3
|
+
export default function cssloader(this: webpack.LoaderContext<{
|
|
4
|
+
classGenerator: ClassGenerator;
|
|
5
|
+
getCachedClassSet: (() => Set<string>) | undefined;
|
|
6
|
+
}>, content: string): string;
|
package/dist/nuxt.js
CHANGED
|
@@ -5,10 +5,7 @@ require('unplugin');
|
|
|
5
5
|
require('micromatch');
|
|
6
6
|
require('fs');
|
|
7
7
|
require('path');
|
|
8
|
-
require('
|
|
9
|
-
require('@babel/core');
|
|
10
|
-
require('postcss');
|
|
11
|
-
require('postcss-selector-parser');
|
|
8
|
+
require('tailwindcss-mangle-core');
|
|
12
9
|
require('tailwindcss-patch');
|
|
13
10
|
|
|
14
11
|
function nuxt (options = {}, nuxt) {
|
package/dist/nuxt.mjs
CHANGED
|
@@ -3,10 +3,7 @@ import 'unplugin';
|
|
|
3
3
|
import 'micromatch';
|
|
4
4
|
import 'fs';
|
|
5
5
|
import 'path';
|
|
6
|
-
import '
|
|
7
|
-
import '@babel/core';
|
|
8
|
-
import 'postcss';
|
|
9
|
-
import 'postcss-selector-parser';
|
|
6
|
+
import 'tailwindcss-mangle-core';
|
|
10
7
|
import 'tailwindcss-patch';
|
|
11
8
|
|
|
12
9
|
function nuxt (options = {}, nuxt) {
|
package/dist/options.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Options, ClassSetOutputOptions, ClassMapOutputOptions } from './types';
|
|
2
|
-
import
|
|
2
|
+
import { TailwindcssPatcher } from 'tailwindcss-patch';
|
|
3
|
+
import { ClassGenerator } from 'tailwindcss-mangle-core';
|
|
3
4
|
export declare function getOptions(options?: Options | undefined): {
|
|
4
5
|
getCachedClassSet: () => Set<string>;
|
|
5
6
|
classGenerator: ClassGenerator;
|
|
@@ -8,4 +9,5 @@ export declare function getOptions(options?: Options | undefined): {
|
|
|
8
9
|
isInclude: (file: string) => boolean;
|
|
9
10
|
classSetOutputOptions: ClassSetOutputOptions;
|
|
10
11
|
classMapOutputOptions: ClassMapOutputOptions;
|
|
12
|
+
twPatcher: TailwindcssPatcher;
|
|
11
13
|
};
|
package/dist/rollup.js
CHANGED
|
@@ -5,10 +5,7 @@ require('unplugin');
|
|
|
5
5
|
require('micromatch');
|
|
6
6
|
require('fs');
|
|
7
7
|
require('path');
|
|
8
|
-
require('
|
|
9
|
-
require('@babel/core');
|
|
10
|
-
require('postcss');
|
|
11
|
-
require('postcss-selector-parser');
|
|
8
|
+
require('tailwindcss-mangle-core');
|
|
12
9
|
require('tailwindcss-patch');
|
|
13
10
|
|
|
14
11
|
var rollup = index.unplugin.rollup;
|
package/dist/rollup.mjs
CHANGED
|
@@ -3,10 +3,7 @@ import 'unplugin';
|
|
|
3
3
|
import 'micromatch';
|
|
4
4
|
import 'fs';
|
|
5
5
|
import 'path';
|
|
6
|
-
import '
|
|
7
|
-
import '@babel/core';
|
|
8
|
-
import 'postcss';
|
|
9
|
-
import 'postcss-selector-parser';
|
|
6
|
+
import 'tailwindcss-mangle-core';
|
|
10
7
|
import 'tailwindcss-patch';
|
|
11
8
|
|
|
12
9
|
var rollup = unplugin.rollup;
|
package/dist/twm-css.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var tailwindcssMangleCore = require('tailwindcss-mangle-core');
|
|
4
|
+
|
|
5
|
+
function cssloader(content) {
|
|
6
|
+
this.cacheable && this.cacheable();
|
|
7
|
+
const opt = this.getOptions();
|
|
8
|
+
if (opt.getCachedClassSet) {
|
|
9
|
+
const runtimeSet = opt.getCachedClassSet();
|
|
10
|
+
return tailwindcssMangleCore.cssHandler(content, {
|
|
11
|
+
classGenerator: opt.classGenerator,
|
|
12
|
+
runtimeSet,
|
|
13
|
+
scene: 'loader'
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return content;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = cssloader;
|
package/dist/twm-css.mjs
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { cssHandler } from 'tailwindcss-mangle-core';
|
|
2
|
+
|
|
3
|
+
function cssloader(content) {
|
|
4
|
+
this.cacheable && this.cacheable();
|
|
5
|
+
const opt = this.getOptions();
|
|
6
|
+
if (opt.getCachedClassSet) {
|
|
7
|
+
const runtimeSet = opt.getCachedClassSet();
|
|
8
|
+
return cssHandler(content, {
|
|
9
|
+
classGenerator: opt.classGenerator,
|
|
10
|
+
runtimeSet,
|
|
11
|
+
scene: 'loader'
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
return content;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { cssloader as default };
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type ClassGenerator from '
|
|
1
|
+
import type { ClassGenerator } from 'tailwindcss-mangle-core';
|
|
2
2
|
export interface IClassGeneratorContextItem {
|
|
3
3
|
name: string;
|
|
4
4
|
usedBy: any[];
|
|
@@ -21,6 +21,9 @@ export interface IHandlerOptions {
|
|
|
21
21
|
runtimeSet: Set<string>;
|
|
22
22
|
classGenerator: ClassGenerator;
|
|
23
23
|
}
|
|
24
|
+
export interface ICssHandlerOptions extends IHandlerOptions {
|
|
25
|
+
scene?: 'loader' | 'process';
|
|
26
|
+
}
|
|
24
27
|
export interface ClassSetOutputOptions {
|
|
25
28
|
filename: string;
|
|
26
29
|
dir?: string;
|
package/dist/vite.js
CHANGED
|
@@ -5,10 +5,7 @@ require('unplugin');
|
|
|
5
5
|
require('micromatch');
|
|
6
6
|
require('fs');
|
|
7
7
|
require('path');
|
|
8
|
-
require('
|
|
9
|
-
require('@babel/core');
|
|
10
|
-
require('postcss');
|
|
11
|
-
require('postcss-selector-parser');
|
|
8
|
+
require('tailwindcss-mangle-core');
|
|
12
9
|
require('tailwindcss-patch');
|
|
13
10
|
|
|
14
11
|
var vite = index.unplugin.vite;
|
package/dist/vite.mjs
CHANGED
|
@@ -3,10 +3,7 @@ import 'unplugin';
|
|
|
3
3
|
import 'micromatch';
|
|
4
4
|
import 'fs';
|
|
5
5
|
import 'path';
|
|
6
|
-
import '
|
|
7
|
-
import '@babel/core';
|
|
8
|
-
import 'postcss';
|
|
9
|
-
import 'postcss-selector-parser';
|
|
6
|
+
import 'tailwindcss-mangle-core';
|
|
10
7
|
import 'tailwindcss-patch';
|
|
11
8
|
|
|
12
9
|
var vite = unplugin.vite;
|
package/dist/webpack.js
CHANGED
|
@@ -5,10 +5,7 @@ require('unplugin');
|
|
|
5
5
|
require('micromatch');
|
|
6
6
|
require('fs');
|
|
7
7
|
require('path');
|
|
8
|
-
require('
|
|
9
|
-
require('@babel/core');
|
|
10
|
-
require('postcss');
|
|
11
|
-
require('postcss-selector-parser');
|
|
8
|
+
require('tailwindcss-mangle-core');
|
|
12
9
|
require('tailwindcss-patch');
|
|
13
10
|
|
|
14
11
|
var webpack = index.unplugin.webpack;
|
package/dist/webpack.mjs
CHANGED
|
@@ -3,10 +3,7 @@ import 'unplugin';
|
|
|
3
3
|
import 'micromatch';
|
|
4
4
|
import 'fs';
|
|
5
5
|
import 'path';
|
|
6
|
-
import '
|
|
7
|
-
import '@babel/core';
|
|
8
|
-
import 'postcss';
|
|
9
|
-
import 'postcss-selector-parser';
|
|
6
|
+
import 'tailwindcss-mangle-core';
|
|
10
7
|
import 'tailwindcss-patch';
|
|
11
8
|
|
|
12
9
|
var webpack = unplugin.webpack;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unplugin-tailwindcss-mangle",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "mangle tailwindcss utilities class plugin. support vite and webpack!",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -60,31 +60,22 @@
|
|
|
60
60
|
"author": "SonOfMagic <qq1324318532@gmail.com>",
|
|
61
61
|
"license": "MIT",
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"@babel/core": "^7.21.4",
|
|
64
|
-
"@babel/types": "^7.21.4",
|
|
65
63
|
"micromatch": "^4.0.5",
|
|
66
|
-
"parse5": "^7.1.2",
|
|
67
|
-
"postcss": "^8.4.23",
|
|
68
|
-
"postcss-selector-parser": "^6.0.11",
|
|
69
|
-
"semver": "^7.5.0",
|
|
70
64
|
"unplugin": "^1.3.1",
|
|
71
|
-
"tailwindcss-
|
|
65
|
+
"tailwindcss-mangle-core": "^1.0.0",
|
|
66
|
+
"tailwindcss-patch": "^1.1.1"
|
|
72
67
|
},
|
|
73
68
|
"publishConfig": {
|
|
74
69
|
"access": "public",
|
|
75
70
|
"registry": "https://registry.npmjs.org/"
|
|
76
71
|
},
|
|
77
72
|
"devDependencies": {
|
|
78
|
-
"@parse5/tools": "^0.1.0",
|
|
79
|
-
"@types/babel__core": "^7.20.0",
|
|
80
|
-
"@types/escodegen": "^0.0.7",
|
|
81
73
|
"@types/micromatch": "^4.0.2",
|
|
82
|
-
"
|
|
83
|
-
"pkg-types": "^1.0.2",
|
|
74
|
+
"simple-functional-loader": "^1.2.1",
|
|
84
75
|
"tailwindcss": "^3.3.2",
|
|
85
76
|
"tslib": "^2.5.0",
|
|
86
|
-
"vite": "^4.3.
|
|
87
|
-
"webpack": "^5.
|
|
77
|
+
"vite": "^4.3.5",
|
|
78
|
+
"webpack": "^5.82.1"
|
|
88
79
|
},
|
|
89
80
|
"homepage": "https://github.com/sonofmagic/tailwindcss-mangle",
|
|
90
81
|
"repository": {
|
|
@@ -96,7 +87,7 @@
|
|
|
96
87
|
"build": "cross-env NODE_ENV=production rollup -c",
|
|
97
88
|
"dev:tsc": "tsc -p tsconfig.json --sourceMap",
|
|
98
89
|
"build:tsc": "tsc -p tsconfig.json",
|
|
99
|
-
"
|
|
90
|
+
"_test": "jest",
|
|
100
91
|
"_prepare": "tw-patch"
|
|
101
92
|
}
|
|
102
93
|
}
|
package/dist/classGenerator.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { IClassGeneratorOptions, IClassGeneratorContextItem, IClassGenerator } from './types';
|
|
2
|
-
declare class ClassGenerator implements IClassGenerator {
|
|
3
|
-
newClassMap: Record<string, IClassGeneratorContextItem>;
|
|
4
|
-
newClassSize: number;
|
|
5
|
-
context: Record<string, any>;
|
|
6
|
-
opts: IClassGeneratorOptions;
|
|
7
|
-
classPrefix: string;
|
|
8
|
-
constructor(opts?: IClassGeneratorOptions);
|
|
9
|
-
defaultClassGenerate(): string;
|
|
10
|
-
ignoreClassName(className: string): boolean;
|
|
11
|
-
includeFilePath(filePath: string): boolean;
|
|
12
|
-
excludeFilePath(filePath: string): boolean;
|
|
13
|
-
isFileIncluded(filePath: string): boolean;
|
|
14
|
-
transformCssClass(className: string): string;
|
|
15
|
-
generateClassName(original: string): IClassGeneratorContextItem;
|
|
16
|
-
}
|
|
17
|
-
export default ClassGenerator;
|
package/dist/css/index.d.ts
DELETED
package/dist/css/plugins.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { IClassGeneratorContextItem } from '@/types';
|
|
2
|
-
import type { PluginCreator } from 'postcss';
|
|
3
|
-
export type PostcssMangleTailwindcssPlugin = PluginCreator<{
|
|
4
|
-
newClassMap: Record<string, IClassGeneratorContextItem>;
|
|
5
|
-
}>;
|
|
6
|
-
declare const postcssMangleTailwindcssPlugin: PostcssMangleTailwindcssPlugin;
|
|
7
|
-
export { postcssMangleTailwindcssPlugin };
|
package/dist/html/index.d.ts
DELETED
package/dist/js/index.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { StringLiteral, TemplateElement } from '@babel/types';
|
|
2
|
-
import { type BabelFileResult } from '@babel/core';
|
|
3
|
-
import type { IHandlerOptions } from '../types';
|
|
4
|
-
export declare function makeRegex(str: string): RegExp;
|
|
5
|
-
export declare function handleValue(str: string, node: StringLiteral | TemplateElement, options: IHandlerOptions): string;
|
|
6
|
-
export declare function jsHandler(rawSource: string, options: IHandlerOptions): BabelFileResult;
|
package/dist/js/split.d.ts
DELETED