weapp-tailwindcss 4.10.2 → 4.11.0-alpha.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.
Files changed (62) hide show
  1. package/dist/{chunk-3XVUGMTY.mjs → chunk-2LH6PZH3.mjs} +8 -4
  2. package/dist/{chunk-3WUHHFLF.mjs → chunk-35EI5JMK.mjs} +4 -2
  3. package/dist/{chunk-HJVZ4TO3.js → chunk-7XQXBJL6.js} +10 -9
  4. package/dist/{chunk-5U24PLVV.js → chunk-ACTJYB33.js} +4 -2
  5. package/dist/{chunk-ACNOEKQI.mjs → chunk-CLNUBO3Q.mjs} +6 -5
  6. package/dist/{chunk-HT76VHOV.mjs → chunk-DOH7FULQ.mjs} +1 -1
  7. package/dist/{chunk-BZCCVPSU.mjs → chunk-EOK3NZVC.mjs} +2 -2
  8. package/dist/{chunk-3R7FDZJL.js → chunk-FKUPQQYX.js} +377 -215
  9. package/dist/{chunk-MPVAZKRB.mjs → chunk-FMWKBZWX.mjs} +835 -317
  10. package/dist/{chunk-NPZ5QQC7.js → chunk-FV4ZRTAK.js} +57 -17
  11. package/dist/{chunk-IIDSY4XZ.js → chunk-G3G437UE.js} +2 -2
  12. package/dist/{chunk-I35XJD75.js → chunk-I4EOMKX2.js} +900 -382
  13. package/dist/{chunk-N6JOG5K3.mjs → chunk-OIDFSOER.mjs} +52 -12
  14. package/dist/{chunk-DBAAU4LK.js → chunk-OV7FX6XR.js} +1 -1
  15. package/dist/{chunk-SR4GC2F4.js → chunk-OYSABARD.js} +8 -4
  16. package/dist/{chunk-M2ATX5ZS.js → chunk-PXZUQ7RR.js} +5 -5
  17. package/dist/{chunk-WJU62RPV.mjs → chunk-QX2A7SBB.mjs} +352 -190
  18. package/dist/{chunk-5APD2MNV.js → chunk-RXNSOSCT.js} +13 -9
  19. package/dist/{chunk-LHBUALTK.mjs → chunk-W3JO6LBC.mjs} +30 -16
  20. package/dist/{chunk-6VKE7EWV.js → chunk-WGFNCK5B.js} +60 -46
  21. package/dist/{chunk-QOTLDKI4.mjs → chunk-XGUD52TA.mjs} +9 -5
  22. package/dist/cli.js +45 -42
  23. package/dist/cli.mjs +9 -6
  24. package/dist/core.d.mts +4 -3
  25. package/dist/core.d.ts +4 -3
  26. package/dist/core.js +124 -30
  27. package/dist/core.mjs +119 -25
  28. package/dist/css-macro/postcss.js +6 -5
  29. package/dist/css-macro/postcss.mjs +4 -3
  30. package/dist/css-macro.js +5 -5
  31. package/dist/css-macro.mjs +2 -2
  32. package/dist/defaults.js +3 -3
  33. package/dist/defaults.mjs +2 -2
  34. package/dist/escape.js +2 -1
  35. package/dist/escape.mjs +2 -1
  36. package/dist/gulp.d.mts +1 -1
  37. package/dist/gulp.d.ts +1 -1
  38. package/dist/gulp.js +8 -7
  39. package/dist/gulp.mjs +8 -7
  40. package/dist/index.js +11 -11
  41. package/dist/index.mjs +9 -9
  42. package/dist/postcss-html-transform.js +1 -1
  43. package/dist/postcss-html-transform.mjs +1 -1
  44. package/dist/presets.js +5 -5
  45. package/dist/presets.mjs +2 -2
  46. package/dist/reset.js +1 -1
  47. package/dist/reset.mjs +1 -1
  48. package/dist/types.js +1 -1
  49. package/dist/types.mjs +1 -1
  50. package/dist/vite.d.mts +1 -1
  51. package/dist/vite.d.ts +1 -1
  52. package/dist/vite.js +9 -8
  53. package/dist/vite.mjs +8 -7
  54. package/dist/webpack.d.mts +1 -1
  55. package/dist/webpack.d.ts +1 -1
  56. package/dist/webpack.js +10 -9
  57. package/dist/webpack.mjs +8 -7
  58. package/dist/webpack4.d.mts +1 -1
  59. package/dist/webpack4.d.ts +1 -1
  60. package/dist/webpack4.js +64 -49
  61. package/dist/webpack4.mjs +33 -18
  62. package/package.json +7 -7
@@ -12,8 +12,9 @@ import {
12
12
  } from "./chunk-RRHPTTCP.mjs";
13
13
  import {
14
14
  setupPatchRecorder
15
- } from "./chunk-BZCCVPSU.mjs";
15
+ } from "./chunk-EOK3NZVC.mjs";
16
16
  import {
17
+ babelParse,
17
18
  collectRuntimeClassSet,
18
19
  createAttributeMatcher,
19
20
  createDebug,
@@ -23,8 +24,9 @@ import {
23
24
  refreshTailwindRuntimeState,
24
25
  replaceWxml,
25
26
  toCustomAttributesEntities,
27
+ traverse,
26
28
  vitePluginName
27
- } from "./chunk-MPVAZKRB.mjs";
29
+ } from "./chunk-FMWKBZWX.mjs";
28
30
  import {
29
31
  resolveUniUtsPlatform
30
32
  } from "./chunk-OOHJLO5M.mjs";
