unplugin-tailwindcss-mangle 0.1.3 → 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 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
@@ -2,16 +2,10 @@
2
2
 
3
3
  var index = require('./index.js');
4
4
  require('unplugin');
5
- require('./index-2edd594b.js');
6
- require('@babel/types');
7
- require('@babel/core');
8
5
  require('micromatch');
9
6
  require('fs');
10
7
  require('path');
11
- require('parse5');
12
- require('./index-c8e1bdc5.js');
13
- require('postcss');
14
- require('postcss-selector-parser');
8
+ require('tailwindcss-mangle-core');
15
9
  require('tailwindcss-patch');
16
10
 
17
11
  var esbuild = index.unplugin.esbuild;
package/dist/esbuild.mjs CHANGED
@@ -1,15 +1,9 @@
1
1
  import { unplugin } from './index.mjs';
2
2
  import 'unplugin';
3
- import './index-92f879d3.mjs';
4
- import '@babel/types';
5
- import '@babel/core';
6
3
  import 'micromatch';
7
4
  import 'fs';
8
5
  import 'path';
9
- import 'parse5';
10
- import './index-b715a07f.mjs';
11
- import 'postcss';
12
- import 'postcss-selector-parser';
6
+ import 'tailwindcss-mangle-core';
13
7
  import 'tailwindcss-patch';
14
8
 
15
9
  var esbuild = unplugin.esbuild;
package/dist/index.js CHANGED
@@ -3,238 +3,121 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var unplugin$1 = require('unplugin');
6
- var index = require('./index-2edd594b.js');
7
- var parse5 = require('parse5');
8
- var index$1 = require('./index-c8e1bdc5.js');
9
- var path = require('path');
6
+ var micromatch = require('micromatch');
10
7
  var fs = require('fs');
8
+ var path = require('path');
9
+ var tailwindcssMangleCore = require('tailwindcss-mangle-core');
11
10
  var tailwindcssPatch = require('tailwindcss-patch');
12
- require('@babel/types');
13
- require('@babel/core');
14
- require('micromatch');
15
- require('postcss');
16
- require('postcss-selector-parser');
17
11
 
18
12
  function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
19
13
 
20
- var path__default = /*#__PURE__*/_interopDefault(path);
14
+ var micromatch__default = /*#__PURE__*/_interopDefault(micromatch);
21
15
  var fs__default = /*#__PURE__*/_interopDefault(fs);
16
+ var path__default = /*#__PURE__*/_interopDefault(path);
22
17
 
23
- ({
24
- HTML: parse5.html.NS.HTML,
25
- XML: parse5.html.NS.XML,
26
- MATHML: parse5.html.NS.MATHML,
27
- SVG: parse5.html.NS.SVG,
28
- XLINK: parse5.html.NS.XLINK,
29
- XMLNS: parse5.html.NS.XMLNS
30
- });
31
-
32
- /**
33
- * Determines if a given node is a document or not
34
- * @param {Node} node Node to test
35
- * @return {boolean}
36
- */
37
- function isDocument(node) {
38
- return node.nodeName === '#document';
39
- }
40
- /**
41
- * Determines if a given node is a document fragment or not
42
- * @param {Node} node Node to test
43
- * @return {boolean}
44
- */
45
- function isDocumentFragment(node) {
46
- return node.nodeName === '#document-fragment';
47
- }
48
- /**
49
- * Determines if a given node is a template node or not
50
- * @param {Node} node Node to test
51
- * @return {boolean}
52
- */
53
- function isTemplateNode(node) {
54
- return node.nodeName === 'template';
55
- }
56
- const isElementNode = parse5.defaultTreeAdapter.isElementNode;
57
- const isCommentNode = parse5.defaultTreeAdapter.isCommentNode;
58
- const isDocumentTypeNode = parse5.defaultTreeAdapter.isDocumentTypeNode;
59
- const isTextNode = parse5.defaultTreeAdapter.isTextNode;
60
- /**
61
- * Determines if a given node is a parent or not
62
- * @param {Node} node Node to test
63
- * @return {boolean}
64
- */
65
- function isParentNode(node) {
66
- return (isDocument(node) ||
67
- isDocumentFragment(node) ||
68
- isElementNode(node) ||
69
- isTemplateNode(node));
70
- }
71
-
72
- parse5.defaultTreeAdapter.appendChild;
18
+ const pluginName = 'unplugin-tailwindcss-mangle';
73
19
 
