@tailwindcss-mangle/core 2.2.2 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -2,32 +2,46 @@
2
2
 
3
3
  const fs = require('node:fs');
4
4
  const node_path = require('node:path');
5
+ const process = require('node:process');
5
6
  const shared = require('@tailwindcss-mangle/shared');
6
7
  const config = require('@tailwindcss-mangle/config');
7
8
  const fastSort = require('fast-sort');
8
- const micromatch = require('micromatch');
9
9
  const postcss = require('postcss');
10
10
  const parser = require('postcss-selector-parser');
11
- const parse5 = require('parse5');
12
- const babel = require('@babel/core');
13
- const helperPluginUtils = require('@babel/helper-plugin-utils');
11
+ const htmlparser2 = require('htmlparser2');
14
12
  const MagicString = require('magic-string');
15
13
  const escape = require('@ast-core/escape');
14
+ const _babelTraverse = require('@babel/traverse');
15
+ const parser$1 = require('@babel/parser');
16
16
 
17
17
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
18
18
 
19
19
  const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
20
- const micromatch__default = /*#__PURE__*/_interopDefaultCompat(micromatch);
20
+ const process__default = /*#__PURE__*/_interopDefaultCompat(process);
21
21
  const postcss__default = /*#__PURE__*/_interopDefaultCompat(postcss);
22
22
  const parser__default = /*#__PURE__*/_interopDefaultCompat(parser);
23
- const babel__default = /*#__PURE__*/_interopDefaultCompat(babel);
24
23
  const MagicString__default = /*#__PURE__*/_interopDefaultCompat(MagicString);
24
+ const _babelTraverse__default = /*#__PURE__*/_interopDefaultCompat(_babelTraverse);
25
25
 