@@ -38,12 +40,12 @@ import postcssHtmlTransform from "@weapp-tailwindcss/postcss/html-transform";
38
40
  import { NodeTypes } from "@vue/compiler-dom";
39
41
  import { parse } from "@vue/compiler-sfc";
40
42
  import MagicString from "magic-string";
41
- function traverse(node, visitor) {
43
+ function traverse2(node, visitor) {
42
44
  visitor(node);
43
45
  if (Array.isArray(node.children)) {
44
46
  for (const child of node.children) {
45
47
  if (child && typeof child === "object" && "type" in child) {
46
- traverse(child, visitor);
48
+ traverse2(child, visitor);
47
49
  }
48
50
  }
49
51
  }
@@ -91,8 +93,9 @@ var defaultCreateJsHandlerOptions = {
91
93
  ]
92
94
  }
93
95
  };
96
+ var UVUE_NVUE_RE = /\.(?:uvue|nvue)(?:\?.*)?$/;
94
97
  function transformUVue(code, id, jsHandler, runtimeSet, options = {}) {
95
- if (!/\.(?:uvue|nvue)(?:\?.*)?$/.test(id)) {
98
+ if (!UVUE_NVUE_RE.test(id)) {
96
99
  return;
97
100
  }
98
101
  const { customAttributesEntities, disabledDefaultTemplateHandler = false } = options;
@@ -101,7 +104,7 @@ function transformUVue(code, id, jsHandler, runtimeSet, options = {}) {
101
104
  const { descriptor, errors } = parse(code);
102
105
  if (errors.length === 0) {
103
106
  if (descriptor.template?.ast) {
104
- traverse(descriptor.template.ast, (node) => {
107
+ traverse2(descriptor.template.ast, (node) => {
105
108
  if (node.type !== NodeTypes.ELEMENT) {
106
109
  return;
107
110
  }
@@ -223,16 +226,20 @@ async function formatPostcssSourceMap(rawMap, file) {
223
226
 
224
227
  // src/uni-app-x/vite.ts
225
228
  var preprocessorLangs = /* @__PURE__ */ new Set(["scss", "sass", "less", "styl", "stylus"]);
229
+ var INLINE_LANG_RE = /lang\.([a-z]+)/i;
230
+ var PREPROCESSOR_EXT_RE = /\.(?:scss|sass|less|styl|stylus)(?:\?|$)/i;
231
+ var UVUE_NVUE_QUERY_RE = /\.(?:uvue|nvue)(?:\?.*)?$/;
232
+ var UVUE_NVUE_RE2 = /\.(?:uvue|nvue)$/;
226
233
  function isPreprocessorRequest(id, lang) {
227
234
  const normalizedLang = lang?.toLowerCase();
228
235
  if (normalizedLang && preprocessorLangs.has(normalizedLang)) {
229
236
  return true;
230
237
  }
231
- const inlineLangMatch = id.match(/lang\.([a-z]+)/i);
238
+ const inlineLangMatch = id.match(INLINE_LANG_RE);
232
239
  if (inlineLangMatch && preprocessorLangs.has(inlineLangMatch[1].toLowerCase())) {
233
240
  return true;
234
241
  }
235
- return /\.(?:scss|sass|less|styl|stylus)(?:\?|$)/i.test(id);
242
+ return PREPROCESSOR_EXT_RE.test(id);
236
243
  }
237
244
  function createUniAppXPlugins(options) {
238
245
  const {
@@ -248,24 +255,31 @@ function createUniAppXPlugins(options) {
248
255
  getResolvedConfig
249
256
  } = options;
250
257
  const isIosPlatform = providedIosPlatform ?? resolveUniUtsPlatform().isAppIos;
258
+ const cssHandlerOptionsCache = /* @__PURE__ */ new Map();
251
259
  async function transformStyle(code, id, query) {
252
260
  const parsed = query ?? parseVueRequest(id).query;
253
261
  if (isCSSRequest(id) || parsed.vue && parsed.type === "style") {
254
- const postcssResult = await styleHandler(code, {
255
- isMainChunk: mainCssChunkMatcher(id, appType),
256
- postcssOptions: {
257
- options: {
258
- from: id,
259
- map: {
260
- inline: false,
261
- annotation: false,
262
- // PostCSS 可能返回虚拟文件,因此需要启用这一项以获取源内容
263
- sourcesContent: true
264
- // 若上游预处理器已经生成 source map,sources 中可能出现重复条目
262
+ const cacheKey = `${mainCssChunkMatcher(id, appType) ? "1" : "0"}:${id}`;
263
+ let styleHandlerOptions = cssHandlerOptionsCache.get(cacheKey);
264
+ if (!styleHandlerOptions) {
265
+ styleHandlerOptions = {
266
+ isMainChunk: mainCssChunkMatcher(id, appType),
267
+ postcssOptions: {
268
+ options: {
269
+ from: id,
270
+ map: {
271
+ inline: false,
272
+ annotation: false,
273
+ // PostCSS 可能返回虚拟文件,因此需要启用这一项以获取源内容
274
+ sourcesContent: true
275
+ // 若上游预处理器已经生成 source map,sources 中可能出现重复条目
276
+ }
265
277
  }
266
278
  }
267
- }
268
- });
279
+ };
280
+ cssHandlerOptionsCache.set(cacheKey, styleHandlerOptions);
281
+ }
282
+ const postcssResult = await styleHandler(code, styleHandlerOptions);
269
283
  const rawPostcssMap = postcssResult.map.toJSON();
270
284
  const postcssMap = await formatPostcssSourceMap(
271
285
  rawPostcssMap,
@@ -305,7 +319,7 @@ function createUniAppXPlugins(options) {
305
319
  await ensureRuntimeClassSet(true);
306
320
  },
307
321
  async transform(code, id) {
308
- if (!/\.(?:uvue|nvue)(?:\?.*)?$/.test(id)) {
322
+ if (!UVUE_NVUE_QUERY_RE.test(id)) {
309
323
  return;
310
324
  }
311
325
  const resolvedConfig = getResolvedConfig();
@@ -328,7 +342,7 @@ function createUniAppXPlugins(options) {
328
342
  if (resolvedConfig?.command !== "serve") {
329
343
  return;
330
344
  }
331
- if (!/\.(?:uvue|nvue)$/.test(ctx.file)) {
345
+ if (!UVUE_NVUE_RE2.test(ctx.file)) {
332
346
  return;
333
347
  }
334
348
  await ensureRuntimeClassSet(true);
@@ -338,7 +352,7 @@ function createUniAppXPlugins(options) {
338
352
  if (resolvedConfig?.command !== "build" || !resolvedConfig.build?.watch) {
339
353
  return;
340
354
  }
341
- if (!/\.(?:uvue|nvue)(?:\?.*)?$/.test(id)) {
355
+ if (!UVUE_NVUE_QUERY_RE.test(id)) {
342
356
  return;
343
357
  }
344
358
  await ensureRuntimeClassSet(true);
@@ -470,46 +484,116 @@ function applyLinkedResults(linked, entries, onLinkedUpdate, onApplied) {
470
484
  }
471
485
  }
472
486
 
473
- // src/bundlers/vite/js-precheck.ts
474
- var FAST_JS_TRANSFORM_HINT_RE = /className\b|class\s*=|classList\.|\b(?:twMerge|clsx|classnames|cn|cva)\b|\[["'`]class["'`]\]|text-\[|bg-\[|\b(?:[whpm]|px|py|mx|my|rounded|flex|grid|gap)-/;
475
- var DEPENDENCY_HINT_RE = /\bimport\s*[("'`{*]|\brequire\s*\(|\bexport\s+\*\s+from\s+["'`]|\bexport\s*\{[^}]*\}\s*from\s+["'`]/;
476
- function shouldSkipViteJsTransform(rawSource, options) {
477
- if (!rawSource) {
478
- return true;
479
- }
480
- if (options?.alwaysEscape) {
481
- return false;
487
+ // src/bundlers/vite/runtime-affecting-signature.ts
488
+ import { Parser } from "htmlparser2";
489
+ function createHtmlRuntimeAffectingSignature(source) {
490
+ try {
491
+ const parts = [];
492
+ const parser = new Parser(
493
+ {
494
+ onattribute(name, value) {
495
+ parts.push(`a:${name}=${value}`);
496
+ },
497
+ oncomment(data) {
498
+ parts.push(`c:${data}`);
499
+ },
500
+ ontext(data) {
501
+ const value = data.trim();
502
+ if (value.length > 0) {
503
+ parts.push(`t:${value}`);
504
+ }
505
+ }
506
+ },
507
+ {
508
+ xmlMode: true
509
+ }
510
+ );
511
+ parser.write(source);
512
+ parser.end();
513
+ return parts.join("\n");
514
+ } catch {
515
+ return source;
482
516
  }
483
- if (options?.moduleSpecifierReplacements && Object.keys(options.moduleSpecifierReplacements).length > 0) {
484
- return false;
517
+ }
518
+ function createJsRuntimeAffectingSignature(source) {
519
+ try {
520
+ const ast = babelParse(source, {
521
+ cache: true,
522
+ cacheKey: "vite-runtime-affecting:unambiguous",
523
+ plugins: ["jsx", "typescript"],
524
+ sourceType: "unambiguous"
525
+ });
526
+ const parts = [];
527
+ traverse(ast, {
528
+ noScope: true,
529
+ StringLiteral(path4) {
530
+ parts.push(`s:${path4.node.value}`);
531
+ },
532
+ TemplateElement(path4) {
533
+ parts.push(`t:${path4.node.value.raw}`);
534
+ },
535
+ JSXText(path4) {
536
+ const value = path4.node.value.trim();
537
+ if (value.length > 0) {
538
+ parts.push(`x:${value}`);
539
+ }
540
+ }
541
+ });
542
+ const comments = ast.comments;
543
+ if (Array.isArray(comments)) {
544
+ for (const comment of comments) {
545
+ if (typeof comment?.value === "string" && comment.value.length > 0) {
546
+ parts.push(`c:${comment.value}`);
547
+ }
548
+ }
549
+ }
550
+ return parts.join("\n");
551
+ } catch {
552
+ return source;
485
553
  }
486
- if (options?.wrapExpression) {
487
- return false;
554
+ }
555
+ function createRuntimeAffectingSourceSignature(source, type) {
556
+ if (type === "html") {
557
+ return createHtmlRuntimeAffectingSignature(source);
488
558
  }
489
- if (DEPENDENCY_HINT_RE.test(rawSource)) {
490
- return false;
559
+ if (type === "js") {
560
+ return createJsRuntimeAffectingSignature(source);
491
561
  }
492
- return !FAST_JS_TRANSFORM_HINT_RE.test(rawSource);
562
+ return source;
493
563
  }
494
564
 
495
- // src/bundlers/vite/generate-bundle.ts
496
- function createEmptyMetric() {
565
+ // src/bundlers/vite/bundle-state.ts
566
+ function createBundleBuildState() {
497
567
  return {
498
- total: 0,
499
- transformed: 0,
500
- cacheHits: 0,
501
- elapsed: 0
568
+ iteration: 0,
569
+ sourceHashByFile: /* @__PURE__ */ new Map(),
570
+ runtimeAffectingHashByFile: /* @__PURE__ */ new Map(),
571
+ linkedByEntry: /* @__PURE__ */ new Map(),
572
+ dependentsByLinkedFile: /* @__PURE__ */ new Map()
502
573
  };
503
574
  }
504
- function createEmptyMetrics() {
575
+ function createChangedByType() {
505
576
  return {
506
- runtimeSet: 0,
507
- html: createEmptyMetric(),
508
- js: createEmptyMetric(),
509
- css: createEmptyMetric()
577
+ html: /* @__PURE__ */ new Set(),
578
+ js: /* @__PURE__ */ new Set(),
579
+ css: /* @__PURE__ */ new Set(),
580
+ other: /* @__PURE__ */ new Set()
510
581
  };
511
582
  }
512
- function classifyEntry(file, opts) {
583
+ function createProcessFiles() {
584
+ return {
585
+ html: /* @__PURE__ */ new Set(),
586
+ js: /* @__PURE__ */ new Set(),
587
+ css: /* @__PURE__ */ new Set()
588
+ };
589
+ }
590
+ function readEntrySource(output) {
591
+ if (output.type === "chunk") {
592
+ return output.code;
593
+ }
594
+ return output.source.toString();
595
+ }
596
+ function classifyBundleEntry(file, opts) {
513
597
  if (opts.cssMatcher(file)) {
514
598
  return "css";
515
599
  }
@@ -521,84 +605,69 @@ function classifyEntry(file, opts) {
521
605
  }
522
606
  return "other";
523
607
  }
524
- function readEntrySource(output) {
525
- if (output.type === "chunk") {
526
- return output.code;
608
+ function collectJsEntries(fileName, output, outDir, store) {
609
+ const entry = { fileName, output };
610
+ if (!isJavaScriptEntry(entry)) {
611
+ return;
527
612
  }
528
- return output.source.toString();
613
+ const absolute = toAbsoluteOutputPath(fileName, outDir);
614
+ store.set(absolute, entry);
529
615
  }
530
- function toJsAbsoluteFilename(file, outDir) {
531
- return toAbsoluteOutputPath(file, outDir);
616
+ function markProcessFile(type, file, processFiles) {
617
+ if (type === "html" || type === "js" || type === "css") {
618
+ processFiles[type].add(file);
619
+ }
532
620
  }
533
- function computeDirtyEntries(entries, opts, state) {
534
- const nextSourceHashByFile = /* @__PURE__ */ new Map();
535
- const changedByType = {
536
- html: /* @__PURE__ */ new Set(),
537
- js: /* @__PURE__ */ new Set(),
538
- css: /* @__PURE__ */ new Set(),
539
- other: /* @__PURE__ */ new Set()
540
- };
541
- for (const [file, output] of entries) {
542
- const type = classifyEntry(file, opts);
621
+ function buildBundleSnapshot(bundle, opts, outDir, state, forceAll = false) {
622
+ const sourceHashByFile = /* @__PURE__ */ new Map();
623
+ const runtimeAffectingHashByFile = /* @__PURE__ */ new Map();
624
+ const changedByType = createChangedByType();
625
+ const runtimeAffectingChangedByType = createChangedByType();
626
+ const processFiles = createProcessFiles();
627
+ const linkedImpactsByEntry = /* @__PURE__ */ new Map();
628
+ const jsEntries = /* @__PURE__ */ new Map();
629
+ const entries = [];
630
+ const firstRun = state.linkedByEntry.size === 0;
631
+ for (const [file, output] of Object.entries(bundle)) {
632
+ const type = classifyBundleEntry(file, opts);
543
633
  const source = readEntrySource(output);
544
634
  const hash = opts.cache.computeHash(source);
545
- nextSourceHashByFile.set(file, hash);
546
- const previousHash = state.previousSourceHashByFile.get(file);
547
- if (previousHash == null || previousHash !== hash) {
635
+ sourceHashByFile.set(file, hash);
636
+ const runtimeAffectingSignature = createRuntimeAffectingSourceSignature(source, type);
637
+ const runtimeAffectingHash = opts.cache.computeHash(runtimeAffectingSignature);
638
+ runtimeAffectingHashByFile.set(file, runtimeAffectingHash);
639
+ const previousHash = state.sourceHashByFile.get(file);
640
+ const changed = previousHash == null || previousHash !== hash;
641
+ if (changed) {
548
642
  changedByType[type].add(file);
549
643
  }
550
- }
551
- return {
552
- sourceHashByFile: nextSourceHashByFile,
553
- changedByType
554
- };
555
- }
556
- function buildProcessSets(entries, opts, changedByType, previousLinkedByEntry, forceAll = false) {
557
- const processFiles = {
558
- html: /* @__PURE__ */ new Set(),
559
- js: /* @__PURE__ */ new Set(),
560
- css: /* @__PURE__ */ new Set()
561
- };
562
- const linkedImpactsByEntry = /* @__PURE__ */ new Map();
563
- if (forceAll) {
564
- for (const [file] of entries) {
565
- const type = classifyEntry(file, opts);
566
- if (type === "html" || type === "js" || type === "css") {
567
- processFiles[type].add(file);
568
- }
569
- }
570
- return {
571
- files: processFiles,
572
- linkedImpactsByEntry
573
- };
574
- }
575
- const firstRun = previousLinkedByEntry.size === 0;
576
- if (firstRun) {
577
- for (const [file] of entries) {
578
- const type = classifyEntry(file, opts);
579
- if (type === "html" || type === "js" || type === "css") {
580
- processFiles[type].add(file);
581
- }
644
+ const previousRuntimeAffectingHash = state.runtimeAffectingHashByFile.get(file);
645
+ const runtimeAffectingChanged = previousRuntimeAffectingHash == null || previousRuntimeAffectingHash !== runtimeAffectingHash;
646
+ if (runtimeAffectingChanged) {
647
+ runtimeAffectingChangedByType[type].add(file);
582
648
  }
583
- return {
584
- files: processFiles,
585
- linkedImpactsByEntry
586
- };
587
- }
588
- for (const [file] of entries) {
589
- if (classifyEntry(file, opts) === "html") {
649
+ if (forceAll || firstRun) {
650
+ markProcessFile(type, file, processFiles);
651
+ } else if (type === "html") {
590
652
  processFiles.html.add(file);
653
+ } else if (changed && (type === "js" || type === "css")) {
654
+ processFiles[type].add(file);
591
655
  }
656
+ collectJsEntries(file, output, outDir, jsEntries);
657
+ entries.push({
658
+ file,
659
+ output,
660
+ source,
661
+ type
662
+ });
592
663
  }
593
- for (const file of changedByType.css) {
594
- processFiles.css.add(file);
595
- }
596
- for (const file of changedByType.js) {
597
- processFiles.js.add(file);
598
- }
599
- for (const changedFile of changedByType.js) {
600
- for (const [entryFile, linkedFiles] of previousLinkedByEntry.entries()) {
601
- if (linkedFiles.has(changedFile)) {
664
+ if (!forceAll && !firstRun) {
665
+ for (const changedFile of changedByType.js) {
666
+ const dependents = state.dependentsByLinkedFile.get(changedFile);
667
+ if (!dependents) {
668
+ continue;
669
+ }
670
+ for (const entryFile of dependents) {
602
671
  processFiles.js.add(entryFile);
603
672
  let impacts = linkedImpactsByEntry.get(entryFile);
604
673
  if (!impacts) {
@@ -610,10 +679,87 @@ function buildProcessSets(entries, opts, changedByType, previousLinkedByEntry, f
610
679
  }
611
680
  }
612
681
  return {
613
- files: processFiles,
682
+ entries,
683
+ jsEntries,
684
+ sourceHashByFile,
685
+ runtimeAffectingHashByFile,
686
+ changedByType,
687
+ runtimeAffectingChangedByType,
688
+ processFiles,
614
689
  linkedImpactsByEntry
615
690
  };
616
691
  }
692
+ function invertLinkedByEntry(linkedByEntry) {
693
+ const dependentsByLinkedFile = /* @__PURE__ */ new Map();
694
+ for (const [entryFile, linkedFiles] of linkedByEntry.entries()) {
695
+ for (const linkedFile of linkedFiles) {
696
+ let dependents = dependentsByLinkedFile.get(linkedFile);
697
+ if (!dependents) {
698
+ dependents = /* @__PURE__ */ new Set();
699
+ dependentsByLinkedFile.set(linkedFile, dependents);
700
+ }
701
+ dependents.add(entryFile);
702
+ }
703
+ }
704
+ return dependentsByLinkedFile;
705
+ }
706
+ function updateBundleBuildState(state, snapshot, linkedByEntry) {
707
+ state.iteration += 1;
708
+ state.sourceHashByFile = snapshot.sourceHashByFile;
709
+ state.runtimeAffectingHashByFile = snapshot.runtimeAffectingHashByFile;
710
+ state.linkedByEntry = linkedByEntry;
711
+ state.dependentsByLinkedFile = invertLinkedByEntry(linkedByEntry);
712
+ }
713
+
714
+ // src/bundlers/vite/js-precheck.ts
715
+ var FAST_JS_TRANSFORM_HINT_RE = /className\b|class\s*=|classList\.|\b(?:twMerge|clsx|classnames|cn|cva)\b|\[["'`]class["'`]\]|text-\[|bg-\[|\b(?:[whpm]|px|py|mx|my|rounded|flex|grid|gap)-/;
716
+ var DEPENDENCY_HINT_RE = /\bimport\s*[("'`{*]|\brequire\s*\(|\bexport\s+\*\s+from\s+["'`]|\bexport\s*\{[^}]*\}\s*from\s+["'`]/;
717
+ function shouldSkipViteJsTransform(rawSource, options) {
718
+ if (!rawSource) {
719
+ return true;
720
+ }
721
+ if (options?.alwaysEscape) {
722
+ return false;
723
+ }
724
+ if (options?.moduleSpecifierReplacements && Object.keys(options.moduleSpecifierReplacements).length > 0) {
725
+ return false;
726
+ }
727
+ if (options?.wrapExpression) {
728
+ return false;
729
+ }
730
+ if (DEPENDENCY_HINT_RE.test(rawSource)) {
731
+ return false;
732
+ }
733
+ return !FAST_JS_TRANSFORM_HINT_RE.test(rawSource);
734
+ }
735
+
736
+ // src/bundlers/vite/generate-bundle.ts
737
+ function formatDebugFileList(files, limit = 8) {
738
+ if (files.size === 0) {
739
+ return "-";
740
+ }
741
+ const sorted = [...files].sort();
742
+ if (sorted.length <= limit) {
743
+ return sorted.join(",");
744
+ }
745
+ return `${sorted.slice(0, limit).join(",")},...(+${sorted.length - limit})`;
746
+ }
747
+ function createEmptyMetric() {
748
+ return {
749
+ total: 0,
750
+ transformed: 0,
751
+ cacheHits: 0,
752
+ elapsed: 0
753
+ };
754
+ }
755
+ function createEmptyMetrics() {
756
+ return {
757
+ runtimeSet: 0,
758
+ html: createEmptyMetric(),
759
+ js: createEmptyMetric(),
760
+ css: createEmptyMetric()
761
+ };
762
+ }
617
763
  function measureElapsed(start) {
618
764
  return performance.now() - start;
619
765
  }
@@ -668,17 +814,8 @@ function hasRuntimeAffectingSourceChanges(changedByType) {
668
814
  return changedByType.html.size > 0 || changedByType.js.size > 0;
669
815
  }
670
816
  function createGenerateBundleHook(context) {
671
- const state = {
672
- iteration: 0,
673
- previousSourceHashByFile: /* @__PURE__ */ new Map(),
674
- previousLinkedByEntry: /* @__PURE__ */ new Map(),
675
- changedByType: {
676
- html: /* @__PURE__ */ new Set(),
677
- js: /* @__PURE__ */ new Set(),
678
- css: /* @__PURE__ */ new Set(),
679
- other: /* @__PURE__ */ new Set()
680
- }
681
- };
817
+ const state = createBundleBuildState();
818
+ const cssHandlerOptionsCache = /* @__PURE__ */ new Map();
682
819
  return async function generateBundle(_opt, bundle) {
683
820
  const {
684
821
  opts,
@@ -699,6 +836,26 @@ function createGenerateBundleHook(context) {
699
836
  jsHandler,
700
837
  uniAppX
701
838
  } = opts;
839
+ const getCssHandlerOptions = (file) => {
840
+ const majorVersion = runtimeState.twPatcher.majorVersion;
841
+ const isMainChunk = mainCssChunkMatcher(file, appType);
842
+ const cacheKey = `${majorVersion ?? "unknown"}:${isMainChunk ? "1" : "0"}:${file}`;
843
+ const cached = cssHandlerOptionsCache.get(cacheKey);
844
+ if (cached) {
845
+ return cached;
846
+ }
847
+ const created = {
848
+ isMainChunk,
849
+ postcssOptions: {
850
+ options: {
851
+ from: file
852
+ }
853
+ },
854
+ majorVersion
855
+ };
856
+ cssHandlerOptionsCache.set(cacheKey, created);
857
+ return created;
858
+ };
702
859
  await runtimeState.patchPromise;
703
860
  debug2("start");
704
861
  onStart();
@@ -707,32 +864,48 @@ function createGenerateBundleHook(context) {
707
864
  const disableDirtyOptimization = process2.env.WEAPP_TW_VITE_DISABLE_DIRTY === "1";
708
865
  const disableJsPrecheck = process2.env.WEAPP_TW_VITE_DISABLE_JS_PRECHECK === "1";
709
866
  const debugCssDiff = process2.env.WEAPP_TW_VITE_DEBUG_CSS_DIFF === "1";
710
- const entries = Object.entries(bundle);
711
- const dirtyEntries = computeDirtyEntries(entries, opts, state);
712
- const forceRuntimeRefreshBySource = hasRuntimeAffectingSourceChanges(dirtyEntries.changedByType);
713
- const forceRuntimeRefresh = forceRuntimeRefreshByEnv || forceRuntimeRefreshBySource;
714
- const processSets = buildProcessSets(entries, opts, dirtyEntries.changedByType, state.previousLinkedByEntry, disableDirtyOptimization);
715
- const processFiles = processSets.files;
716
867
  const resolvedConfig = getResolvedConfig();
717
868
  const rootDir = resolvedConfig?.root ? path2.resolve(resolvedConfig.root) : process2.cwd();
718
869
  const outDir = resolvedConfig?.build?.outDir ? path2.resolve(rootDir, resolvedConfig.build.outDir) : rootDir;
719
- const jsEntries = /* @__PURE__ */ new Map();
720
- for (const [fileName, output] of entries) {
721
- const entry = { fileName, output };
722
- if (isJavaScriptEntry(entry)) {
723
- const absolute = toJsAbsoluteFilename(fileName, outDir);
724
- jsEntries.set(absolute, entry);
725
- }
726
- }
870
+ const snapshot = buildBundleSnapshot(bundle, opts, outDir, state, disableDirtyOptimization);
871
+ const forceRuntimeRefreshBySource = hasRuntimeAffectingSourceChanges(snapshot.runtimeAffectingChangedByType);
872
+ const forceRuntimeRefresh = forceRuntimeRefreshByEnv || forceRuntimeRefreshBySource;
873
+ const processFiles = snapshot.processFiles;
874
+ debug2(
875
+ "dirty iteration=%d html=%d[%s] js=%d[%s] css=%d[%s] other=%d[%s]",
876
+ state.iteration + 1,
877
+ snapshot.changedByType.html.size,
878
+ formatDebugFileList(snapshot.changedByType.html),
879
+ snapshot.changedByType.js.size,
880
+ formatDebugFileList(snapshot.changedByType.js),
881
+ snapshot.changedByType.css.size,
882
+ formatDebugFileList(snapshot.changedByType.css),
883
+ snapshot.changedByType.other.size,
884
+ formatDebugFileList(snapshot.changedByType.other)
885
+ );
886
+ debug2(
887
+ "process iteration=%d html=%d[%s] js=%d[%s] css=%d[%s]",
888
+ state.iteration + 1,
889
+ processFiles.html.size,
890
+ formatDebugFileList(processFiles.html),
891
+ processFiles.js.size,
892
+ formatDebugFileList(processFiles.js),
893
+ processFiles.css.size,
894
+ formatDebugFileList(processFiles.css)
895
+ );
896
+ const jsEntries = snapshot.jsEntries;
727
897
  const moduleGraphOptions = createBundleModuleGraphOptions(outDir, jsEntries);
728
898
  const runtimeStart = performance.now();
729
899
  const runtime = await ensureRuntimeClassSet(forceRuntimeRefresh);
900
+ const defaultTemplateHandlerOptions = {
901
+ runtimeSet: runtime
902
+ };
730
903
  metrics.runtimeSet = measureElapsed(runtimeStart);
731
904
  if (forceRuntimeRefreshBySource) {
732
905
  debug2(
733
906
  "runtimeSet forced refresh due to source changes: html=%d js=%d",
734
- dirtyEntries.changedByType.html.size,
735
- dirtyEntries.changedByType.js.size
907
+ snapshot.runtimeAffectingChangedByType.html.size,
908
+ snapshot.runtimeAffectingChangedByType.js.size
736
909
  );
737
910
  }
738
911
  debug2("get runtimeSet, class count: %d", runtime.size);
@@ -767,14 +940,14 @@ function createGenerateBundleHook(context) {
767
940
  const linkedByEntry = /* @__PURE__ */ new Map();
768
941
  const tasks = [];
769
942
  const jsTaskFactories = [];
770
- for (const [file, originalSource] of entries) {
771
- const type = classifyEntry(file, opts);
943
+ for (const entry of snapshot.entries) {
944
+ const { file, output: originalSource, source: originalEntrySource, type } = entry;
772
945
  if (type === "html" && originalSource.type === "asset") {
773
946
  metrics.html.total++;
774
947
  if (!processFiles.html.has(file)) {
775
948
  continue;
776
949
  }
777
- const rawSource = originalSource.source.toString();
950
+ const rawSource = originalEntrySource;
778
951
  tasks.push(
779
952
  processCachedTask({
780
953
  cache,
@@ -790,9 +963,7 @@ function createGenerateBundleHook(context) {
790
963
  },
791
964
  async transform() {
792
965
  const start = performance.now();
793
- const transformed = await templateHandler(rawSource, {
794
- runtimeSet: runtime
795
- });
966
+ const transformed = await templateHandler(rawSource, defaultTemplateHandlerOptions);
796
967
  metrics.html.elapsed += measureElapsed(start);
797
968
  metrics.html.transformed++;
798
969
  onUpdate(file, rawSource, transformed);
@@ -807,7 +978,7 @@ function createGenerateBundleHook(context) {
807
978
  }
808
979
  if (type === "css" && originalSource.type === "asset") {
809
980
  metrics.css.total++;
810
- const rawSource = originalSource.source.toString();
981
+ const rawSource = originalEntrySource;
811
982
  tasks.push(
812
983
  processCachedTask({
813
984
  cache,
@@ -824,15 +995,7 @@ function createGenerateBundleHook(context) {
824
995
  async transform() {
825
996
  const start = performance.now();
826
997
  await runtimeState.patchPromise;
827
- const { css } = await styleHandler(rawSource, {
828
- isMainChunk: mainCssChunkMatcher(originalSource.fileName, appType),
829
- postcssOptions: {
830
- options: {
831
- from: file
832
- }
833
- },
834
- majorVersion: runtimeState.twPatcher.majorVersion
835
- });
998
+ const { css } = await styleHandler(rawSource, getCssHandlerOptions(file));
836
999
  if (debugCssDiff) {
837
1000
  debug2("css diff %s: %s", file, summarizeStringDiff(rawSource, css));
838
1001
  }
@@ -852,19 +1015,20 @@ function createGenerateBundleHook(context) {
852
1015
  continue;
853
1016
  }
854
1017
  metrics.js.total++;
855
- if (!processFiles.js.has(file)) {
856
- continue;
1018
+ const shouldTransformJs = processFiles.js.has(file);
1019
+ if (!shouldTransformJs) {
1020
+ debug2("js skip transform (clean), replay cache: %s", file);
857
1021
  }
858
1022
  if (originalSource.type === "chunk") {
859
- const absoluteFile = toJsAbsoluteFilename(file, outDir);
860
- const initialRawSource = originalSource.code;
1023
+ const absoluteFile = path2.resolve(outDir, file);
1024
+ const initialRawSource = originalEntrySource;
861
1025
  const linkedSet = /* @__PURE__ */ new Set();
862
1026
  linkedByEntry.set(file, linkedSet);
863
1027
  jsTaskFactories.push(async () => {
864
1028
  const linkedImpactSignature = createLinkedImpactSignature(
865
1029
  file,
866
- processSets.linkedImpactsByEntry,
867
- dirtyEntries.sourceHashByFile
1030
+ snapshot.linkedImpactsByEntry,
1031
+ snapshot.sourceHashByFile
868
1032
  );
869
1033
  const hashSalt = createJsHashSalt(runtimeSignature, linkedImpactSignature);
870
1034
  await processCachedTask({
@@ -883,6 +1047,9 @@ function createGenerateBundleHook(context) {
883
1047
  async transform() {
884
1048
  const start = performance.now();
885
1049
  const rawSource = originalSource.code;
1050
+ if (!shouldTransformJs) {
1051
+ debug2("js cache replay miss, fallback transform: %s", file);
1052
+ }
886
1053
  const handlerOptions = createHandlerOptions(absoluteFile);
887
1054
  if (!disableJsPrecheck && shouldSkipViteJsTransform(rawSource, handlerOptions)) {
888
1055
  metrics.js.elapsed += measureElapsed(start);
@@ -937,8 +1104,8 @@ function createGenerateBundleHook(context) {
937
1104
  runtimeSignature,
938
1105
  createLinkedImpactSignature(
939
1106
  file,
940
- processSets.linkedImpactsByEntry,
941
- dirtyEntries.sourceHashByFile
1107
+ snapshot.linkedImpactsByEntry,
1108
+ snapshot.sourceHashByFile
942
1109
  )
943
1110
  ),
944
1111
  createHandlerOptions,
@@ -952,8 +1119,15 @@ function createGenerateBundleHook(context) {
952
1119
  );
953
1120
  jsTaskFactories.push(async () => {
954
1121
  const start = performance.now();
955
- const currentSource = originalSource.source.toString();
956
- const absoluteFile = toJsAbsoluteFilename(file, outDir);
1122
+ if (!shouldTransformJs) {
1123
+ debug2("js skip transform (clean, uni-app-x), replay cache: %s", file);
1124
+ await factory();
1125
+ metrics.js.elapsed += measureElapsed(start);
1126
+ metrics.js.transformed++;
1127
+ return;
1128
+ }
1129
+ const currentSource = originalEntrySource;
1130
+ const absoluteFile = path2.resolve(outDir, file);
957
1131
  const precheckOptions = createHandlerOptions(absoluteFile, {
958
1132
  uniAppX: uniAppX ?? true,
959
1133
  babelParserOptions: {
@@ -977,20 +1151,7 @@ function createGenerateBundleHook(context) {
977
1151
  for (const apply of pendingLinkedUpdates) {
978
1152
  apply();
979
1153
  }
980
- state.iteration += 1;
981
- state.previousSourceHashByFile = dirtyEntries.sourceHashByFile;
982
- state.changedByType = dirtyEntries.changedByType;
983
- const nextLinkedByEntry = new Map(state.previousLinkedByEntry);
984
- for (const [entryFile, linkedFiles] of linkedByEntry.entries()) {
985
- nextLinkedByEntry.set(entryFile, linkedFiles);
986
- }
987
- for (const entryFile of [...nextLinkedByEntry.keys()]) {
988
- const exists = entries.some(([fileName]) => fileName === entryFile);
989
- if (!exists) {
990
- nextLinkedByEntry.delete(entryFile);
991
- }
992
- }
993
- state.previousLinkedByEntry = nextLinkedByEntry;
1154
+ updateBundleBuildState(state, snapshot, linkedByEntry);
994
1155
  debug2(
995
1156
  "metrics iteration=%d runtime=%sms html(total=%d transform=%d hit=%d rate=%s elapsed=%sms) js(total=%d transform=%d hit=%d rate=%s elapsed=%sms) css(total=%d transform=%d hit=%d rate=%s elapsed=%sms)",
996
1157
  state.iteration,
@@ -1083,7 +1244,7 @@ var debug = createDebug();
1083
1244
  var weappTailwindcssPackageDir = resolvePackageDir("weapp-tailwindcss");
1084
1245
  var weappTailwindcssDirPosix = slash(weappTailwindcssPackageDir);
1085
1246
  function UnifiedViteWeappTailwindcssPlugin(options = {}) {
1086
- const rewriteCssImportsSpecified = Object.prototype.hasOwnProperty.call(options, "rewriteCssImports");
1247
+ const rewriteCssImportsSpecified = Object.hasOwn(options, "rewriteCssImports");
1087
1248
  const hasExplicitTailwindcssBasedir = typeof options.tailwindcssBasedir === "string" && options.tailwindcssBasedir.trim().length > 0;
1088
1249
  const opts = getCompilerContext(options);
1089
1250
  const {
@@ -1218,12 +1379,13 @@ function UnifiedViteWeappTailwindcssPlugin(options = {}) {
1218
1379
  await refreshRuntimeState(true);
1219
1380
  }
1220
1381
  if (typeof config.css.postcss === "object" && Array.isArray(config.css.postcss.plugins)) {
1221
- const idx = config.css.postcss.plugins.findIndex((x) => (
1382
+ const postcssPlugins = config.css.postcss.plugins;
1383
+ const idx = postcssPlugins.findIndex((x) => (
1222
1384
  // @ts-ignore
1223
1385
  x.postcssPlugin === "postcss-html-transform"
1224
1386
  ));
1225
1387
  if (idx > -1) {
1226
- config.css.postcss.plugins.splice(idx, 1, postcssHtmlTransform());
1388
+ postcssPlugins.splice(idx, 1, postcssHtmlTransform());
1227
1389
  debug("remove postcss-html-transform plugin from vite config");
1228
1390
  }
1229
1391
  }