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