26
- function isObject(value) {
27
- return value !== null && typeof value === "object";
26
+ function isPlainObject(value) {
27
+ if (value === null || typeof value !== "object") {
28
+ return false;
29
+ }
30
+ const prototype = Object.getPrototypeOf(value);
31
+ if (prototype !== null && prototype !== Object.prototype && Object.getPrototypeOf(prototype) !== null) {
32
+ return false;
33
+ }
34
+ if (Symbol.iterator in value) {
35
+ return false;
36
+ }
37
+ if (Symbol.toStringTag in value) {
38
+ return Object.prototype.toString.call(value) === "[object Module]";
39
+ }
40
+ return true;
28
41
  }
42
+
29
43
  function _defu(baseObject, defaults, namespace = ".", merger) {
30
- if (!isObject(defaults)) {
44
+ if (!isPlainObject(defaults)) {
31
45
  return _defu(baseObject, {}, namespace, merger);
32
46
  }
33
47
  const object = Object.assign({}, defaults);
@@ -44,7 +58,7 @@ function _defu(baseObject, defaults, namespace = ".", merger) {
44
58
  }
45
59
  if (Array.isArray(value) && Array.isArray(object[key])) {
46
60
  object[key] = [...value, ...object[key]];
47
- } else if (isObject(value) && isObject(object[key])) {
61
+ } else if (isPlainObject(value) && isPlainObject(object[key])) {
48
62
  object[key] = _defu(
49
63
  value,
50
64
  object[key],
@@ -65,23 +79,12 @@ function createDefu(merger) {
65
79
  }
66
80
  const defu = createDefu();
67
81
 
68
- const { isMatch } = micromatch__default;
69
82
  function escapeStringRegexp(str) {
70
83
  if (typeof str !== "string") {
71
84
  throw new TypeError("Expected a string");
72
85
  }
73
86
  return str.replaceAll(/[$()*+.?[\\\]^{|}]/g, "\\$&").replaceAll("-", "\\x2d");
74
87
  }
75
- function createGlobMatcher(pattern, fallbackValue = false) {
76
- if (pattern === void 0) {
77
- return function() {
78
- return fallbackValue;
79
- };
80
- }
81
- return function(file) {
82
- return isMatch(file, pattern);
83
- };
84
- }
85
88
 
86
89
  var __defProp = Object.defineProperty;
87
90
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -92,8 +95,6 @@ var __publicField = (obj, key, value) => {
92
95
  class Context {
93
96
  constructor() {
94
97
  __publicField(this, "options");
95
- __publicField(this, "includeMatcher");
96
- __publicField(this, "excludeMatcher");
97
98
  __publicField(this, "replaceMap");
98
99
  __publicField(this, "classSet");
99
100
  __publicField(this, "classGenerator");
@@ -103,8 +104,6 @@ class Context {
103
104
  this.options = {};
104
105
  this.classSet = /* @__PURE__ */ new Set();
105
106
  this.replaceMap = /* @__PURE__ */ new Map();
106
- this.includeMatcher = () => true;
107
- this.excludeMatcher = () => false;
108
107
  this.classGenerator = new shared.ClassGenerator();
109
108
  this.preserveFunctionSet = /* @__PURE__ */ new Set();
110
109
  this.preserveClassNamesSet = /* @__PURE__ */ new Set();
@@ -121,17 +120,12 @@ class Context {
121
120
  }
122
121
  mergeOptions(...opts) {
123
122
  this.options = defu(this.options, ...opts);
124
- this.includeMatcher = createGlobMatcher(this.options.include, true);
125
- this.excludeMatcher = createGlobMatcher(this.options.exclude, false);
126
123
  this.classGenerator = new shared.ClassGenerator(this.options.classGenerator);
127
124
  this.preserveFunctionSet = new Set(this.options?.preserveFunction ?? []);
128
125
  this.preserveFunctionRegexs = [...this.preserveFunctionSet.values()].map((x) => {
129
- return new RegExp(escapeStringRegexp(x) + "\\(([^)]*)\\)", "g");
126
+ return new RegExp(`${escapeStringRegexp(x)}\\(([^)]*)\\)`, "g");
130
127
  });
131
128
  }
132
- isInclude(file) {
133
- return this.includeMatcher(file) && !this.excludeMatcher(file);
134
- }
135
129
  currentMangleClassFilter(className) {
136
130
  return (this.options.mangleClassFilter ?? shared.defaultMangleClassFilter)(className);
137
131
  }
@@ -142,6 +136,9 @@ class Context {
142
136
  return this.replaceMap;
143
137
  }
144
138
  addToUsedBy(key, file) {
139
+ if (!file) {
140
+ return;
141
+ }
145
142
  const hit = this.classGenerator.newClassMap[key];
146
143
  if (hit) {
147
144
  hit.usedBy.add(file);
@@ -158,13 +155,19 @@ class Context {
158
155
  async initConfig(opts = {}) {
159
156
  const { cwd, classList: _classList, mangleOptions } = opts;
160
157
  const { config: config$1, cwd: configCwd } = await config.getConfig(cwd);
158
+ if (mangleOptions?.classMapOutput === true) {
159
+ mangleOptions.classMapOutput = config$1.mangle?.classMapOutput;
160
+ if (typeof mangleOptions.classMapOutput === "object") {
161
+ mangleOptions.classMapOutput.enable = true;
162
+ }
163
+ }
161
164
  this.mergeOptions(mangleOptions, config$1?.mangle);
162
165
  if (_classList) {
163
166
  this.loadClassSet(_classList);
164
167
  } else {
165
- let jsonPath = this.options.classListPath ?? node_path.resolve(process.cwd(), config$1?.patch?.output?.filename);
168
+ let jsonPath = this.options.classListPath ?? node_path.resolve(process__default.cwd(), config$1?.patch?.output?.filename);
166
169
  if (!node_path.isAbsolute(jsonPath)) {
167
- jsonPath = node_path.resolve(configCwd ?? process.cwd(), jsonPath);
170
+ jsonPath = node_path.resolve(configCwd ?? process__default.cwd(), jsonPath);
168
171
  }
169
172
  if (jsonPath && fs__default.existsSync(jsonPath)) {
170
173
  const rawClassList = fs__default.readFileSync(jsonPath, "utf8");
@@ -180,11 +183,28 @@ class Context {
180
183
  }
181
184
  return config$1;
182
185
  }
183
- // ["clsx\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"]
186
+ async dump() {
187
+ try {
188
+ const arr = Object.entries(this.classGenerator.newClassMap).map((x) => {
189
+ return {
190
+ before: x[0],
191
+ after: x[1].name,
192
+ usedBy: Array.from(x[1].usedBy)
193
+ };
194
+ });
195
+ if (typeof this.options.classMapOutput === "function") {
196
+ await this.options.classMapOutput(arr);
197
+ } else if (typeof this.options.classMapOutput === "object" && this.options.classMapOutput.enable && this.options.classMapOutput.filename) {
198
+ fs__default.mkdirSync(node_path.dirname(this.options.classMapOutput.filename), { recursive: true });
199
+ fs__default.writeFileSync(this.options.classMapOutput.filename, JSON.stringify(arr, null, 2));
200
+ }
201
+ } catch (error) {
202
+ console.error(`[tailwindcss-mangle]: ${error}`);
203
+ }
204
+ }
184
205
  }
185
206
 
186
207
  const postcssPlugin = "postcss-mangle-tailwindcss-plugin";
187
- const clonedKey = "__tw_mangle_cloned__";
188
208
  function isVueScoped(s) {
189
209
  if (s.parent) {
190
210
  const index = s.parent.nodes.indexOf(s);
@@ -198,283 +218,150 @@ function isVueScoped(s) {
198
218
  return false;
199
219
  }
200
220
  const transformSelectorPostcssPlugin = function(options) {
201
- const { ignoreVueScoped, replaceMap, ctx } = defu(options, {
221
+ const { ignoreVueScoped, ctx, id } = defu(options, {
202
222
  ignoreVueScoped: true
203
223
  });
224
+ const replaceMap = ctx.replaceMap;
204
225
  return {
205
226
  postcssPlugin,
206
- async Rule(rule) {
207
- if (rule[clonedKey]) {
208
- return;
209
- }
210
- await parser__default((selectors) => {
211
- selectors.walkClasses((s) => {
212
- if (s.value && replaceMap && replaceMap.has(s.value)) {
213
- if (ignoreVueScoped && isVueScoped(s)) {
214
- return;
215
- }
216
- const v = replaceMap.get(s.value);
217
- if (v) {
218
- if (ctx.isPreserveClass(s.value)) {
219
- const r = rule.cloneBefore();
220
- r[clonedKey] = true;
227
+ Once(root) {
228
+ root.walkRules((rule) => {
229
+ parser__default((selectors) => {
230
+ selectors.walkClasses((s) => {
231
+ if (s.value && replaceMap && replaceMap.has(s.value)) {
232
+ if (ignoreVueScoped && isVueScoped(s)) {
233
+ return;
234
+ }
235
+ const v = replaceMap.get(s.value);
236
+ if (v) {
237
+ if (ctx.isPreserveClass(s.value)) {
238
+ rule.cloneBefore();
239
+ }
240
+ s.value = v;
221
241
  }
222
- s.value = v;
223
242
  }
224
- }
243
+ });
244
+ }).transformSync(rule, {
245
+ lossless: false,
246
+ updateSelector: true
225
247
  });
226
- }).transform(rule, {
227
- lossless: false,
228
- updateSelector: true
229
248
  });
230
249
  }
231
250
  };
232
251
  };
233
252
  transformSelectorPostcssPlugin.postcss = true;
234
253
 
235
- function cssHandler(rawSource, options) {
254
+ async function cssHandler(rawSource, options) {
236
255
  const acceptedPlugins = [transformSelectorPostcssPlugin(options)];
237
- const { file } = options;
238
- return postcss__default(acceptedPlugins).process(rawSource, {
239
- from: file,
240
- to: file
256
+ const { id } = options;
257
+ const { css: code, map } = await postcss__default(acceptedPlugins).process(rawSource, {
258
+ from: id,
259
+ to: id
241
260
  });
261
+ return {
262
+ code,
263
+ // @ts-ignore
264
+ map
265
+ };
242
266
  }
243
267
 
244
- ({
245
- HTML: parse5.html.NS.HTML,
246
- XML: parse5.html.NS.XML,
247
- MATHML: parse5.html.NS.MATHML,
248
- SVG: parse5.html.NS.SVG,
249
- XLINK: parse5.html.NS.XLINK,
250
- XMLNS: parse5.html.NS.XMLNS
251
- });
252
-
253
- /**
254
- * Determines if a given node is a document or not
255
- * @param {Node} node Node to test
256
- * @return {boolean}
257
- */
258
- function isDocument(node) {
259
- return node.nodeName === '#document';
260
- }
261
- /**
262
- * Determines if a given node is a document fragment or not
263
- * @param {Node} node Node to test
264
- * @return {boolean}
265
- */
266
- function isDocumentFragment(node) {
267
- return node.nodeName === '#document-fragment';
268
- }
269
- /**
270
- * Determines if a given node is a template node or not
271
- * @param {Node} node Node to test
272
- * @return {boolean}
273
- */
274
- function isTemplateNode(node) {
275
- return node.nodeName === 'template';
276
- }
277
- const isElementNode = parse5.defaultTreeAdapter.isElementNode;
278
- const isCommentNode = parse5.defaultTreeAdapter.isCommentNode;
279
- const isDocumentTypeNode = parse5.defaultTreeAdapter.isDocumentTypeNode;
280
- const isTextNode = parse5.defaultTreeAdapter.isTextNode;
281
- /**
282
- * Determines if a given node is a parent or not
283
- * @param {Node} node Node to test
284
- * @return {boolean}
285
- */
286
- function isParentNode(node) {
287
- return (isDocument(node) ||
288
- isDocumentFragment(node) ||
289
- isElementNode(node) ||
290
- isTemplateNode(node));
291
- }
292
-
293
- parse5.defaultTreeAdapter.appendChild;
294
-
295
- /**
296
- * Traverses the tree of a given node
297
- * @param {Node} node Node to traverse
298
- * @param {Visitor} visitor Visitor to apply
299
- * @param {ParentNode=} parent Parent node of the current node
300
- * @return {void}
301
- */
302
- function traverse(node, visitor, parent) {
303
- const shouldVisitChildren = typeof visitor['pre:node'] !== 'function' ||
304
- visitor['pre:node'](node, parent) !== false;
305
- if (shouldVisitChildren && isParentNode(node)) {
306
- for (const child of node.childNodes) {
307
- traverse(child, visitor, node);
308
- }
309
- }
310
- if (typeof visitor.node === 'function') {
311
- visitor.node(node, parent);
312
- }
313
- if (typeof visitor.document === 'function' && isDocument(node)) {
314
- visitor.document(node);
315
- }
316
- if (typeof visitor.documentFragment === 'function' &&
317
- isDocumentFragment(node)) {
318
- visitor.documentFragment(node, parent);
319
- }
320
- if (typeof visitor.element === 'function' && isElementNode(node)) {
321
- visitor.element(node, parent);
322
- }
323
- if (typeof visitor.template === 'function' && isTemplateNode(node)) {
324
- visitor.template(node, parent);
325
- }
326
- if (typeof visitor.comment === 'function' && isCommentNode(node)) {
327
- visitor.comment(node, parent);
328
- }
329
- if (typeof visitor.text === 'function' && isTextNode(node)) {
330
- visitor.text(node, parent);
331
- }
332
- if (typeof visitor.documentType === 'function' && isDocumentTypeNode(node)) {
333
- visitor.documentType(node, parent);
334
- }
335
- }
336
-
337
- function htmlHandler(rawSource, options) {
338
- const { replaceMap, ctx } = options;
339
- const fragment = parse5.parse(rawSource);
340
- traverse(fragment, {
341
- element(node) {
342
- const attribute = node.attrs.find((x) => x.name === "class");
343
- if (attribute) {
344
- const array = shared.splitCode(attribute.value, {
268
+ function htmlHandler(raw, options) {
269
+ const { ctx, id } = options;
270
+ const { replaceMap, classGenerator } = ctx;
271
+ const ms = typeof raw === "string" ? new MagicString__default(raw) : raw;
272
+ const parser = new htmlparser2.Parser({
273
+ onattribute(name, value) {
274
+ if (name === "class") {
275
+ let needUpdate = false;
276
+ const arr = shared.splitCode(value, {
345
277
  splitQuote: false
346
278
  });
347
- for (const v of array) {
279
+ let rawValue = value;
280
+ for (const v of arr) {
348
281
  if (replaceMap.has(v)) {
349
- attribute.value = attribute.value.replace(shared.makeRegex(v), ctx.classGenerator.generateClassName(v).name);
282
+ const gen = classGenerator.generateClassName(v);
283
+ rawValue = rawValue.replace(shared.makeRegex(v), gen.name);
284
+ ctx.addToUsedBy(v, id);
285
+ needUpdate = true;
350
286
  }
351
287
  }
288
+ needUpdate && ms.update(parser.startIndex + name.length + 2, parser.endIndex - 1, rawValue);
352
289
  }
353
290
  }
354
291
  });
355
- return parse5.serialize(fragment);
292
+ parser.write(ms.original);
293
+ parser.end();
294
+ return {
295
+ code: ms.toString()
296
+ };
356
297
  }
357
298
 
358
- const isProd = () => process.env.NODE_ENV === "production";
359
-
360
- function between(x, min, max, included = false) {
361
- if (typeof x !== "number") {
362
- return false;
363
- }
364
- return included ? x >= min && x <= max : x > min && x < max;
299
+ function _interopDefaultCompat$1(e) {
300
+ return e && typeof e === "object" && "default" in e ? e.default : e;
365
301
  }
302
+ const traverse = _interopDefaultCompat$1(_babelTraverse__default);
366
303
 
367
- function handleValue$1(options) {
368
- const { ctx, id, path, magicString, raw, replaceMap, offset = 0, escape: escape$1 = false, markedArray } = options;
369
- const node = path.node;
370
- let value = raw;
371
- for (const [s, e] of markedArray) {
372
- if (between(node.start, s, e) || between(node.end, s, e)) {
373
- return;
374
- }
375
- }
376
- const arr = fastSort.sort(shared.splitCode(value)).desc((x) => x.length);
377
- for (const str of arr) {
378
- if (replaceMap.has(str)) {
379
- ctx.addToUsedBy(str, id);
380
- const v = replaceMap.get(str);
381
- if (v) {
382
- value = value.replaceAll(str, v);
304
+ function handleValue(raw, node, options, ms, offset, escape$1) {
305
+ const { ctx, splitQuote = true, id } = options;
306
+ const { replaceMap, classGenerator: clsGen } = ctx;
307
+ const array = shared.splitCode(raw, {
308
+ splitQuote
309
+ });
310
+ let rawString = raw;
311
+ let needUpdate = false;
312
+ for (const v of array) {
313
+ if (replaceMap.has(v)) {
314
+ let ignoreFlag = false;
315
+ if (Array.isArray(node.leadingComments)) {
316
+ ignoreFlag = node.leadingComments.findIndex((x) => x.value.includes("tw-mangle") && x.value.includes("ignore")) > -1;
317
+ }
318
+ if (!ignoreFlag) {
319
+ const gen = clsGen.generateClassName(v);
320
+ rawString = rawString.replace(shared.makeRegex(v), gen.name);
321
+ ctx.addToUsedBy(v, id);
322
+ needUpdate = true;
383
323
  }
384
324
  }
385
325
  }
386
- if (typeof node.start === "number" && typeof node.end === "number" && value) {
326
+ if (needUpdate && typeof node.start === "number" && typeof node.end === "number") {
387
327
  const start = node.start + offset;
388
328
  const end = node.end - offset;
389
- if (start < end) {
390
- magicString.update(start, end, escape$1 ? escape.jsStringEscape(value) : value);
329
+ if (start < end && raw !== rawString) {
330
+ ms.update(start, end, escape$1 ? escape.jsStringEscape(rawString) : rawString);
391
331
  }
392
332
  }
333
+ return rawString;
393
334
  }
394
- const JsPlugin = helperPluginUtils.declare((api, options) => {
395
- api.assertVersion(7);
396
- const { magicString, replaceMap, id, ctx, markedArray } = options;
397
- return {
398
- visitor: {
399
- StringLiteral: {
400
- exit(p) {
401
- const opts = {
402
- ctx,
403
- id,
404
- magicString,
405
- path: p,
406
- raw: p.node.value,
407
- replaceMap,
408
- offset: 1,
409
- escape: true,
410
- markedArray
411
- };
412
- handleValue$1(opts);
413
- }
414
- },
415
- TemplateElement: {
416
- exit(p) {
417
- const opts = {
418
- ctx,
419
- id,
420
- magicString,
421
- path: p,
422
- raw: p.node.value.raw,
423
- replaceMap,
424
- offset: 0,
425
- escape: false,
426
- markedArray
427
- };
428
- handleValue$1(opts);
429
- }
430
- }
431
- }
432
- };
433
- });
434
- function transformSync(ast, code, plugins, filename) {
435
- babel__default.transformFromAstSync(ast, code, {
436
- presets: loadPresets(),
437
- plugins,
438
- filename
439
- });
440
- }
441
- function loadPresets() {
442
- return [
443
- [
444
- require("@babel/preset-typescript"),
445
- {
446
- allExtensions: true,
447
- isTSX: true
448
- }
449
- ]
450
- ];
451
- }
452
- function preProcessJs(options) {
453
- const { code, replaceMap, id, ctx } = options;
454
- const magicString = typeof code === "string" ? new MagicString__default(code) : code;
335
+ function jsHandler(rawSource, options) {
336
+ const ms = typeof rawSource === "string" ? new MagicString__default(rawSource) : rawSource;
455
337
  let ast;
456
338
  try {
457
- const file = babel__default.parseSync(magicString.original, {
458
- sourceType: "unambiguous",
459
- presets: loadPresets()
339
+ ast = parser$1.parse(ms.original, {
340
+ sourceType: "unambiguous"
460
341
  });
461
- if (file) {
462
- ast = file;
463
- } else {
464
- return code.toString();
465
- }
466
- } catch {
467
- return code.toString();
342
+ } catch (error) {
343
+ return {
344
+ code: ms.original
345
+ };
468
346
  }
469
- const markedArray = [];
470
- babel__default.traverse(ast, {
347
+ const { ctx } = options;
348
+ traverse(ast, {
349
+ StringLiteral: {
350
+ enter(p) {
351
+ const n = p.node;
352
+ handleValue(n.value, n, options, ms, 1, true);
353
+ }
354
+ },
355
+ TemplateElement: {
356
+ enter(p) {
357
+ const n = p.node;
358
+ handleValue(n.value.raw, n, options, ms, 0, false);
359
+ }
360
+ },
471
361
  CallExpression: {
472
362
  enter(p) {
473
363
  const callee = p.get("callee");
474
364
  if (callee.isIdentifier() && ctx.isPreserveFunction(callee.node.name)) {
475
- if (p.node.start && p.node.end) {
476
- markedArray.push([p.node.start, p.node.end]);
477
- }
478
365
  p.traverse({
479
366
  StringLiteral: {
480
367
  enter(path) {
@@ -482,7 +369,7 @@ function preProcessJs(options) {
482
369
  const value = node.value;
483
370
  const arr = fastSort.sort(shared.splitCode(value)).desc((x) => x.length);
484
371
  for (const str of arr) {
485
- if (replaceMap.has(str)) {
372
+ if (ctx.replaceMap.has(str)) {
486
373
  ctx.addPreserveClass(str);
487
374
  }
488
375
  }
@@ -494,7 +381,7 @@ function preProcessJs(options) {
494
381
  const value = node.value.raw;
495
382
  const arr = fastSort.sort(shared.splitCode(value)).desc((x) => x.length);
496
383
  for (const str of arr) {
497
- if (replaceMap.has(str)) {
384
+ if (ctx.replaceMap.has(str)) {
498
385
  ctx.addPreserveClass(str);
499
386
  }
500
387
  }
@@ -505,158 +392,12 @@ function preProcessJs(options) {
505
392
  }
506
393
  }
507
394
  });
508
- transformSync(
509
- ast,
510
- magicString.original,
511
- [
512
- [
513
- JsPlugin,
514
- {
515
- magicString,
516
- replaceMap,
517
- id,
518
- ctx,
519
- markedArray
520
- }
521
- ]
522
- ],
523
- id
524
- );
525
- return magicString.toString();
526
- }
527
- function preProcessRawCode(options) {
528
- const { code, replaceMap, ctx } = options;
529
- const magicString = typeof code === "string" ? new MagicString__default(code) : code;
530
- const markArr = [];
531
- for (const regex of ctx.preserveFunctionRegexs) {
532
- const allArr = [];
533
- let arr = null;
534
- while ((arr = regex.exec(magicString.original)) !== null) {
535
- allArr.push(arr);
536
- markArr.push([arr.index, arr.index + arr[0].length]);
537
- }
538
- for (const regExpMatch of allArr) {
539
- let ast;
540
- try {
541
- ast = babel__default.parseSync(regExpMatch[0], {
542
- sourceType: "unambiguous"
543
- });
544
- ast && babel__default.traverse(ast, {
545
- StringLiteral: {
546
- enter(p) {
547
- const arr2 = fastSort.sort(shared.splitCode(p.node.value)).desc((x) => x.length);
548
- for (const v of arr2) {
549
- if (replaceMap.has(v)) {
550
- ctx.addPreserveClass(v);
551
- }
552
- }
553
- }
554
- },
555
- TemplateElement: {
556
- enter(p) {
557
- const arr2 = fastSort.sort(shared.splitCode(p.node.value.raw)).desc((x) => x.length);
558
- for (const v of arr2) {
559
- if (replaceMap.has(v)) {
560
- ctx.addPreserveClass(v);
561
- }
562
- }
563
- }
564
- }
565
- });
566
- } catch {
567
- continue;
568
- }
569
- }
570
- }
571
- for (const [key, value] of replaceMap) {
572
- const regex = new RegExp(escapeStringRegexp(key), "g");
573
- let arr = null;
574
- while ((arr = regex.exec(magicString.original)) !== null) {
575
- const start = arr.index;
576
- const end = arr.index + arr[0].length;
577
- let shouldUpdate = true;
578
- for (const [ps, pe] of markArr) {
579
- if (between(start, ps, pe) || between(end, ps, pe)) {
580
- shouldUpdate = false;
581
- break;
582
- }
583
- }
584
- if (shouldUpdate) {
585
- magicString.update(start, end, value);
586
- markArr.push([start, end]);
587
- }
588
- }
589
- }
590
- return magicString.toString();
591
- }
592
-
593
- function handleValue(raw, node, options) {
594
- const { replaceMap, ctx, splitQuote = true } = options;
595
- const clsGen = ctx.classGenerator;
596
- const array = shared.splitCode(raw, {
597
- splitQuote
598
- });
599
- let rawString = raw;
600
- for (const v of array) {
601
- if (replaceMap.has(v)) {
602
- let ignoreFlag = false;
603
- if (Array.isArray(node.leadingComments)) {
604
- ignoreFlag = node.leadingComments.findIndex((x) => x.value.includes("tw-mangle") && x.value.includes("ignore")) > -1;
605
- }
606
- if (!ignoreFlag) {
607
- rawString = rawString.replace(shared.makeRegex(v), clsGen.generateClassName(v).name);
608
- }
395
+ return {
396
+ code: ms.toString(),
397
+ get map() {
398
+ return ms.generateMap();
609
399
  }
610
- }
611
- return rawString;
612
- }
613
- function jsHandler(rawSource, options) {
614
- const result = babel.transformSync(rawSource, {
615
- babelrc: false,
616
- ast: true,
617
- plugins: [
618
- () => {
619
- return {
620
- visitor: {
621
- StringLiteral: {
622
- enter(p) {
623
- const n = p.node;
624
- n.value = handleValue(n.value, n, options);
625
- }
626
- },
627
- TemplateElement: {
628
- enter(p) {
629
- const n = p.node;
630
- n.value.raw = handleValue(n.value.raw, n, options);
631
- }
632
- },
633
- CallExpression: {
634
- enter(p) {
635
- const calleePath = p.get("callee");
636
- if (calleePath.isIdentifier() && calleePath.node.name === "eval") {
637
- p.traverse({
638
- StringLiteral: {
639
- enter(s) {
640
- const res = jsHandler(s.node.value, options);
641
- if (res.code) {
642
- s.node.value = res.code;
643
- }
644
- }
645
- }
646
- });
647
- }
648
- }
649
- }
650
- // noScope: true
651
- }
652
- };
653
- }
654
- ],
655
- minified: options.minified ?? isProd(),
656
- sourceMaps: false,
657
- configFile: false
658
- });
659
- return result;
400
+ };
660
401
  }
661
402
 
662
403
  exports.ClassGenerator = shared.ClassGenerator;
@@ -665,5 +406,3 @@ exports.cssHandler = cssHandler;
665
406
  exports.handleValue = handleValue;
666
407
  exports.htmlHandler = htmlHandler;
667
408
  exports.jsHandler = jsHandler;
668
- exports.preProcessJs = preProcessJs;
669
- exports.preProcessRawCode = preProcessRawCode;