74
- /**
75
- * Traverses the tree of a given node
76
- * @param {Node} node Node to traverse
77
- * @param {Visitor} visitor Visitor to apply
78
- * @param {ParentNode=} parent Parent node of the current node
79
- * @return {void}
80
- */
81
- function traverse(node, visitor, parent) {
82
- const shouldVisitChildren = typeof visitor['pre:node'] !== 'function' ||
83
- visitor['pre:node'](node, parent) !== false;
84
- if (shouldVisitChildren && isParentNode(node)) {
85
- for (const child of node.childNodes) {
86
- traverse(child, visitor, node);
87
- }
88
- }
89
- if (typeof visitor.node === 'function') {
90
- visitor.node(node, parent);
20
+ const { isMatch } = micromatch__default["default"];
21
+ const isMangleClass = (className) => {
22
+ return /[-:]/.test(className);
23
+ };
24
+ function groupBy(arr, cb) {
25
+ if (!Array.isArray(arr)) {
26
+ throw new Error('expected an array for first argument');
91
27
  }
92
- if (typeof visitor.document === 'function' && isDocument(node)) {
93
- visitor.document(node);
28
+ if (typeof cb !== 'function') {
29
+ throw new Error('expected a function for second argument');
94
30
  }
95
- if (typeof visitor.documentFragment === 'function' &&
96
- isDocumentFragment(node)) {
97
- visitor.documentFragment(node, parent);
98
- }
99
- if (typeof visitor.element === 'function' && isElementNode(node)) {
100
- visitor.element(node, parent);
101
- }
102
- if (typeof visitor.template === 'function' && isTemplateNode(node)) {
103
- visitor.template(node, parent);
104
- }
105
- if (typeof visitor.comment === 'function' && isCommentNode(node)) {
106
- visitor.comment(node, parent);
107
- }
108
- if (typeof visitor.text === 'function' && isTextNode(node)) {
109
- visitor.text(node, parent);
110
- }
111
- if (typeof visitor.documentType === 'function' && isDocumentTypeNode(node)) {
112
- visitor.documentType(node, parent);
113
- }
114
- }
115
-
116
- function htmlHandler(rawSource, options) {
117
- const { runtimeSet, classGenerator } = options;
118
- const fragment = parse5.parse(rawSource);
119
- traverse(fragment, {
120
- element(node, parent) {
121
- const attr = node.attrs.find((x) => x.name === 'class');
122
- if (attr) {
123
- const arr = attr.value.split(/\s/).filter((x) => x);
124
- attr.value = arr
125
- .map((x) => {
126
- if (runtimeSet.has(x)) {
127
- return classGenerator.generateClassName(x).name;
128
- }
129
- return x;
130
- })
131
- .join(' ');
132
- }
31
+ const result = {};
32
+ for (let i = 0; i < arr.length; i++) {
33
+ const item = arr[i];
34
+ const bucketCategory = cb(item);
35
+ const bucket = result[bucketCategory];
36
+ if (!Array.isArray(bucket)) {
37
+ result[bucketCategory] = [item];
133
38
  }
134
- });
135
- return parse5.serialize(fragment);
136
- }
137
-
138
- class ClassGenerator {
139
- newClassMap;
140
- newClassSize;
141
- context;
142
- opts;
143
- classPrefix;
144
- constructor(opts = {}) {
145
- this.newClassMap = {};
146
- this.newClassSize = 0;
147
- this.context = {};
148
- this.opts = opts;
149
- this.classPrefix = opts.classPrefix ?? 'tw-';
150
- }
151
- defaultClassGenerate() {
152
- const chars = [];
153
- let rest = (this.newClassSize - (this.newClassSize % index.acceptChars.length)) / index.acceptChars.length;
154
- if (rest > 0) {
155
- while (true) {
156
- rest -= 1;
157
- const m = rest % index.acceptChars.length;
158
- const c = index.acceptChars[m];
159
- chars.push(c);
160
- rest -= m;
161
- if (rest === 0) {
162
- break;
163
- }
164
- rest /= index.acceptChars.length;
165
- }
39
+ else {
40
+ result[bucketCategory].push(item);
166
41
  }
167
- const prefixIndex = this.newClassSize % index.acceptChars.length;
168
- const newClassName = `${this.classPrefix}${index.acceptChars[prefixIndex]}${chars.join('')}`;
169
- return newClassName;
170
42
  }
171
- ignoreClassName(className) {
172
- return index.regExpTest(this.opts.ignoreClass, className);
43
+ return result;
44
+ }
45
+ function getGroupedEntries(entries, options = {
46
+ cssMatcher(file) {
47
+ return /\.css$/.test(file);
48
+ },
49
+ htmlMatcher(file) {
50
+ return /\.html?$/.test(file);
51
+ },
52
+ jsMatcher(file) {
53
+ return /\.[cm]?js$/.test(file);
173
54
  }
174
- includeFilePath(filePath) {
175
- const { include } = this.opts;
176
- if (Array.isArray(include)) {
177
- return index.regExpTest(include, filePath);
55
+ }) {
56
+ const { cssMatcher, htmlMatcher, jsMatcher } = options;
57
+ const groupedEntries = groupBy(entries, ([file]) => {
58
+ if (cssMatcher(file)) {
59
+ return 'css';
178
60
  }
179
- else {
180
- return true;
61
+ else if (htmlMatcher(file)) {
62
+ return 'html';
181
63
  }
182
- }
183
- excludeFilePath(filePath) {
184
- const { exclude } = this.opts;
185
- if (Array.isArray(exclude)) {
186
- return index.regExpTest(exclude, filePath);
64
+ else if (jsMatcher(file)) {
65
+ return 'js';
187
66
  }
188
67
  else {
189
- return false;
68
+ return 'other';
190
69
  }
70
+ });
71
+ if (!groupedEntries.css) {
72
+ groupedEntries.css = [];
191
73
  }
192
- isFileIncluded(filePath) {
193
- return this.includeFilePath(filePath) && !this.excludeFilePath(filePath);
74
+ if (!groupedEntries.html) {
75
+ groupedEntries.html = [];
194
76
  }
195
- transformCssClass(className) {
196
- const key = index.stripEscapeSequence(className);
197
- const cn = this.newClassMap[key];
198
- if (cn)
199
- return cn.name;
200
- return className;
77
+ if (!groupedEntries.js) {
78
+ groupedEntries.js = [];
201
79
  }
202
- generateClassName(original) {
203
- const opts = this.opts;
204
- original = index.stripEscapeSequence(original);
205
- const cn = this.newClassMap[original];
206
- if (cn)
207
- return cn;
208
- let newClassName;
209
- if (opts.customGenerate && typeof opts.customGenerate === 'function') {
210
- newClassName = opts.customGenerate(original, opts, this.context);
211
- }
212
- if (!newClassName) {
213
- newClassName = this.defaultClassGenerate();
214
- }
215
- if (opts.reserveClassName && index.regExpTest(opts.reserveClassName, newClassName)) {
216
- if (opts.log) {
217
- console.log(`The class name has been reserved. ${newClassName}`);
218
- }
219
- this.newClassSize++;
220
- return this.generateClassName(original);
221
- }
222
- if (opts.log) {
223
- console.log(`Minify class name from ${original} to ${newClassName}`);
224
- }
225
- const newClass = {
226
- name: newClassName,
227
- usedBy: []
80
+ if (!groupedEntries.other) {
81
+ groupedEntries.other = [];
82
+ }
83
+ return groupedEntries;
84
+ }
85
+ function createGlobMatcher(pattern, fallbackValue = false) {
86
+ if (typeof pattern === 'undefined') {
87
+ return function (file) {
88
+ return fallbackValue;
228
89
  };
229
- this.newClassMap[original] = newClass;
230
- this.newClassSize++;
231
- return newClass;
90
+ }
91
+ return function (file) {
92
+ return isMatch(file, pattern);
93
+ };
94
+ }
95
+ function getCacheDir(basedir = process.cwd()) {
96
+ return path__default["default"].resolve(basedir, 'node_modules/.cache', pluginName);
97
+ }
98
+ function mkCacheDirectory(cwd = process.cwd()) {
99
+ const cacheDirectory = getCacheDir(cwd);
100
+ const exists = fs__default["default"].existsSync(cacheDirectory);
101
+ if (!exists) {
102
+ fs__default["default"].mkdirSync(cacheDirectory, {
103
+ recursive: true
104
+ });
105
+ }
106
+ return cacheDirectory;
107
+ }
108
+ function cacheDump(filename, data, basedir) {
109
+ try {
110
+ const dir = mkCacheDirectory(basedir);
111
+ fs__default["default"].writeFileSync(path__default["default"].resolve(dir, filename), JSON.stringify(Array.from(data), null, 2), 'utf-8');
112
+ }
113
+ catch (error) {
114
+ console.log(error);
232
115
  }
233
116
  }
234
117
 
235
118
  function getOptions(options = {}) {
236
- const includeMatcher = index.createGlobMatcher(options.include, true);
237
- const excludeMatcher = index.createGlobMatcher(options.exclude, false);
119
+ const includeMatcher = createGlobMatcher(options.include, true);
120
+ const excludeMatcher = createGlobMatcher(options.exclude, false);
238
121
  function isInclude(file) {
239
122
  return includeMatcher(file) && !excludeMatcher(file);
240
123
  }
@@ -253,20 +136,20 @@ function getOptions(options = {}) {
253
136
  if (typeof options.classMapOutput === 'object') {
254
137
  Object.assign(classMapOutputOptions, options.classMapOutput);
255
138
  }
256
- const classGenerator = new ClassGenerator(options.classGenerator);
139
+ const classGenerator = new tailwindcssMangleCore.ClassGenerator(options.classGenerator);
257
140
  function getCachedClassSet() {
258
141
  const set = twPatcher.getClassSet();
259
142
  const isOutput = set.size && options.classSetOutput;
260
143
  if (isOutput && classSetOutputOptions.type === 'all') {
261
- index.cacheDump(classSetOutputOptions.filename, set, classSetOutputOptions.dir);
144
+ cacheDump(classSetOutputOptions.filename, set, classSetOutputOptions.dir);
262
145
  }
263
146
  set.forEach((c) => {
264
- if (!index.isMangleClass(c)) {
147
+ if (!isMangleClass(c)) {
265
148
  set.delete(c);
266
149
  }
267
150
  });
268
151
  if (isOutput && classSetOutputOptions.type === 'partial') {
269
- index.cacheDump(classSetOutputOptions.filename, set, classSetOutputOptions.dir);
152
+ cacheDump(classSetOutputOptions.filename, set, classSetOutputOptions.dir);
270
153
  }
271
154
  classSet = set;
272
155
  return classSet;
@@ -287,7 +170,7 @@ const outputCachedMap = new Map();
287
170
  const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
288
171
  const { classGenerator, getCachedClassSet, isInclude, classMapOutputOptions } = getOptions(options);
289
172
  return {
290
- name: index.pluginName,
173
+ name: pluginName,
291
174
  enforce: 'post',
292
175
  vite: {
293
176
  generateBundle: {
@@ -296,12 +179,12 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
296
179
  if (!runtimeSet.size) {
297
180
  return;
298
181
  }
299
- const groupedEntries = index.getGroupedEntries(Object.entries(bundle));
182
+ const groupedEntries = getGroupedEntries(Object.entries(bundle));
300
183
  if (Array.isArray(groupedEntries.html) && groupedEntries.html.length) {
301
184
  for (let i = 0; i < groupedEntries.html.length; i++) {
302
185
  const [file, asset] = groupedEntries.html[i];
303
186
  if (isInclude(file)) {
304
- asset.source = htmlHandler(asset.source.toString(), {
187
+ asset.source = tailwindcssMangleCore.htmlHandler(asset.source.toString(), {
305
188
  classGenerator,
306
189
  runtimeSet
307
190
  });
@@ -312,7 +195,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
312
195
  for (let i = 0; i < groupedEntries.js.length; i++) {
313
196
  const [file, chunk] = groupedEntries.js[i];
314
197
  if (isInclude(file)) {
315
- const code = index.jsHandler(chunk.code, {
198
+ const code = tailwindcssMangleCore.jsHandler(chunk.code, {
316
199
  runtimeSet,
317
200
  classGenerator
318
201
  }).code;
@@ -326,7 +209,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
326
209
  for (let i = 0; i < groupedEntries.css.length; i++) {
327
210
  const [file, css] = groupedEntries.css[i];
328
211
  if (isInclude(file)) {
329
- css.source = index$1.cssHandler(css.source.toString(), {
212
+ css.source = tailwindcssMangleCore.cssHandler(css.source.toString(), {
330
213
  classGenerator,
331
214
  runtimeSet
332
215
  });
@@ -356,8 +239,8 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
356
239
  }
357
240
  }
358
241
  const twmCssloader = path__default["default"].resolve(__dirname, 'twm-css.js');
359
- compiler.hooks.compilation.tap(index.pluginName, (compilation) => {
360
- NormalModule.getCompilationHooks(compilation).loader.tap(index.pluginName, (loaderContext, module) => {
242
+ compiler.hooks.compilation.tap(pluginName, (compilation) => {
243
+ NormalModule.getCompilationHooks(compilation).loader.tap(pluginName, (loaderContext, module) => {
361
244
  const idx = module.loaders.findIndex((x) => x.loader.includes('css-loader'));
362
245
  if (idx > -1) {
363
246
  module.loaders.splice(idx + 1, 0, {
@@ -372,11 +255,11 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
372
255
  }
373
256
  });
374
257
  compilation.hooks.processAssets.tap({
375
- name: index.pluginName,
258
+ name: pluginName,
376
259
  stage: Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE
377
260
  }, (assets) => {
378
261
  const runtimeSet = getCachedClassSet();
379
- const groupedEntries = index.getGroupedEntries(Object.entries(assets));
262
+ const groupedEntries = getGroupedEntries(Object.entries(assets));
380
263
  if (!runtimeSet.size) {
381
264
  const css = new Map();
382
265
  const html = new Map();
@@ -403,7 +286,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
403
286
  for (let i = 0; i < groupedEntries.html.length; i++) {
404
287
  const [file, asset] = groupedEntries.html[i];
405
288
  if (isInclude(file)) {
406
- const html = htmlHandler(asset.source().toString(), {
289
+ const html = tailwindcssMangleCore.htmlHandler(asset.source().toString(), {
407
290
  classGenerator,
408
291
  runtimeSet
409
292
  });
@@ -416,7 +299,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
416
299
  for (let i = 0; i < groupedEntries.js.length; i++) {
417
300
  const [file, chunk] = groupedEntries.js[i];
418
301
  if (isInclude(file)) {
419
- const code = index.jsHandler(chunk.source().toString(), {
302
+ const code = tailwindcssMangleCore.jsHandler(chunk.source().toString(), {
420
303
  runtimeSet,
421
304
  classGenerator
422
305
  }).code;
@@ -431,7 +314,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
431
314
  for (let i = 0; i < groupedEntries.css.length; i++) {
432
315
  const [file, css] = groupedEntries.css[i];
433
316
  if (isInclude(file)) {
434
- const newCss = index$1.cssHandler(css.source().toString(), {
317
+ const newCss = tailwindcssMangleCore.cssHandler(css.source().toString(), {
435
318
  classGenerator,
436
319
  runtimeSet
437
320
  });
@@ -444,7 +327,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
444
327
  if (html.size) {
445
328
  html.forEach((asset, file) => {
446
329
  if (isInclude(file)) {
447
- const html = htmlHandler(asset.source().toString(), {
330
+ const html = tailwindcssMangleCore.htmlHandler(asset.source().toString(), {
448
331
  classGenerator,
449
332
  runtimeSet
450
333
  });
@@ -457,7 +340,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
457
340
  js.forEach((chunk, file) => {
458
341
  if (isInclude(file)) {
459
342
  const rawCode = chunk.source().toString();
460
- const code = index.jsHandler(rawCode, {
343
+ const code = tailwindcssMangleCore.jsHandler(rawCode, {
461
344
  runtimeSet,
462
345
  classGenerator
463
346
  }).code;
@@ -471,7 +354,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
471
354
  if (css.size) {
472
355
  css.forEach((style, file) => {
473
356
  if (isInclude(file)) {
474
- const newCss = index$1.cssHandler(style.source().toString(), {
357
+ const newCss = tailwindcssMangleCore.cssHandler(style.source().toString(), {
475
358
  classGenerator,
476
359
  runtimeSet
477
360
  });
@@ -487,7 +370,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
487
370
  writeBundle() {
488
371
  const entries = Object.entries(classGenerator.newClassMap);
489
372
  if (entries.length && classMapOutputOptions) {
490
- index.cacheDump(classMapOutputOptions.filename, entries.map((x) => {
373
+ cacheDump(classMapOutputOptions.filename, entries.map((x) => {
491
374
  return [x[0], x[1].name];
492
375
  }), classMapOutputOptions.dir);
493
376
  }