weapp-tailwindcss 5.0.0-next.1 → 5.0.0-next.3

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 (44) hide show
  1. package/dist/bundlers/shared/generator-css.d.ts +3 -1
  2. package/dist/bundlers/vite/css-finalizer.d.ts +3 -0
  3. package/dist/bundlers/vite/generate-bundle.d.ts +14 -1
  4. package/dist/bundlers/vite/source-candidates.d.ts +15 -0
  5. package/dist/cli.js +1 -1
  6. package/dist/cli.mjs +1 -1
  7. package/dist/core.js +1 -1
  8. package/dist/core.mjs +1 -1
  9. package/dist/generator/options.d.ts +2 -0
  10. package/dist/generator/types.d.ts +1 -0
  11. package/dist/generator-Y-Ikv4Fu.mjs +1177 -0
  12. package/dist/{generator-css-DhPFjSzK.mjs → generator-css-Bwy_Uz89.mjs} +72 -32
  13. package/dist/{generator-css-CnYjiMrD.js → generator-css-CRLrHW4F.js} +72 -32
  14. package/dist/{generator-CZ-JXw6T.js → generator-mmhXzZnv.js} +797 -13
  15. package/dist/generator.js +1 -1
  16. package/dist/generator.mjs +1 -1
  17. package/dist/gulp.js +4 -5
  18. package/dist/gulp.mjs +4 -5
  19. package/dist/index.js +3 -3
  20. package/dist/index.mjs +3 -3
  21. package/dist/{loader-anchors-DvwgIYdA.mjs → loader-anchors-1MumTAtA.mjs} +2 -2
  22. package/dist/{loader-anchors-cprm4Klq.js → loader-anchors-TrFvT6g1.js} +1 -1
  23. package/dist/postcss.js +3 -1
  24. package/dist/postcss.mjs +3 -1
  25. package/dist/{recorder-rn_2v_nd.js → recorder-GdTJ3QqX.js} +1 -1
  26. package/dist/{recorder-B_XyZ576.mjs → recorder-XdFvVASS.mjs} +1 -1
  27. package/dist/tailwindcss/v4-engine/candidates.d.ts +2 -0
  28. package/dist/tailwindcss/v4-engine/miniprogram.d.ts +1 -0
  29. package/dist/tailwindcss/v4-engine/tailwind-v3-compatibility.d.ts +1 -0
  30. package/dist/tailwindcss/v4-engine/tailwind-v3-default-colors.d.ts +1 -0
  31. package/dist/tailwindcss/v4-engine/tailwind-v4-default-colors.d.ts +1 -0
  32. package/dist/tailwindcss/v4-engine/types.d.ts +2 -0
  33. package/dist/{vite-C8JlHiyR.mjs → vite-BDywuCjn.mjs} +409 -163
  34. package/dist/{vite-BHpAqldo.js → vite-DgRh_GXn.js} +405 -158
  35. package/dist/vite.js +1 -1
  36. package/dist/vite.mjs +1 -1
  37. package/dist/{webpack-DNIJ0ysE.js → webpack-CAJR4hhP.js} +3 -3
  38. package/dist/{webpack-CABjKGGQ.mjs → webpack-CiHqVZTg.mjs} +3 -3
  39. package/dist/webpack.js +1 -1
  40. package/dist/webpack.mjs +1 -1
  41. package/dist/webpack4.js +3 -3
  42. package/dist/webpack4.mjs +3 -3
  43. package/package.json +5 -8
  44. package/dist/generator-Dwxgra97.mjs +0 -399
@@ -1,20 +1,22 @@
1
- import { d as loadTailwindV4DesignSystem, i as normalizeWeappTailwindcssGeneratorOptions, s as resolveTailwindV4SourceFromPatcher, t as createWeappTailwindcssGenerator } from "./generator-Dwxgra97.mjs";
1
+ import { d as filterUnsupportedMiniProgramTailwindV4Candidates, f as loadTailwindV4DesignSystem, i as normalizeWeappTailwindcssGeneratorOptions, s as resolveTailwindV4SourceFromPatcher } from "./generator-Y-Ikv4Fu.mjs";
2
2
  import { r as resolveTailwindcssOptions } from "./patcher-options-DQfR5xxT.mjs";
3
- import { _ as refreshTailwindRuntimeState, a as createAttributeMatcher, c as isClassContextLiteralPath, d as traverse$1, f as toCustomAttributesEntities, h as collectRuntimeClassSet, i as generateCode, l as replaceWxml, m as vitePluginName, n as shouldSkipJsTransform, o as analyzeSource, r as getCompilerContext, s as JsTokenUpdater, t as setupPatchRecorder, u as babelParse, v as createDebug } from "./recorder-B_XyZ576.mjs";
3
+ import { _ as refreshTailwindRuntimeState, a as createAttributeMatcher, c as isClassContextLiteralPath, d as traverse$1, f as toCustomAttributesEntities, h as collectRuntimeClassSet, i as generateCode, l as replaceWxml, m as vitePluginName, n as shouldSkipJsTransform, o as analyzeSource, r as getCompilerContext, s as JsTokenUpdater, t as setupPatchRecorder, u as babelParse, v as createDebug } from "./recorder-XdFvVASS.mjs";
4
4
  import { o as resolveUniUtsPlatform } from "./utils-7DUGTFED.mjs";
5
5
  import { a as resolveUniAppXOptions, d as getRuntimeClassSetSignature, i as isUniAppXEnabled, l as findNearestPackageRoot, o as findTailwindConfig, t as logger$1 } from "./logger-BoVx1Dbt.mjs";
6
- import { i as processCachedTask, n as hasTailwindGeneratedCssMarkers, r as hasTailwindSourceDirectives, t as generateCssByGenerator } from "./generator-css-DhPFjSzK.mjs";
6
+ import { i as processCachedTask, n as hasTailwindGeneratedCssMarkers, r as hasTailwindSourceDirectives, t as generateCssByGenerator } from "./generator-css-Bwy_Uz89.mjs";
7
7
  import { a as resolveDisabledOptions, c as toAbsoluteOutputPath, i as resolvePackageDir, n as rewriteTailwindcssImportsInCode, o as normalizeOutputPathKey, r as pushConcurrentTaskFactories, s as resolveOutputSpecifier, t as resolveTailwindcssImport } from "./css-imports-CSdPq_Sc.mjs";
8
8
  import path from "node:path";
9
9
  import process from "node:process";
10
10
  import { extractRawCandidatesWithPositions, extractValidCandidates } from "tailwindcss-patch";
11
11
  import { Buffer } from "node:buffer";
12
12
  import fs, { existsSync, readFileSync } from "node:fs";
13
+ import { readFile } from "node:fs/promises";
13
14
  import { logger } from "@weapp-tailwindcss/logger";
14
- import { cleanUrl, ensurePosix } from "@weapp-tailwindcss/shared";
15
+ import { cleanUrl as cleanUrl$1, ensurePosix } from "@weapp-tailwindcss/shared";
15
16
  import MagicString from "magic-string";
16
17
  import { splitCode } from "@weapp-tailwindcss/shared/extractors";
17
18
  import { Parser } from "htmlparser2";
19
+ import fg from "fast-glob";
18
20
  import postcssHtmlTransform from "@weapp-tailwindcss/postcss/html-transform";
19
21
  import postcssrc from "postcss-load-config";
20
22
  import { NodeTypes } from "@vue/compiler-dom";
@@ -306,7 +308,7 @@ function normalizePath(id) {
306
308
  async function formatPostcssSourceMap(rawMap, file) {
307
309
  const inputFileDir = path.dirname(file);
308
310
  const sources = rawMap.sources.map((source) => {
309
- const cleanSource = cleanUrl(decodeURIComponent(source));
311
+ const cleanSource = cleanUrl$1(decodeURIComponent(source));
310
312
  if (cleanSource[0] === "<" && cleanSource.endsWith(">")) return `\0${cleanSource}`;
311
313
  return normalizePath(path.resolve(inputFileDir, cleanSource));
312
314
  });
@@ -358,7 +360,7 @@ function isPreprocessorRequest(id, lang) {
358
360
  return PREPROCESSOR_EXT_RE.test(id);
359
361
  }
360
362
  function resolveUniAppXCssTarget(id) {
361
- return UVUE_NVUE_RE.test(cleanUrl(id)) ? "uvue" : void 0;
363
+ return UVUE_NVUE_RE.test(cleanUrl$1(id)) ? "uvue" : void 0;
362
364
  }
363
365
  function resolveUniAppXJsTransformEnabled$1(uniAppX) {
364
366
  return uniAppX === void 0 ? true : isUniAppXEnabled(uniAppX);
@@ -407,7 +409,7 @@ function createUniAppXPlugins(options) {
407
409
  const postcssResult = await styleHandler(code, styleHandlerOptions);
408
410
  const warnings = typeof postcssResult.warnings === "function" ? postcssResult.warnings() : [];
409
411
  for (const warning of warnings) logger$1.warn(warning.toString());
410
- const postcssMap = await formatPostcssSourceMap(postcssResult.map.toJSON(), cleanUrl(id));
412
+ const postcssMap = await formatPostcssSourceMap(postcssResult.map.toJSON(), cleanUrl$1(id));
411
413
  return {
412
414
  code: postcssResult.css,
413
415
  map: postcssMap
@@ -501,19 +503,6 @@ function createUniAppXAssetTask(file, originalSource, outDir, options) {
501
503
  };
502
504
  }
503
505
  //#endregion
504
- //#region src/bundlers/shared/generator-candidates.ts
505
- async function collectGeneratorCandidatesFromSources(sources, baseCandidates = []) {
506
- const candidates = new Set(baseCandidates);
507
- await Promise.all(sources.map(async (source) => {
508
- const matches = await extractRawCandidatesWithPositions(source.content, source.extension);
509
- for (const match of matches) {
510
- const candidate = match.rawCandidate;
511
- if (typeof candidate === "string" && candidate.length > 0) candidates.add(candidate);
512
- }
513
- }));
514
- return candidates;
515
- }
516
- //#endregion
517
506
  //#region src/bundlers/vite/css-finalizer.ts
518
507
  function createCssHandlerOptions(opts, majorVersion, file) {
519
508
  return {
@@ -527,7 +516,7 @@ function shouldGenerateCssByGenerator(opts, file, rawSource, processed) {
527
516
  return processed && shouldFinalizeProcessedCssAsset(opts, file);
528
517
  }
529
518
  function shouldFinalizeProcessedCssAsset(opts, file) {
530
- return normalizeWeappTailwindcssGeneratorOptions(opts.generator).mode === "force" && opts.mainCssChunkMatcher(file, opts.appType);
519
+ return normalizeWeappTailwindcssGeneratorOptions(opts.generator).mode !== "off" && opts.mainCssChunkMatcher(file, opts.appType);
531
520
  }
532
521
  function createViteCssFinalizerOutputPlugin(context) {
533
522
  return {
@@ -535,16 +524,16 @@ function createViteCssFinalizerOutputPlugin(context) {
535
524
  generateBundle: {
536
525
  order: "post",
537
526
  async handler(_options, bundle) {
538
- const { opts, runtimeState, ensureRuntimeClassSet, isCssAssetProcessed, markCssAssetProcessed, debug, getResolvedConfig, recordCssAssetResult, getRecordedGeneratorCandidates } = context;
527
+ const { opts, runtimeState, ensureRuntimeClassSet, isCssAssetProcessed, markCssAssetProcessed, debug, getResolvedConfig, recordCssAssetResult, getRecordedGeneratorCandidates, getSourceCandidates, waitForSourceCandidateSyncs, rememberMainCssSource } = context;
539
528
  if (getResolvedConfig()?.command !== "build") return;
540
529
  const entries = Object.entries(bundle).filter(([, output]) => output.type === "asset" && opts.cssMatcher(output.fileName) && (!isCssAssetProcessed(output, output.fileName) || shouldFinalizeProcessedCssAsset(opts, output.fileName)));
541
530
  if (entries.length === 0) return;
542
531
  await runtimeState.patchPromise;
543
- const runtime = getRecordedGeneratorCandidates?.() ?? await ensureRuntimeClassSet();
544
- const generatorRuntime = await collectGeneratorCandidatesFromSources(Object.entries(bundle).filter(([, output]) => output.type === "asset" || output.type === "chunk").filter(([file]) => opts.htmlMatcher(file) || opts.jsMatcher(file) || opts.wxsMatcher(file)).map(([file, output]) => ({
545
- content: output.type === "chunk" ? output.code : output.source.toString(),
546
- extension: path.extname(file).replace(/^\./, "") || (opts.htmlMatcher(file) ? "html" : "js")
547
- })), runtime);
532
+ await waitForSourceCandidateSyncs?.();
533
+ const generatorOptions = normalizeWeappTailwindcssGeneratorOptions(opts.generator);
534
+ const runtime = getRecordedGeneratorCandidates?.() ?? getSourceCandidates?.() ?? await ensureRuntimeClassSet();
535
+ const collectedGeneratorCandidates = new Set([...runtime, ...getSourceCandidates?.() ?? []]);
536
+ const generatorRuntime = runtimeState.twPatcher.majorVersion === 4 && generatorOptions.target === "weapp" ? filterUnsupportedMiniProgramTailwindV4Candidates(collectedGeneratorCandidates) : collectedGeneratorCandidates;
548
537
  await Promise.all(entries.map(async ([bundleFile, output]) => {
549
538
  const file = output.fileName || bundleFile;
550
539
  const rawSource = output.source.toString();
@@ -568,6 +557,7 @@ function createViteCssFinalizerOutputPlugin(context) {
568
557
  if (generated) {
569
558
  debug("css finalizer generated result: %s bytes=%d", file, nextCss.length);
570
559
  recordCssAssetResult?.(file, nextCss);
560
+ if (cssHandlerOptions.isMainChunk) rememberMainCssSource?.(file, rawSource);
571
561
  }
572
562
  output.source = nextCss;
573
563
  markCssAssetProcessed(output, file);
@@ -892,6 +882,18 @@ function createJsHashSalt(runtimeSignature, linkedImpactSignature) {
892
882
  if (!linkedImpactSignature) return runtimeSignature;
893
883
  return `${runtimeSignature}:linked:${linkedImpactSignature}`;
894
884
  }
885
+ function createStableTextSignature(input) {
886
+ let hash = 2166136261;
887
+ for (let i = 0; i < input.length; i++) {
888
+ hash ^= input.charCodeAt(i);
889
+ hash = Math.imul(hash, 16777619);
890
+ }
891
+ return (hash >>> 0).toString(36);
892
+ }
893
+ function createCandidateSignature(candidates) {
894
+ if (candidates.size === 0) return "empty";
895
+ return createStableTextSignature([...candidates].sort().join("\n"));
896
+ }
895
897
  function getSnapshotHash(snapshotMap, file, fallback) {
896
898
  return snapshotMap.get(file) ?? fallback;
897
899
  }
@@ -922,6 +924,21 @@ function createCssTransformShareScopeKey(opts, file, rawSource) {
922
924
  if (normalizeWeappTailwindcssGeneratorOptions(opts.generator).mode === "force" && opts.mainCssChunkMatcher(file, opts.appType)) return `main:${normalizeOutputPathKey(file)}`;
923
925
  return createCssTransformShareScope(file, rawSource);
924
926
  }
927
+ function createCssRuntimeSignature(runtimeSignature, generatorCandidateSignature) {
928
+ return `${runtimeSignature}:${generatorCandidateSignature}`;
929
+ }
930
+ function createReplayCssAsset(fileName, source) {
931
+ return {
932
+ type: "asset",
933
+ fileName,
934
+ name: void 0,
935
+ source,
936
+ needsCodeReference: false,
937
+ names: [],
938
+ originalFileName: null,
939
+ originalFileNames: []
940
+ };
941
+ }
925
942
  function hasOmittedKnownBundleFiles(currentBundleFiles, previousBundleFiles) {
926
943
  const currentFileSet = new Set(currentBundleFiles);
927
944
  for (const file of previousBundleFiles) if (!currentFileSet.has(file)) return true;
@@ -949,36 +966,17 @@ function collectUnescapedDynamicCandidates(source) {
949
966
  }
950
967
  return [...matches];
951
968
  }
952
- function collectLegacyContainerCompatCandidates(sources, runtime) {
953
- if (runtime.has("container")) return runtime;
954
- if (!sources.some((source) => /\bcontainer\b/.test(source.content))) return runtime;
955
- return new Set([...runtime, "container"]);
956
- }
957
- async function collectTailwindV4ContentCandidates(runtimeState, runtime, generatorMode, debug) {
958
- const collectContentTokens = runtimeState.twPatcher.collectContentTokens;
959
- if (generatorMode !== "force" || runtimeState.twPatcher.majorVersion !== 4 || typeof collectContentTokens !== "function") return runtime;
960
- try {
961
- const generator = createWeappTailwindcssGenerator(await resolveTailwindV4SourceFromPatcher(runtimeState.twPatcher));
962
- const report = await collectContentTokens.call(runtimeState.twPatcher);
963
- const rawCandidates = new Set(report.entries.map((entry) => entry.rawCandidate));
964
- const validCandidates = await generator.validateCandidates(rawCandidates);
965
- if (rawCandidates.size === 0 && validCandidates.size === 0) return runtime;
966
- return new Set([
967
- ...runtime,
968
- ...rawCandidates,
969
- ...validCandidates
970
- ]);
971
- } catch (error) {
972
- debug("collect Tailwind v4 content candidates for generator failed: %O", error);
973
- return runtime;
974
- }
969
+ function collectLegacyContainerCompatCandidates(sourceCandidates, candidates) {
970
+ if (candidates.has("container")) return candidates;
971
+ if (!sourceCandidates.has("container")) return candidates;
972
+ return new Set([...candidates, "container"]);
975
973
  }
976
974
  function createGenerateBundleHook(context) {
977
975
  const state = createBundleBuildState();
978
976
  const cssHandlerOptionsCache = /* @__PURE__ */ new Map();
979
977
  const cssUserHandlerOptionsCache = /* @__PURE__ */ new Map();
980
978
  return async function generateBundle(_opt, bundle) {
981
- const { opts, runtimeState, ensureBundleRuntimeClassSet, debug, getResolvedConfig, markCssAssetProcessed, recordCssAssetResult, recordGeneratorCandidates } = context;
979
+ const { opts, runtimeState, ensureBundleRuntimeClassSet, debug, getResolvedConfig, markCssAssetProcessed, recordCssAssetResult, getSourceCandidates, waitForSourceCandidateSyncs, rememberMainCssSource, getRememberedMainCssSources, getRememberedMainCssSignature, setRememberedMainCssSignature, recordGeneratorCandidates } = context;
982
980
  const { appType, cache, mainCssChunkMatcher, onEnd, onStart, onUpdate, styleHandler, templateHandler, jsHandler, uniAppX } = opts;
983
981
  const generatorOptions = normalizeWeappTailwindcssGeneratorOptions(opts.generator);
984
982
  const getCssHandlerOptions = (file) => {
@@ -1034,12 +1032,12 @@ function createGenerateBundleHook(context) {
1034
1032
  const moduleGraphOptions = createBundleModuleGraphOptions(outDir, jsEntries);
1035
1033
  const runtimeStart = performance.now();
1036
1034
  const runtime = useBundleRuntimeClassSet ? await ensureBundleRuntimeClassSet(snapshot, forceRuntimeRefreshByEnv) : await context.ensureRuntimeClassSet(forceRuntimeRefreshByEnv);
1037
- const generatorBaseRuntime = await collectTailwindV4ContentCandidates(runtimeState, runtime, generatorOptions.mode, debug);
1038
- const generatorCandidateSources = snapshot.entries.filter((entry) => entry.type === "html" || entry.type === "js").map((entry) => ({
1039
- content: entry.source,
1040
- extension: path.extname(entry.file).replace(/^\./, "") || (entry.type === "html" ? "html" : "js")
1041
- }));
1042
- const generatorRuntime = collectLegacyContainerCompatCandidates(generatorCandidateSources, await collectGeneratorCandidatesFromSources(generatorCandidateSources, generatorBaseRuntime));
1035
+ const shouldFilterTailwindV4MiniProgramCandidates = runtimeState.twPatcher.majorVersion === 4 && generatorOptions.target === "weapp";
1036
+ await waitForSourceCandidateSyncs?.();
1037
+ const sourceCandidates = getSourceCandidates?.() ?? /* @__PURE__ */ new Set();
1038
+ const collectedGeneratorCandidates = generatorOptions.mode === "force" ? new Set(sourceCandidates) : new Set([...runtime, ...sourceCandidates]);
1039
+ const generatorRuntime = collectLegacyContainerCompatCandidates(sourceCandidates, shouldFilterTailwindV4MiniProgramCandidates ? filterUnsupportedMiniProgramTailwindV4Candidates(collectedGeneratorCandidates) : collectedGeneratorCandidates);
1040
+ const generatorCandidateSignature = createCandidateSignature(generatorRuntime);
1043
1041
  recordGeneratorCandidates?.(generatorRuntime);
1044
1042
  const defaultTemplateHandlerOptions = { runtimeSet: runtime };
1045
1043
  metrics.runtimeSet = measureElapsed(runtimeStart);
@@ -1117,15 +1115,17 @@ function createGenerateBundleHook(context) {
1117
1115
  const cssRuntimeAffectingSignature = snapshot.runtimeAffectingSignatureByFile.get(file) ?? rawSource;
1118
1116
  const cssShareScope = createCssTransformShareScopeKey(opts, file, rawSource);
1119
1117
  const cssHandlerOptions = getCssHandlerOptions(file);
1120
- const cssSharedCacheKey = `${cssShareScope}:${runtimeSignature}:${runtimeState.twPatcher.majorVersion ?? "unknown"}:${cssHandlerOptions.isMainChunk ? "1" : "0"}:${cssRuntimeAffectingSignature}`;
1118
+ const cssRuntimeSignature = createCssRuntimeSignature(runtimeSignature, generatorCandidateSignature);
1119
+ const cssSharedCacheKey = `${cssShareScope}:${cssRuntimeSignature}:${runtimeState.twPatcher.majorVersion ?? "unknown"}:${cssHandlerOptions.isMainChunk ? "1" : "0"}:${cssRuntimeAffectingSignature}`;
1121
1120
  tasks.push(processCachedTask({
1122
1121
  cache,
1123
1122
  cacheKey: file,
1124
- hashKey: `${file}:css:${runtimeSignature}:${runtimeState.twPatcher.majorVersion ?? "unknown"}`,
1125
- hash: getSnapshotHash(snapshot.runtimeAffectingHashByFile, file, cssRuntimeAffectingSignature),
1123
+ hashKey: `${file}:css:${cssRuntimeSignature}:${runtimeState.twPatcher.majorVersion ?? "unknown"}`,
1124
+ hash: `${getSnapshotHash(snapshot.runtimeAffectingHashByFile, file, cssRuntimeAffectingSignature)}:${generatorCandidateSignature}`,
1126
1125
  applyResult(source) {
1127
1126
  originalSource.source = source;
1128
1127
  markCssAssetProcessed?.(originalSource, file);
1128
+ if (cssHandlerOptions.isMainChunk) rememberMainCssSource?.(file, rawSource, cssRuntimeSignature);
1129
1129
  },
1130
1130
  onCacheHit() {
1131
1131
  metrics.css.cacheHits++;
@@ -1279,6 +1279,43 @@ function createGenerateBundleHook(context) {
1279
1279
  });
1280
1280
  }
1281
1281
  }
1282
+ const cssRuntimeSignature = createCssRuntimeSignature(runtimeSignature, generatorCandidateSignature);
1283
+ if (useIncrementalMode && generatorOptions.mode !== "off") for (const [file, rawSource] of getRememberedMainCssSources?.() ?? []) {
1284
+ if (bundleFiles.includes(file) || getRememberedMainCssSignature?.(file) === cssRuntimeSignature) continue;
1285
+ tasks.push((async () => {
1286
+ const start = performance.now();
1287
+ const cssHandlerOptions = getCssHandlerOptions(file);
1288
+ const generated = await generateCssByGenerator({
1289
+ opts,
1290
+ runtimeState,
1291
+ runtime: generatorRuntime,
1292
+ rawSource,
1293
+ file,
1294
+ cssHandlerOptions,
1295
+ cssUserHandlerOptions: getCssUserHandlerOptions(file),
1296
+ styleHandler,
1297
+ debug
1298
+ });
1299
+ const css = generated?.css ?? (await styleHandler(rawSource, cssHandlerOptions)).css;
1300
+ setRememberedMainCssSignature?.(file, cssRuntimeSignature);
1301
+ if (generated) {
1302
+ recordCssAssetResult?.(file, generated.css);
1303
+ debug("css replay generated result: %s bytes=%d", file, css.length);
1304
+ }
1305
+ const replayAsset = createReplayCssAsset(file, css);
1306
+ if (typeof this.emitFile === "function") this.emitFile({
1307
+ type: "asset",
1308
+ fileName: file,
1309
+ source: css
1310
+ });
1311
+ else bundle[file] = replayAsset;
1312
+ markCssAssetProcessed?.(replayAsset, file);
1313
+ metrics.css.elapsed += measureElapsed(start);
1314
+ metrics.css.transformed++;
1315
+ onUpdate(file, rawSource, css);
1316
+ debug("css replay handle: %s", file);
1317
+ })());
1318
+ }
1282
1319
  pushConcurrentTaskFactories(tasks, jsTaskFactories);
1283
1320
  await Promise.all(tasks);
1284
1321
  for (const apply of pendingLinkedUpdates) apply();
@@ -1316,7 +1353,7 @@ function resolveEntryExtension(entry) {
1316
1353
  function createCandidateValidationSource(candidates) {
1317
1354
  return [...new Set(candidates)].sort().join("\n");
1318
1355
  }
1319
- function removeCandidateSet(candidateCountByClass, runtimeSet, candidates) {
1356
+ function removeCandidateSet$1(candidateCountByClass, runtimeSet, candidates) {
1320
1357
  for (const className of candidates) {
1321
1358
  const count = candidateCountByClass.get(className);
1322
1359
  if (count == null) continue;
@@ -1328,7 +1365,7 @@ function removeCandidateSet(candidateCountByClass, runtimeSet, candidates) {
1328
1365
  candidateCountByClass.set(className, count - 1);
1329
1366
  }
1330
1367
  }
1331
- function addCandidateSet(candidateCountByClass, runtimeSet, candidates) {
1368
+ function addCandidateSet$1(candidateCountByClass, runtimeSet, candidates) {
1332
1369
  for (const className of candidates) {
1333
1370
  const nextCount = (candidateCountByClass.get(className) ?? 0) + 1;
1334
1371
  candidateCountByClass.set(className, nextCount);
@@ -1411,7 +1448,7 @@ function createBundleRuntimeClassSetManager(options = {}) {
1411
1448
  runtimeSignature = nextSignature;
1412
1449
  for (const [file, previousCandidates] of candidatesByFile) {
1413
1450
  if (currentRuntimeFiles.has(file)) continue;
1414
- removeCandidateSet(candidateCountByClass, runtimeSet, previousCandidates);
1451
+ removeCandidateSet$1(candidateCountByClass, runtimeSet, previousCandidates);
1415
1452
  candidatesByFile.delete(file);
1416
1453
  }
1417
1454
  const changedRuntimeFiles = fullRebuild ? [...runtimeEntriesByFile.keys()] : [...collectChangedRuntimeFiles(snapshot)];
@@ -1430,7 +1467,7 @@ function createBundleRuntimeClassSetManager(options = {}) {
1430
1467
  for (const file of changedRuntimeFiles) {
1431
1468
  const nextRawCandidates = rawCandidatesByFile.get(file);
1432
1469
  const previousCandidates = candidatesByFile.get(file);
1433
- if (previousCandidates) removeCandidateSet(candidateCountByClass, runtimeSet, previousCandidates);
1470
+ if (previousCandidates) removeCandidateSet$1(candidateCountByClass, runtimeSet, previousCandidates);
1434
1471
  if (!nextRawCandidates || nextRawCandidates.size === 0) {
1435
1472
  candidatesByFile.delete(file);
1436
1473
  continue;
@@ -1441,7 +1478,7 @@ function createBundleRuntimeClassSetManager(options = {}) {
1441
1478
  candidatesByFile.delete(file);
1442
1479
  continue;
1443
1480
  }
1444
- addCandidateSet(candidateCountByClass, runtimeSet, nextCandidates);
1481
+ addCandidateSet$1(candidateCountByClass, runtimeSet, nextCandidates);
1445
1482
  candidatesByFile.set(file, nextCandidates);
1446
1483
  }
1447
1484
  debug$1("incremental runtime set synced, changedFiles=%d rawCandidates=%d validateMisses=%d runtimeSize=%d trackedFiles=%d", changedRuntimeFiles.length, rawCandidateCount, unknownCandidates.size, runtimeSet.size, candidatesByFile.size);
@@ -1521,7 +1558,7 @@ function joinPosixPath(base, subpath) {
1521
1558
  }
1522
1559
  function isCssLikeImporter(importer) {
1523
1560
  if (!importer) return false;
1524
- const normalized = cleanUrl(importer);
1561
+ const normalized = cleanUrl$1(importer);
1525
1562
  return isCSSRequest(normalized) || normalized.endsWith("/*");
1526
1563
  }
1527
1564
  function createRewriteCssImportsPlugins(options) {
@@ -1563,6 +1600,158 @@ function createRewriteCssImportsPlugins(options) {
1563
1600
  }];
1564
1601
  }
1565
1602
  //#endregion
1603
+ //#region src/bundlers/vite/source-candidates.ts
1604
+ const CLEAN_URL_RE = /[?#].*$/;
1605
+ const SOURCE_CANDIDATE_EXTENSIONS = [
1606
+ "js",
1607
+ "jsx",
1608
+ "mjs",
1609
+ "cjs",
1610
+ "ts",
1611
+ "tsx",
1612
+ "mts",
1613
+ "cts",
1614
+ "vue",
1615
+ "uvue",
1616
+ "nvue",
1617
+ "svelte",
1618
+ "mpx",
1619
+ "html",
1620
+ "wxml",
1621
+ "axml",
1622
+ "jxml",
1623
+ "ksml",
1624
+ "ttml",
1625
+ "qml",
1626
+ "tyml",
1627
+ "xhsml",
1628
+ "swan",
1629
+ "css",
1630
+ "wxss",
1631
+ "acss",
1632
+ "jxss",
1633
+ "ttss",
1634
+ "qss",
1635
+ "tyss",
1636
+ "scss",
1637
+ "sass",
1638
+ "less",
1639
+ "styl",
1640
+ "stylus"
1641
+ ];
1642
+ const SOURCE_CANDIDATE_EXTENSION_RE = /\.(?:[cm]?[jt]sx?|vue|uvue|nvue|svelte|mpx|html|wxml|axml|jxml|ksml|ttml|qml|tyml|xhsml|swan|css|wxss|acss|jxss|ttss|qss|tyss|scss|sass|less|stylus?)$/;
1643
+ const CSS_SOURCE_CANDIDATE_EXTENSION_RE = /^(?:css|wxss|acss|jxss|ttss|qss|tyss|scss|sass|less|styl|stylus)$/;
1644
+ const SOURCE_CANDIDATE_GLOB = `**/*.{${SOURCE_CANDIDATE_EXTENSIONS.join(",")}}`;
1645
+ const DEFAULT_SCAN_IGNORE = ["**/node_modules/**", "**/.git/**"];
1646
+ function cleanUrl(id) {
1647
+ return id.replace(CLEAN_URL_RE, "");
1648
+ }
1649
+ function toPosixPath(value) {
1650
+ return value.split(path.sep).join("/");
1651
+ }
1652
+ function resolveOutDirIgnorePattern(root, outDir) {
1653
+ if (!outDir) return;
1654
+ const relative = path.relative(root, path.resolve(root, outDir));
1655
+ if (!relative || relative.startsWith("..") || path.isAbsolute(relative)) return;
1656
+ return `${toPosixPath(relative)}/**`;
1657
+ }
1658
+ function resolveSourceCandidateExtension(id) {
1659
+ const normalized = cleanUrl(id);
1660
+ return /\.([^.\\/]+)$/.exec(normalized)?.[1] ?? "html";
1661
+ }
1662
+ function isSourceCandidateRequest(id) {
1663
+ return SOURCE_CANDIDATE_EXTENSION_RE.test(cleanUrl(id));
1664
+ }
1665
+ function removeCandidateSet(candidateCount, candidates) {
1666
+ for (const candidate of candidates) {
1667
+ const count = candidateCount.get(candidate);
1668
+ if (count == null) continue;
1669
+ if (count <= 1) {
1670
+ candidateCount.delete(candidate);
1671
+ continue;
1672
+ }
1673
+ candidateCount.set(candidate, count - 1);
1674
+ }
1675
+ }
1676
+ function addCandidateSet(candidateCount, candidates) {
1677
+ for (const candidate of candidates) candidateCount.set(candidate, (candidateCount.get(candidate) ?? 0) + 1);
1678
+ }
1679
+ const CSS_APPLY_RE = /@apply\s+([^;{}]+)/g;
1680
+ const CSS_APPLY_IMPORTANT = "!important";
1681
+ function extractCssApplyCandidates(source) {
1682
+ const candidates = /* @__PURE__ */ new Set();
1683
+ CSS_APPLY_RE.lastIndex = 0;
1684
+ let match = CSS_APPLY_RE.exec(source);
1685
+ while (match !== null) {
1686
+ const params = match[1] ?? "";
1687
+ for (const candidate of splitCode(params, true)) {
1688
+ const normalized = candidate.trim();
1689
+ if (normalized && normalized !== CSS_APPLY_IMPORTANT) candidates.add(normalized);
1690
+ }
1691
+ match = CSS_APPLY_RE.exec(source);
1692
+ }
1693
+ return candidates;
1694
+ }
1695
+ function createSourceCandidateCollector() {
1696
+ const candidatesById = /* @__PURE__ */ new Map();
1697
+ const candidateCount = /* @__PURE__ */ new Map();
1698
+ async function sync(id, source) {
1699
+ const normalizedId = cleanUrl(id);
1700
+ const extension = resolveSourceCandidateExtension(normalizedId);
1701
+ const nextCandidates = /* @__PURE__ */ new Set();
1702
+ if (CSS_SOURCE_CANDIDATE_EXTENSION_RE.test(extension)) for (const candidate of extractCssApplyCandidates(source)) nextCandidates.add(candidate);
1703
+ else {
1704
+ const matches = await extractRawCandidatesWithPositions(source, extension);
1705
+ for (const match of matches) {
1706
+ const candidate = match.rawCandidate;
1707
+ if (typeof candidate === "string" && candidate.length > 0) nextCandidates.add(candidate);
1708
+ }
1709
+ }
1710
+ remove(normalizedId);
1711
+ if (nextCandidates.size === 0) return;
1712
+ candidatesById.set(normalizedId, nextCandidates);
1713
+ addCandidateSet(candidateCount, nextCandidates);
1714
+ }
1715
+ async function syncFile(id) {
1716
+ const normalizedId = cleanUrl(id);
1717
+ await sync(normalizedId, await readFile(normalizedId, "utf8"));
1718
+ }
1719
+ async function scanRoot({ root, outDir }) {
1720
+ const resolvedRoot = path.resolve(root);
1721
+ const outDirIgnore = resolveOutDirIgnorePattern(resolvedRoot, outDir);
1722
+ const files = await fg(SOURCE_CANDIDATE_GLOB, {
1723
+ absolute: true,
1724
+ cwd: resolvedRoot,
1725
+ ignore: outDirIgnore ? [...DEFAULT_SCAN_IGNORE, outDirIgnore] : DEFAULT_SCAN_IGNORE,
1726
+ onlyFiles: true,
1727
+ unique: true
1728
+ });
1729
+ await Promise.all(files.map((file) => syncFile(file)));
1730
+ }
1731
+ function remove(id) {
1732
+ const normalizedId = cleanUrl(id);
1733
+ const previousCandidates = candidatesById.get(normalizedId);
1734
+ if (!previousCandidates) return;
1735
+ removeCandidateSet(candidateCount, previousCandidates);
1736
+ candidatesById.delete(normalizedId);
1737
+ }
1738
+ function values() {
1739
+ return new Set(candidateCount.keys());
1740
+ }
1741
+ function clear() {
1742
+ candidatesById.clear();
1743
+ candidateCount.clear();
1744
+ }
1745
+ return {
1746
+ sync,
1747
+ syncFile,
1748
+ scanRoot,
1749
+ remove,
1750
+ values,
1751
+ clear
1752
+ };
1753
+ }
1754
+ //#endregion
1566
1755
  //#region src/bundlers/vite/index.ts
1567
1756
  const debug = createDebug();
1568
1757
  const weappTailwindcssPackageDir = resolvePackageDir("weapp-tailwindcss");
@@ -1680,7 +1869,7 @@ function UnifiedViteWeappTailwindcssPlugin(options = {}) {
1680
1869
  const uniAppXEnabled = isUniAppXEnabled(uniAppX);
1681
1870
  const disabledOptions = resolveDisabledOptions(disabled);
1682
1871
  const tailwindcssMajorVersion = initialTwPatcher.majorVersion ?? 0;
1683
- const shouldOwnTailwindGeneration = normalizeWeappTailwindcssGeneratorOptions(opts.generator).mode === "force";
1872
+ const shouldOwnTailwindGeneration = normalizeWeappTailwindcssGeneratorOptions(opts.generator).mode !== "off" && !disabledOptions.plugin;
1684
1873
  const shouldRewriteCssImports = opts.rewriteCssImports !== false && !disabledOptions.rewriteCssImports && (rewriteCssImportsSpecified || tailwindcssMajorVersion >= 4);
1685
1874
  const rewritePlugins = createRewriteCssImportsPlugins({
1686
1875
  getAppType: () => opts.appType,
@@ -1707,8 +1896,12 @@ function UnifiedViteWeappTailwindcssPlugin(options = {}) {
1707
1896
  let runtimeRefreshOptionsKey;
1708
1897
  let recordedGeneratorCandidates;
1709
1898
  const bundleRuntimeClassSetManager = createBundleRuntimeClassSetManager();
1899
+ const sourceCandidateCollector = createSourceCandidateCollector();
1900
+ const pendingSourceCandidateSyncs = /* @__PURE__ */ new Set();
1710
1901
  const processedCssAssets = /* @__PURE__ */ new WeakSet();
1711
1902
  const processedCssAssetFiles = /* @__PURE__ */ new Set();
1903
+ const rememberedMainCssSources = /* @__PURE__ */ new Map();
1904
+ const rememberedMainCssSignatureByFile = /* @__PURE__ */ new Map();
1712
1905
  function resolveRuntimeRefreshOptions() {
1713
1906
  const configPath = resolveTailwindcssOptions(runtimeState.twPatcher.options)?.config;
1714
1907
  const signature = getRuntimeClassSetSignature(runtimeState.twPatcher);
@@ -1776,15 +1969,8 @@ function UnifiedViteWeappTailwindcssPlugin(options = {}) {
1776
1969
  }
1777
1970
  if (runtimeState.twPatcher.majorVersion === 4 && !forceRuntimeRefresh) try {
1778
1971
  const nextRuntimeSet = await bundleRuntimeClassSetManager.sync(runtimeState.twPatcher, snapshot);
1779
- const shouldForceFullRuntimeSet = forceRuntimeRefresh || invalidation.changed || forceCollectBySource;
1780
- const fullRuntimeSet = !shouldForceFullRuntimeSet && runtimeSet ? runtimeSet : await collectRuntimeClassSet(runtimeState.twPatcher, {
1781
- force: shouldForceFullRuntimeSet,
1782
- skipRefresh: forceRuntimeRefresh,
1783
- clearCache: forceRuntimeRefresh || invalidation.changed
1784
- });
1785
- const mergedRuntimeSet = new Set([...fullRuntimeSet, ...nextRuntimeSet]);
1786
- runtimeSet = mergedRuntimeSet;
1787
- return mergedRuntimeSet;
1972
+ runtimeSet = nextRuntimeSet;
1973
+ return nextRuntimeSet;
1788
1974
  } catch (error) {
1789
1975
  debug("incremental runtime set sync failed, fallback to full collect: %O", error);
1790
1976
  await bundleRuntimeClassSetManager.reset();
@@ -1813,13 +1999,33 @@ function UnifiedViteWeappTailwindcssPlugin(options = {}) {
1813
1999
  return processedCssAssets.has(asset) || (file ? processedCssAssetFiles.has(normalizeOutputPathKey(file)) : false);
1814
2000
  };
1815
2001
  const recordGeneratorCandidates = (candidates) => {
1816
- if (!recordedGeneratorCandidates) {
1817
- recordedGeneratorCandidates = new Set(candidates);
1818
- return;
1819
- }
1820
- for (const candidate of candidates) recordedGeneratorCandidates.add(candidate);
2002
+ recordedGeneratorCandidates = new Set(candidates);
1821
2003
  };
1822
2004
  const getRecordedGeneratorCandidates = () => recordedGeneratorCandidates;
2005
+ const getSourceCandidates = () => sourceCandidateCollector.values();
2006
+ const isWatchBuild = () => resolvedConfig?.command === "build" && resolvedConfig.build.watch != null;
2007
+ const waitForSourceCandidateSyncs = async () => {
2008
+ while (pendingSourceCandidateSyncs.size > 0) await Promise.all(pendingSourceCandidateSyncs);
2009
+ };
2010
+ const syncChangedSourceCandidateFile = (id) => {
2011
+ if (!shouldOwnTailwindGeneration || !isSourceCandidateRequest(id)) return Promise.resolve();
2012
+ const task = sourceCandidateCollector.syncFile(id).catch((error) => {
2013
+ debug("source candidate watch sync failed: %s %O", id, error);
2014
+ }).finally(() => {
2015
+ pendingSourceCandidateSyncs.delete(task);
2016
+ });
2017
+ pendingSourceCandidateSyncs.add(task);
2018
+ return task;
2019
+ };
2020
+ const rememberMainCssSource = (file, rawSource, cssRuntimeSignature) => {
2021
+ rememberedMainCssSources.set(file, rawSource);
2022
+ if (cssRuntimeSignature) rememberedMainCssSignatureByFile.set(file, cssRuntimeSignature);
2023
+ };
2024
+ const getRememberedMainCssSources = () => rememberedMainCssSources;
2025
+ const getRememberedMainCssSignature = (file) => rememberedMainCssSignatureByFile.get(file);
2026
+ const setRememberedMainCssSignature = (file, cssRuntimeSignature) => {
2027
+ rememberedMainCssSignatureByFile.set(file, cssRuntimeSignature);
2028
+ };
1823
2029
  const cssFinalizerOutputPlugin = createViteCssFinalizerOutputPlugin({
1824
2030
  opts,
1825
2031
  runtimeState,
@@ -1828,7 +2034,10 @@ function UnifiedViteWeappTailwindcssPlugin(options = {}) {
1828
2034
  getResolvedConfig,
1829
2035
  markCssAssetProcessed,
1830
2036
  isCssAssetProcessed,
1831
- getRecordedGeneratorCandidates
2037
+ getRecordedGeneratorCandidates,
2038
+ getSourceCandidates,
2039
+ waitForSourceCandidateSyncs,
2040
+ rememberMainCssSource
1832
2041
  });
1833
2042
  const isIosPlatform = resolveUniUtsPlatform().isAppIos;
1834
2043
  const uniAppXPlugins = uniAppXEnabled ? createUniAppXPlugins({
@@ -1844,95 +2053,132 @@ function UnifiedViteWeappTailwindcssPlugin(options = {}) {
1844
2053
  getResolvedConfig,
1845
2054
  uniAppX
1846
2055
  }) : void 0;
1847
- const plugins = [...rewritePlugins, {
1848
- name: `${vitePluginName}:post`,
1849
- enforce: "post",
1850
- config(config) {
1851
- if (!shouldOwnTailwindGeneration) return;
1852
- if (Array.isArray(config.plugins)) {
1853
- const removed = disableAndRemoveTailwindVitePlugins(config.plugins);
1854
- if (removed > 0) debug("disable official tailwind vite plugins in generator mode: %d", removed);
1855
- }
1856
- const root = config.root ? path.resolve(config.root) : process.cwd();
1857
- const baseConfig = { resolve: { alias: [{
1858
- find: /^tailwindcss$/,
1859
- replacement: path.join(weappTailwindcssPackageDir, "generator-placeholder.css")
1860
- }] } };
1861
- if (config.css?.postcss !== void 0) return baseConfig;
1862
- return resolveFilteredPostcssConfig(root).then((postcssConfig) => {
1863
- if (!postcssConfig) return baseConfig;
1864
- debug("inline filtered postcss config without official tailwind plugins in generator mode: %d", postcssConfig.removed);
1865
- return {
1866
- ...baseConfig,
1867
- css: { postcss: {
1868
- ...postcssConfig.options,
1869
- plugins: postcssConfig.plugins
1870
- } }
1871
- };
1872
- });
1873
- },
1874
- async configResolved(config) {
1875
- resolvedConfig = config;
1876
- if (shouldOwnTailwindGeneration) {
1877
- const removed = Array.isArray(config.plugins) ? removeTailwindVitePlugins(config.plugins) : 0;
1878
- if (removed > 0) debug("remove official tailwind vite plugins in generator mode: %d", removed);
1879
- }
1880
- const resolvedRoot = config.root ? path.resolve(config.root) : void 0;
1881
- let shouldRefreshRuntime = false;
1882
- if (!hasExplicitTailwindcssBasedir && resolvedRoot) {
1883
- const nextTailwindcssBasedir = resolveImplicitTailwindcssBasedirFromViteRoot(resolvedRoot);
1884
- if (opts.tailwindcssBasedir !== nextTailwindcssBasedir) {
1885
- const previousBasedir = opts.tailwindcssBasedir;
1886
- opts.tailwindcssBasedir = nextTailwindcssBasedir;
1887
- debug("align tailwindcss basedir with vite root: %s -> %s", previousBasedir ?? "undefined", nextTailwindcssBasedir);
1888
- shouldRefreshRuntime = true;
2056
+ const plugins = [
2057
+ ...rewritePlugins,
2058
+ {
2059
+ name: `${vitePluginName}:source-candidates`,
2060
+ enforce: "pre",
2061
+ async transform(code, id) {
2062
+ if (!shouldOwnTailwindGeneration || !isSourceCandidateRequest(id)) return;
2063
+ await sourceCandidateCollector.sync(id, code);
2064
+ },
2065
+ async watchChange(id, change) {
2066
+ if (change.event === "delete") {
2067
+ sourceCandidateCollector.remove(id);
2068
+ return;
1889
2069
  }
2070
+ await syncChangedSourceCandidateFile(id);
2071
+ },
2072
+ async handleHotUpdate(ctx) {
2073
+ await syncChangedSourceCandidateFile(ctx.file);
2074
+ },
2075
+ async buildStart() {
2076
+ if (!shouldOwnTailwindGeneration) return;
2077
+ if (resolvedConfig?.command === "build" && !isWatchBuild()) sourceCandidateCollector.clear();
2078
+ const root = resolvedConfig?.root ?? process.cwd();
2079
+ const outDir = resolvedConfig?.build?.outDir;
2080
+ await sourceCandidateCollector.scanRoot({
2081
+ root,
2082
+ outDir
2083
+ });
1890
2084
  }
1891
- if (!hasExplicitAppType && resolvedRoot) {
1892
- const nextAppType = resolveImplicitAppTypeFromViteRoot(resolvedRoot);
1893
- if (nextAppType && opts.appType !== nextAppType) {
1894
- const previousAppType = opts.appType;
1895
- opts.appType = nextAppType;
1896
- logger.info("根据 Vite 项目根目录自动推断 appType -> %s", nextAppType);
1897
- debug("align appType with vite root: %s -> %s", previousAppType ?? "undefined", nextAppType);
1898
- shouldRefreshRuntime = true;
2085
+ },
2086
+ {
2087
+ name: `${vitePluginName}:post`,
2088
+ enforce: "post",
2089
+ config(config) {
2090
+ if (!shouldOwnTailwindGeneration) return;
2091
+ if (Array.isArray(config.plugins)) {
2092
+ const removed = disableAndRemoveTailwindVitePlugins(config.plugins);
2093
+ if (removed > 0) debug("disable official tailwind vite plugins in generator mode: %d", removed);
1899
2094
  }
1900
- }
1901
- if (shouldRefreshRuntime) await refreshRuntimeState(true);
1902
- if (typeof config.css.postcss === "object" && Array.isArray(config.css.postcss.plugins)) {
1903
- const postcssPlugins = config.css.postcss.plugins;
2095
+ const root = config.root ? path.resolve(config.root) : process.cwd();
2096
+ const baseConfig = { resolve: { alias: [{
2097
+ find: /^tailwindcss$/,
2098
+ replacement: path.join(weappTailwindcssPackageDir, "generator-placeholder.css")
2099
+ }] } };
2100
+ if (config.css?.postcss !== void 0) return baseConfig;
2101
+ return resolveFilteredPostcssConfig(root).then((postcssConfig) => {
2102
+ if (!postcssConfig) return baseConfig;
2103
+ debug("inline filtered postcss config without official tailwind plugins in generator mode: %d", postcssConfig.removed);
2104
+ return {
2105
+ ...baseConfig,
2106
+ css: { postcss: {
2107
+ ...postcssConfig.options,
2108
+ plugins: postcssConfig.plugins
2109
+ } }
2110
+ };
2111
+ });
2112
+ },
2113
+ async configResolved(config) {
2114
+ resolvedConfig = config;
1904
2115
  if (shouldOwnTailwindGeneration) {
1905
- const removed = removeTailwindPostcssPlugins(postcssPlugins);
1906
- if (removed > 0) debug("remove official tailwind postcss plugins in generator mode: %d", removed);
2116
+ const removed = Array.isArray(config.plugins) ? removeTailwindVitePlugins(config.plugins) : 0;
2117
+ if (removed > 0) debug("remove official tailwind vite plugins in generator mode: %d", removed);
2118
+ }
2119
+ const resolvedRoot = config.root ? path.resolve(config.root) : void 0;
2120
+ let shouldRefreshRuntime = false;
2121
+ if (!hasExplicitTailwindcssBasedir && resolvedRoot) {
2122
+ const nextTailwindcssBasedir = resolveImplicitTailwindcssBasedirFromViteRoot(resolvedRoot);
2123
+ if (opts.tailwindcssBasedir !== nextTailwindcssBasedir) {
2124
+ const previousBasedir = opts.tailwindcssBasedir;
2125
+ opts.tailwindcssBasedir = nextTailwindcssBasedir;
2126
+ debug("align tailwindcss basedir with vite root: %s -> %s", previousBasedir ?? "undefined", nextTailwindcssBasedir);
2127
+ shouldRefreshRuntime = true;
2128
+ }
1907
2129
  }
1908
- const idx = postcssPlugins.findIndex((x) => getPostcssPluginName(x) === "postcss-html-transform");
1909
- if (idx > -1) {
1910
- postcssPlugins.splice(idx, 1, postcssHtmlTransform());
1911
- debug("remove postcss-html-transform plugin from vite config");
2130
+ if (!hasExplicitAppType && resolvedRoot) {
2131
+ const nextAppType = resolveImplicitAppTypeFromViteRoot(resolvedRoot);
2132
+ if (nextAppType && opts.appType !== nextAppType) {
2133
+ const previousAppType = opts.appType;
2134
+ opts.appType = nextAppType;
2135
+ logger.info("根据 Vite 项目根目录自动推断 appType -> %s", nextAppType);
2136
+ debug("align appType with vite root: %s -> %s", previousAppType ?? "undefined", nextAppType);
2137
+ shouldRefreshRuntime = true;
2138
+ }
2139
+ }
2140
+ if (shouldRefreshRuntime) await refreshRuntimeState(true);
2141
+ if (typeof config.css.postcss === "object" && Array.isArray(config.css.postcss.plugins)) {
2142
+ const postcssPlugins = config.css.postcss.plugins;
2143
+ if (shouldOwnTailwindGeneration) {
2144
+ const removed = removeTailwindPostcssPlugins(postcssPlugins);
2145
+ if (removed > 0) debug("remove official tailwind postcss plugins in generator mode: %d", removed);
2146
+ }
2147
+ const idx = postcssPlugins.findIndex((x) => getPostcssPluginName(x) === "postcss-html-transform");
2148
+ if (idx > -1) {
2149
+ postcssPlugins.splice(idx, 1, postcssHtmlTransform());
2150
+ debug("remove postcss-html-transform plugin from vite config");
2151
+ }
1912
2152
  }
2153
+ },
2154
+ generateBundle: {
2155
+ order: "post",
2156
+ handler: createGenerateBundleHook({
2157
+ opts,
2158
+ runtimeState,
2159
+ ensureRuntimeClassSet,
2160
+ ensureBundleRuntimeClassSet,
2161
+ debug,
2162
+ getResolvedConfig,
2163
+ markCssAssetProcessed,
2164
+ getSourceCandidates,
2165
+ waitForSourceCandidateSyncs,
2166
+ rememberMainCssSource,
2167
+ getRememberedMainCssSources,
2168
+ getRememberedMainCssSignature,
2169
+ setRememberedMainCssSignature,
2170
+ recordGeneratorCandidates
2171
+ })
2172
+ },
2173
+ outputOptions(options) {
2174
+ const plugins = options.plugins;
2175
+ return {
2176
+ ...options,
2177
+ plugins: Array.isArray(plugins) ? [...plugins, cssFinalizerOutputPlugin] : [cssFinalizerOutputPlugin]
2178
+ };
1913
2179
  }
1914
- },
1915
- generateBundle: {
1916
- order: "post",
1917
- handler: createGenerateBundleHook({
1918
- opts,
1919
- runtimeState,
1920
- ensureRuntimeClassSet,
1921
- ensureBundleRuntimeClassSet,
1922
- debug,
1923
- getResolvedConfig,
1924
- markCssAssetProcessed,
1925
- recordGeneratorCandidates
1926
- })
1927
- },
1928
- outputOptions(options) {
1929
- const plugins = options.plugins;
1930
- return {
1931
- ...options,
1932
- plugins: Array.isArray(plugins) ? [...plugins, cssFinalizerOutputPlugin] : [cssFinalizerOutputPlugin]
1933
- };
1934
2180
  }
1935
- }];
2181
+ ];
1936
2182
  if (uniAppXPlugins) plugins.push(...uniAppXPlugins);
1937
2183
  return plugins;
1938
2184
  }