weapp-vite 6.13.3 → 6.14.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.
@@ -1,14 +1,12 @@
1
- import { t as __exportAll } from "./rolldown-runtime-twds-ZHy.mjs";
2
1
  import { n as applyWeappViteHostMeta } from "./pluginHost-SJdl15d3.mjs";
3
- import { n as configureLogger, r as logger_default } from "./logger-gutcwWKE.mjs";
4
- import { _ as templateExtensions, a as findJsEntry, c as findVueEntry, d as isTemplate, f as touch, g as supportedCssLangs, h as jsExtensions, i as findCssEntry, l as inlineAutoRoutesImports, m as configExtensions, n as extractConfigFromVue, o as findJsonEntry, s as findTemplateEntry, t as changeFileExtension, u as isJsOrTs, v as vueExtensions } from "./file-BAUXs16l.mjs";
2
+ import { n as configureLogger, r as logger_default } from "./logger-CgxdNjvb.mjs";
3
+ import { _ as supportedCssLangs, a as findJsonEntry, c as inlineAutoRoutesImports, g as jsExtensions, h as configExtensions, i as findJsEntry, l as isJsOrTs, n as extractConfigFromVue, o as findTemplateEntry, p as touch, r as findCssEntry, s as findVueEntry, t as changeFileExtension, u as isTemplate, v as templateExtensions, y as vueExtensions } from "./file-Ej-4GoYg.mjs";
5
4
  import { createRequire, isBuiltin } from "node:module";
6
- import { addExtension, defu, get, isEmptyObject, isObject, objectHash, removeExtension, removeExtensionDeep, set } from "@weapp-core/shared";
5
+ import { addExtension, defu, fs, get, isEmptyObject, isObject, objectHash, removeExtension, removeExtensionDeep, set } from "@weapp-core/shared";
7
6
  import { LRUCache } from "lru-cache";
8
7
  import path, { posix } from "pathe";
9
8
  import createDebug from "debug";
10
- import { normalize } from "node:path";
11
- import fs from "fs-extra";
9
+ import { normalize, relative, win32 } from "node:path";
12
10
  import { collectComponentPropsFromCode, collectRequireTokens, collectScriptSetupImportsFromCode, mayContainPlatformApiAccess, mayContainStaticRequireLiteral, parseJsLikeWithEngine, platformApiIdentifiers as platformApiIdentifiers$1 } from "@weapp-vite/ast";
13
11
  import { collectOnPageScrollPerformanceWarnings } from "@weapp-vite/ast/operations/onPageScroll";
14
12
  import { collectSetDataPickKeysFromTemplateCode } from "@weapp-vite/ast/operations/setDataPick";
@@ -1665,12 +1663,12 @@ function createVueComponentsDefinition(componentNames, getMetadata, options = {}
1665
1663
  "// oxlint-disable",
1666
1664
  "// ------",
1667
1665
  "// 由 weapp-vite autoImportComponents 生成",
1668
- "import type { ComponentOptionsMixin, DefineComponent, PublicProps } from 'wevu'",
1666
+ "import type { ComponentOptionsMixin, DefineComponent, PublicProps, WeappIntrinsicElementBaseAttributes } from 'wevu'",
1669
1667
  ...options.useTypedComponents ? ["import type { ComponentProp } from 'weapp-vite/typed-components'"] : [],
1670
1668
  "",
1671
1669
  "export {}",
1672
1670
  "",
1673
- "type WeappComponent<Props = Record<string, any>> = new (...args: any[]) => InstanceType<DefineComponent<{}, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Props, {}>>",
1671
+ "type WeappComponent<Props = Record<string, any>> = new (...args: any[]) => InstanceType<DefineComponent<{}, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Props & WeappIntrinsicElementBaseAttributes, {}>>",
1674
1672
  "type __WeappComponentImport<TModule, Fallback = {}> = 0 extends 1 & TModule ? Fallback : TModule extends { default: infer Component } ? Component & Fallback : Fallback",
1675
1673
  "",
1676
1674
  `declare module '${moduleName}' {`,
@@ -9964,7 +9962,7 @@ function asset(ctx) {
9964
9962
  const LEADING_DOT_SLASH_RE$2 = /^\.\//;
9965
9963
  const LEADING_SLASHES_RE$2 = /^\/+/;
9966
9964
  const GLOB_WILDCARD_RE = /[*?[{]/;
9967
- const TRAILING_SLASHES_RE$1 = /\/+$/;
9965
+ const TRAILING_SLASHES_RE$2 = /\/+$/;
9968
9966
  const AUTO_IMPORT_WATCHER_KEY = "__auto-import-vue-watcher__";
9969
9967
  const AUTO_IMPORT_CONFIG_SUFFIXES = configExtensions.map((ext) => `.${ext}`);
9970
9968
  const AUTO_IMPORT_JS_SUFFIXES = new Set(jsExtensions.map((ext) => `.${ext}`));
@@ -10070,7 +10068,7 @@ function registerAutoImportWatchTargets(state, globs, registrar, options = {}) {
10070
10068
  for (const pattern of globs ?? []) {
10071
10069
  const normalizedPattern = toPosixPath(pattern).replace(LEADING_DOT_SLASH_RE$2, "").replace(LEADING_SLASHES_RE$2, "");
10072
10070
  const wildcardIndex = normalizedPattern.search(GLOB_WILDCARD_RE);
10073
- const cleanedBase = (wildcardIndex >= 0 ? normalizedPattern.slice(0, wildcardIndex) : normalizedPattern).replace(TRAILING_SLASHES_RE$1, "");
10071
+ const cleanedBase = (wildcardIndex >= 0 ? normalizedPattern.slice(0, wildcardIndex) : normalizedPattern).replace(TRAILING_SLASHES_RE$2, "");
10074
10072
  if (!cleanedBase) continue;
10075
10073
  watchTargets.add(path.resolve(configService.absoluteSrcRoot, cleanedBase));
10076
10074
  }
@@ -11037,6 +11035,16 @@ function normalizeRouteRuleLayoutMeta(input) {
11037
11035
  disabled: record.disabled === true
11038
11036
  };
11039
11037
  }
11038
+ function compareRuleScore(left, right) {
11039
+ const maxLength = Math.max(left.length, right.length);
11040
+ for (let index = 0; index < maxLength; index += 1) {
11041
+ const leftValue = left[index] ?? 0;
11042
+ const rightValue = right[index] ?? 0;
11043
+ if (leftValue === rightValue) continue;
11044
+ return leftValue > rightValue ? 1 : -1;
11045
+ }
11046
+ return 0;
11047
+ }
11040
11048
  function resolveRouteRuleLayoutMeta(filename, configService) {
11041
11049
  const routeRules = configService.weappViteConfig?.routeRules;
11042
11050
  if (!routeRules) return;
@@ -11061,16 +11069,6 @@ function resolveRouteRuleLayoutMeta(filename, configService) {
11061
11069
  }
11062
11070
  return matched?.meta;
11063
11071
  }
11064
- function compareRuleScore(left, right) {
11065
- const maxLength = Math.max(left.length, right.length);
11066
- for (let index = 0; index < maxLength; index += 1) {
11067
- const leftValue = left[index] ?? 0;
11068
- const rightValue = right[index] ?? 0;
11069
- if (leftValue === rightValue) continue;
11070
- return leftValue > rightValue ? 1 : -1;
11071
- }
11072
- return 0;
11073
- }
11074
11072
  async function collectLayoutFiles(root) {
11075
11073
  const layoutMap = /* @__PURE__ */ new Map();
11076
11074
  const comparableRoot = normalizeComparablePath(root);
@@ -11481,331 +11479,689 @@ function emitNativeLayoutScriptChunkIfNeeded$1(options) {
11481
11479
  return true;
11482
11480
  }
11483
11481
  //#endregion
11484
- //#region src/plugins/hooks/useLoadEntry/loadEntry/emit.ts
11485
- const NON_VUE_PAGE_RE = /\.vue$|\.jsx$|\.tsx$/;
11486
- function prepareNormalizedEntries(options) {
11487
- const { entries, json, jsonPath, templatePath, id, skipOwnEntries, entriesMap, normalizeEntry, extendedLibManager, entryType, explicitEntryTypes } = options;
11488
- const filteredEntries = skipOwnEntries ? [] : entries.filter((entry) => !extendedLibManager.shouldIgnoreEntry(entry));
11489
- const normalizedEntries = skipOwnEntries ? [] : filteredEntries.map((entry) => normalizeEntry(entry, jsonPath));
11490
- if (!skipOwnEntries) for (const normalizedEntry of normalizedEntries) {
11491
- const resolvedEntryType = explicitEntryTypes?.get(normalizedEntry) ?? entryType ?? (json.component ? "component" : "page");
11492
- entriesMap.set(normalizedEntry, {
11493
- type: resolvedEntryType,
11494
- templatePath,
11495
- jsonPath,
11496
- json,
11497
- path: id
11498
- });
11499
- }
11500
- return normalizedEntries;
11482
+ //#region src/utils/wxmlScriptModule.ts
11483
+ const IMPORT_SJS_TAG_RE = /<import-sjs([\s\S]*?)>/g;
11484
+ const IMPORT_SJS_SRC_RE = /\bsrc\s*=\s*/g;
11485
+ const IMPORT_SJS_MODULE_RE = /\bmodule\s*=\s*/g;
11486
+ const DEFAULT_SCRIPT_MODULE_TAG_NAMES = ["wxs", "sjs"];
11487
+ const DEFAULT_SCRIPT_MODULE_TAG_BY_EXTENSION = Object.freeze({
11488
+ wxs: "wxs",
11489
+ sjs: "sjs"
11490
+ });
11491
+ const SCRIPT_MODULE_IMPORT_ATTRS = Object.freeze({
11492
+ "wxs": ["src"],
11493
+ "sjs": ["src"],
11494
+ "import-sjs": ["from"]
11495
+ });
11496
+ function resolveScriptModuleTagByPlatform(platform, scriptModuleExtension) {
11497
+ return getPlatformScriptModuleTag(platform, scriptModuleExtension);
11501
11498
  }
11502
- async function emitEntryOutput(options) {
11503
- const { pluginCtx, id, type, json: initialJson, jsonPath, templatePath, isPluginBuild, normalizedEntries, pluginResolvedRecords, pluginJsonPathForRegistration, pluginJsonForRegistration, resolveEntriesWithCache, entryResolveRoot, configService, wxmlService, resolvedEntryMap, loadedEntrySet, dirtyEntrySet, replaceLayoutDependencies, emitEntriesChunks, registerJsonAsset, existsCache, pathExistsTtlMs, debug, relativeCwdId, getTime } = options;
11504
- let json = initialJson;
11505
- async function emitNativeLayoutAssets(layoutBasePath) {
11506
- if (typeof pluginCtx.emitFile !== "function") return;
11507
- const resolvedOptions = resolveNativeLayoutOutputOptions({
11508
- configService,
11509
- layoutBasePath,
11510
- outputExtensions: configService.outputExtensions
11511
- });
11512
- if (!resolvedOptions) return;
11513
- const assets = await collectNativeLayoutAssets(layoutBasePath);
11514
- const emittedLayoutAssets = pluginCtx.__weappViteNativeLayoutAssets ?? (pluginCtx.__weappViteNativeLayoutAssets = /* @__PURE__ */ new Set());
11515
- if (assets.json) registerJsonAsset({
11516
- jsonPath: assets.json,
11517
- json: JSON.parse(await fs$1.readFile(assets.json, "utf8")),
11518
- type: "component"
11519
- });
11520
- const assetEntries = await resolveNativeLayoutStaticAssetEntries({
11521
- assets,
11522
- resolvedOptions,
11523
- readFile: fs$1.readFile
11524
- });
11525
- for (const asset of assetEntries) {
11526
- if (emittedLayoutAssets.has(asset.fileName)) continue;
11527
- emittedLayoutAssets.add(asset.fileName);
11528
- pluginCtx.emitFile({
11529
- type: "asset",
11530
- fileName: asset.fileName,
11531
- source: asset.source
11532
- });
11533
- }
11534
- emitNativeLayoutScriptChunkIfNeeded$1({
11535
- pluginCtx,
11536
- scriptId: assets.script,
11537
- fileName: `${resolvedOptions.relativeBase}.${resolvedOptions.scriptExtension}`
11538
- });
11539
- }
11540
- const shouldSkipEntries = Boolean(options.skipEntries);
11541
- const resolvedIds = shouldSkipEntries ? [] : normalizedEntries.length ? await resolveEntriesWithCache(pluginCtx, normalizedEntries, entryResolveRoot) : [];
11542
- debug?.(`resolvedIds ${relativeCwdId} 耗时 ${getTime()}`);
11543
- const pendingResolvedIds = [];
11544
- const combinedResolved = shouldSkipEntries ? [] : pluginResolvedRecords ? isPluginBuild ? pluginResolvedRecords : [...resolvedIds, ...pluginResolvedRecords] : resolvedIds;
11545
- const pluginEntrySet = shouldSkipEntries || !pluginResolvedRecords ? void 0 : new Set(pluginResolvedRecords.map((record) => record.entry));
11546
- for (const { entry, resolvedId } of combinedResolved) {
11547
- if (!resolvedId) {
11548
- if (pluginEntrySet?.has(entry)) logger_default.warn(`没有找到插件入口 \`${entry}\` 对应的脚本文件,请检查路径是否正确!`);
11549
- else logger_default.warn(`没有找到 \`${entry}\` 的入口文件,请检查路径是否正确!`);
11550
- continue;
11551
- }
11552
- const normalizedResolvedId = normalizeFsResolvedId(resolvedId.id);
11553
- if (normalizedResolvedId && !isSkippableResolvedId(normalizedResolvedId) && path.isAbsolute(normalizedResolvedId)) addNormalizedWatchFile(pluginCtx, normalizedResolvedId);
11554
- if (normalizedResolvedId && !isSkippableResolvedId(normalizedResolvedId)) resolvedEntryMap.set(normalizedResolvedId, resolvedId);
11555
- const isDirtyEntry = dirtyEntrySet.has(normalizedResolvedId);
11556
- if (!isDirtyEntry && loadedEntrySet.has(normalizedResolvedId)) continue;
11557
- pendingResolvedIds.push(resolvedId);
11558
- if (isDirtyEntry) dirtyEntrySet.delete(normalizedResolvedId);
11559
- }
11560
- if (pendingResolvedIds.length) await Promise.all(emitEntriesChunks.call(pluginCtx, pendingResolvedIds));
11561
- debug?.(`emitEntriesChunks ${relativeCwdId} 耗时 ${getTime()}`);
11562
- let code = await readFile$1(id, { checkMtime: configService.isDev });
11563
- if (type === "page" && templatePath && !NON_VUE_PAGE_RE.test(id)) {
11564
- replaceLayoutDependencies(id, []);
11565
- const layoutPlan = await resolvePageLayoutPlan(code, id, configService);
11566
- if (layoutPlan) {
11567
- const layoutDependencies = /* @__PURE__ */ new Set();
11568
- for (const file of await expandResolvedPageLayoutFiles(layoutPlan.layouts)) {
11569
- addNormalizedWatchFile(pluginCtx, file);
11570
- layoutDependencies.add(normalizeFsResolvedId(file));
11571
- }
11572
- replaceLayoutDependencies(id, layoutDependencies);
11573
- const nativeTemplate = await readFile$1(templatePath, { checkMtime: configService.isDev });
11574
- const transformed = applyPageLayoutPlanToNativePage({
11575
- script: code,
11576
- template: nativeTemplate,
11577
- config: JSON.stringify(json)
11578
- }, id, layoutPlan);
11579
- code = transformed.script ?? code;
11580
- if (transformed.config) json = JSON.parse(transformed.config);
11581
- if (transformed.template && wxmlService) {
11582
- const token = wxmlService.analyze(transformed.template);
11583
- wxmlService.tokenMap.set(templatePath, token);
11584
- wxmlService.setWxmlComponentsMap(templatePath, token.components);
11585
- }
11586
- for (const layout of layoutPlan.layouts) if (layout.kind === "native") await emitNativeLayoutAssets(layout.file);
11587
- }
11588
- code = injectNativePageLayoutRuntime(code, id, layoutPlan) ?? code;
11589
- }
11590
- if (!isPluginBuild || type !== "app") registerJsonAsset({
11591
- jsonPath,
11592
- json,
11593
- type
11594
- });
11595
- if (pluginJsonPathForRegistration && pluginJsonForRegistration) registerJsonAsset({
11596
- jsonPath: pluginJsonPathForRegistration,
11597
- json: pluginJsonForRegistration,
11598
- type: "plugin"
11499
+ function normalizeScriptModuleExtension(scriptModuleExtension) {
11500
+ if (!scriptModuleExtension) return;
11501
+ return scriptModuleExtension.startsWith(".") ? scriptModuleExtension.slice(1) : scriptModuleExtension;
11502
+ }
11503
+ function getDefaultScriptModuleTagByExtension(scriptModuleExtension) {
11504
+ if (!scriptModuleExtension) return "wxs";
11505
+ return DEFAULT_SCRIPT_MODULE_TAG_BY_EXTENSION[normalizeScriptModuleExtension(scriptModuleExtension)] ?? "wxs";
11506
+ }
11507
+ function resolveScriptModuleTagName(options) {
11508
+ if (options?.scriptModuleTag) return options.scriptModuleTag;
11509
+ return resolveScriptModuleTagByPlatform(options?.platform, options?.scriptModuleExtension) ?? getDefaultScriptModuleTagByExtension(options?.scriptModuleExtension);
11510
+ }
11511
+ function getDerivedScriptModuleTagNames() {
11512
+ return MINI_PROGRAM_PLATFORM_ADAPTERS.flatMap((adapter) => Object.values(adapter.scriptModuleTagByExtension ?? {})).filter((value) => typeof value === "string" && value.length > 0);
11513
+ }
11514
+ function getScriptModuleTagNames() {
11515
+ return [...new Set([...DEFAULT_SCRIPT_MODULE_TAG_NAMES, ...getDerivedScriptModuleTagNames()])];
11516
+ }
11517
+ function isScriptModuleTagName(tagName) {
11518
+ return typeof tagName === "string" && getScriptModuleTagNames().includes(tagName);
11519
+ }
11520
+ function getScriptModuleImportAttrs(tagName) {
11521
+ if (!tagName) return;
11522
+ return SCRIPT_MODULE_IMPORT_ATTRS[tagName];
11523
+ }
11524
+ function isScriptModuleImportAttr(tagName, attrName) {
11525
+ if (!tagName) return false;
11526
+ return getScriptModuleImportAttrs(tagName)?.includes(attrName) === true;
11527
+ }
11528
+ function shouldNormalizeScriptModuleAttributes(tagName) {
11529
+ return tagName === "import-sjs";
11530
+ }
11531
+ function normalizeImportSjsAttributes(source) {
11532
+ return source.replace(IMPORT_SJS_TAG_RE, (tag) => {
11533
+ return tag.replace(IMPORT_SJS_SRC_RE, "from=").replace(IMPORT_SJS_MODULE_RE, "name=");
11599
11534
  });
11600
- const styleImports = await collectStyleImports(pluginCtx, id, existsCache, pathExistsTtlMs);
11601
- debug?.(`loadEntry ${relativeCwdId} 耗时 ${getTime()}`);
11602
- if (styleImports.length === 0) return { code };
11603
- const ms = new MagicString(code);
11604
- for (const styleImport of styleImports) ms.prepend(`import '${styleImport}';\n`);
11605
- return { code: ms.toString() };
11606
11535
  }
11607
11536
  //#endregion
11608
- //#region src/plugins/hooks/useLoadEntry/loadEntry/resolve.ts
11609
- function createEntryResolver(configService) {
11610
- const entryResolutionCache = /* @__PURE__ */ new Map();
11611
- async function resolveEntryWithCache(pluginCtx, absPath) {
11612
- const normalized = path.normalize(absPath);
11613
- if (entryResolutionCache.has(normalized)) return entryResolutionCache.get(normalized) ?? null;
11614
- let resolvedSource = normalized;
11615
- if (!path.extname(normalized)) {
11616
- const matched = await resolveEntryPath(normalized, createCachedEntryResolveOptions(configService ?? {}, { kind: "default" }));
11617
- if (matched) resolvedSource = matched;
11537
+ //#region src/wxs/utils.ts
11538
+ function normalizeWxsFilename(value, extension = "wxs") {
11539
+ const normalized = extension.startsWith(".") ? extension.slice(1) : extension;
11540
+ let filename = value;
11541
+ filename = filename.replace(/\.[jt]s$/i, "");
11542
+ filename = filename.replace(/\.(wxs|sjs)$/i, "");
11543
+ return addExtension(filename, `.${normalized}`);
11544
+ }
11545
+ //#endregion
11546
+ //#region src/wxs/index.ts
11547
+ function transformWxsCode(code, options) {
11548
+ const filename = options?.filename ?? "script.ts";
11549
+ const extension = options?.extension ?? "wxs";
11550
+ const importees = [];
11551
+ const maybePushImportee = (value) => {
11552
+ if (typeof value !== "string" || !value) return;
11553
+ importees.push({ source: value });
11554
+ };
11555
+ const tryCollectArgument = (path) => {
11556
+ const node = path.node;
11557
+ if (t.isStringLiteral(node)) {
11558
+ maybePushImportee(node.value);
11559
+ return;
11618
11560
  }
11619
- const resolvedId = await pluginCtx.resolve(resolvedSource) ?? null;
11620
- entryResolutionCache.set(normalized, resolvedId);
11621
- return resolvedId;
11622
- }
11623
- async function resolveEntriesWithCache(pluginCtx, entries, absoluteRoot) {
11624
- return Promise.all(entries.filter((entry) => !entry.includes(":")).map(async (entry) => {
11625
- return {
11626
- entry,
11627
- resolvedId: await resolveEntryWithCache(pluginCtx, path.resolve(absoluteRoot, entry))
11628
- };
11629
- }));
11630
- }
11631
- return {
11632
- resolveEntryWithCache,
11633
- resolveEntriesWithCache,
11634
- invalidate() {
11635
- entryResolutionCache.clear();
11561
+ if (t.isTemplateLiteral(node) && node.expressions.length === 0) {
11562
+ maybePushImportee(node.quasis.map((q) => q.value.cooked ?? q.value.raw ?? "").join(""));
11563
+ return;
11636
11564
  }
11565
+ try {
11566
+ const evaluated = path.evaluate();
11567
+ if (evaluated.confident) maybePushImportee(evaluated.value);
11568
+ } catch {}
11637
11569
  };
11638
- }
11639
- //#endregion
11640
- //#region src/plugins/utils/vueSfc.ts
11641
- function createSfcResolveSrcOptions(pluginCtx, configService) {
11642
11570
  return {
11643
- resolveId: async (source, importer) => {
11644
- if (typeof pluginCtx.resolve !== "function") return;
11645
- return (await pluginCtx.resolve(source, importer))?.id;
11646
- },
11647
- checkMtime: getSfcCheckMtime(configService)
11648
- };
11649
- }
11650
- function createReadAndParseSfcOptions(pluginCtx, configService, options) {
11651
- const resolveCheckMtime = getSfcCheckMtime(configService);
11652
- return {
11653
- source: options?.source,
11654
- checkMtime: options?.checkMtime ?? resolveCheckMtime,
11655
- resolveSrc: createSfcResolveSrcOptions(pluginCtx, configService)
11571
+ result: babel.transformSync(code, {
11572
+ babelrc: false,
11573
+ configFile: false,
11574
+ presets: [["@babel/preset-env"], ["@babel/preset-typescript"]],
11575
+ filename,
11576
+ plugins: [{ visitor: {
11577
+ Directive: { enter(p) {
11578
+ p.remove();
11579
+ } },
11580
+ CallExpression: { enter(p) {
11581
+ const node = p.node;
11582
+ if (!t.isIdentifier(node.callee, { name: "require" })) return;
11583
+ if (node.arguments.length !== 1) return;
11584
+ tryCollectArgument(p.get("arguments.0"));
11585
+ const arg = node.arguments[0];
11586
+ if (t.isStringLiteral(arg)) arg.value = normalizeWxsFilename(arg.value, extension);
11587
+ } },
11588
+ ExpressionStatement(p) {
11589
+ const expression = p.node.expression;
11590
+ if (expression.type === "CallExpression" && expression.callee.type === "MemberExpression" && t.isIdentifier(expression.callee.object) && expression.callee.object.name === "Object" && t.isIdentifier(expression.callee.property) && expression.callee.property.name === "defineProperty" && expression.arguments.length >= 2 && t.isIdentifier(expression.arguments[0]) && expression.arguments[0].name === "exports" && t.isStringLiteral(expression.arguments[1]) && expression.arguments[1].value === "__esModule") p.remove();
11591
+ },
11592
+ NewExpression: { enter(p) {
11593
+ const node = p.node;
11594
+ if (t.isIdentifier(node.callee, { name: "RegExp" })) p.replaceWith(t.callExpression(t.identifier("getRegExp"), node.arguments));
11595
+ else if (t.isIdentifier(node.callee, { name: "Date" })) p.replaceWith(t.callExpression(t.identifier("getDate"), node.arguments));
11596
+ } },
11597
+ RegExpLiteral: { enter(p) {
11598
+ const args = [t.stringLiteral(p.node.pattern)];
11599
+ if (p.node.flags) args.push(t.stringLiteral(p.node.flags));
11600
+ p.replaceWith(t.callExpression(t.identifier("getRegExp"), args));
11601
+ } },
11602
+ MemberExpression: { enter(p) {
11603
+ const node = p.node;
11604
+ if (!t.isIdentifier(node.object, { name: "exports" })) return;
11605
+ const moduleExports = t.memberExpression(t.identifier("module"), t.identifier("exports"));
11606
+ p.replaceWith(t.memberExpression(moduleExports, node.property, node.computed, node.optional));
11607
+ } },
11608
+ ImportDeclaration: { enter(p) {
11609
+ maybePushImportee(p.node.source.value);
11610
+ } }
11611
+ } }]
11612
+ }),
11613
+ importees
11656
11614
  };
11657
11615
  }
11658
11616
  //#endregion
11659
- //#region src/plugins/vue/transform/usingComponentResolver.ts
11660
- const JS_LIKE_FILE_RE = /\.(?:[cm]?ts|[cm]?js)$/;
11661
- async function resolveUsingComponentReference(ctx, configService, reExportResolutionCache, importSource, importerFilename, info) {
11662
- const resolved = await ctx.resolve(importSource, importerFilename);
11663
- let clean = resolved?.id ? normalizeFsResolvedId(resolved.id) : void 0;
11664
- if ((!clean || !path.isAbsolute(clean)) && info?.fallbackRelativeImporterDir && importSource.startsWith(".")) clean = path.resolve(path.dirname(importerFilename), importSource);
11665
- if (!clean) return {
11666
- resolvedId: void 0,
11667
- from: void 0
11668
- };
11669
- if (isSkippableResolvedId(clean)) return {
11670
- resolvedId: void 0,
11671
- from: void 0
11672
- };
11673
- if (path.isAbsolute(clean)) {
11674
- const resolvedEntry = await resolveEntryPath(clean, createCachedEntryResolveOptions(configService ?? {}, { kind: info?.kind ?? "default" }));
11675
- if (resolvedEntry) clean = resolvedEntry;
11617
+ //#region src/wxml/handle.ts
11618
+ const handleCache = /* @__PURE__ */ new WeakMap();
11619
+ const inlineWxsTransformCache = /* @__PURE__ */ new Map();
11620
+ const INLINE_WXS_CACHE_LIMIT = 256;
11621
+ function createCacheKey$1(options) {
11622
+ const extension = options.scriptModuleExtension ?? "";
11623
+ const tag = options.scriptModuleTag ?? "";
11624
+ const templateExt = options.templateExtension ?? "";
11625
+ return `${options.removeComment ? 1 : 0}|${options.transformEvent ? 1 : 0}|${extension}|${tag}|${templateExt}`;
11626
+ }
11627
+ function getCachedResult(data, cacheKey) {
11628
+ return handleCache.get(data)?.get(cacheKey);
11629
+ }
11630
+ function setCachedResult(data, cacheKey, result) {
11631
+ let cacheForToken = handleCache.get(data);
11632
+ if (!cacheForToken) {
11633
+ cacheForToken = /* @__PURE__ */ new Map();
11634
+ handleCache.set(data, cacheForToken);
11676
11635
  }
11677
- if (info?.kind === "named" && info.importedName && JS_LIKE_FILE_RE.test(clean)) {
11678
- const exportName = info.importedName;
11679
- const mapped = await resolveReExportedName(clean, exportName, {
11680
- astEngine: resolveAstEngine(configService.weappViteConfig),
11681
- cache: reExportResolutionCache,
11682
- maxDepth: 4,
11683
- readFile: (file) => readFile$1(file, { checkMtime: getReadFileCheckMtime(configService) }),
11684
- resolveId: async (source, importer) => {
11685
- const hop = await ctx.resolve(source, importer);
11686
- const hopId = hop?.id ? normalizeFsResolvedId(hop.id) : void 0;
11687
- if (isSkippableResolvedId(hopId)) return;
11688
- return hopId;
11689
- }
11690
- });
11691
- if (mapped) clean = mapped;
11636
+ cacheForToken.set(cacheKey, result);
11637
+ return result;
11638
+ }
11639
+ function getCachedInlineWxsTransform(code, extension) {
11640
+ const key = `${extension}::${code}`;
11641
+ const cached = inlineWxsTransformCache.get(key);
11642
+ if (cached) {
11643
+ inlineWxsTransformCache.delete(key);
11644
+ inlineWxsTransformCache.set(key, cached);
11645
+ return cached;
11692
11646
  }
11693
- return {
11694
- resolvedId: clean,
11695
- from: usingComponentFromResolvedFile(clean, configService)
11696
- };
11647
+ const transformed = transformWxsCode(code, { extension });
11648
+ inlineWxsTransformCache.set(key, transformed);
11649
+ if (inlineWxsTransformCache.size > INLINE_WXS_CACHE_LIMIT) {
11650
+ const firstKey = inlineWxsTransformCache.keys().next().value;
11651
+ if (firstKey) inlineWxsTransformCache.delete(firstKey);
11652
+ }
11653
+ return transformed;
11697
11654
  }
11698
- async function resolveUsingComponentPath(ctx, configService, reExportResolutionCache, importSource, importerFilename, info) {
11699
- return (await resolveUsingComponentReference(ctx, configService, reExportResolutionCache, importSource, importerFilename, info)).from;
11655
+ function handleWxml(data, options) {
11656
+ const opts = defu(options, {
11657
+ removeComment: true,
11658
+ transformEvent: true,
11659
+ scriptModuleExtension: void 0,
11660
+ scriptModuleTag: void 0,
11661
+ templateExtension: void 0
11662
+ });
11663
+ const cacheKey = createCacheKey$1(opts);
11664
+ const cached = getCachedResult(data, cacheKey);
11665
+ if (cached) return cached;
11666
+ const { code, removalRanges = [], commentTokens = [], eventTokens = [], directiveTokens = [], tagNameTokens = [], inlineWxsTokens = [], removeWxsLangAttrTokens = [], scriptModuleTagTokens = [], wxsImportNormalizeTokens = [], templateImportNormalizeTokens = [], components, deps } = data;
11667
+ const normalizedScriptExtension = opts.scriptModuleExtension?.startsWith(".") ? opts.scriptModuleExtension.slice(1) : opts.scriptModuleExtension;
11668
+ const normalizedTemplateExtension = opts.templateExtension?.startsWith(".") ? opts.templateExtension.slice(1) : opts.templateExtension;
11669
+ const resolvedScriptTag = resolveScriptModuleTagName({
11670
+ scriptModuleExtension: normalizedScriptExtension,
11671
+ scriptModuleTag: opts.scriptModuleTag
11672
+ });
11673
+ const shouldNormalizeImports = wxsImportNormalizeTokens.length > 0;
11674
+ const shouldNormalizeTemplateImports = templateImportNormalizeTokens.length > 0 && normalizedTemplateExtension;
11675
+ const shouldRemoveLang = removeWxsLangAttrTokens.length > 0;
11676
+ const shouldTransformInlineWxs = inlineWxsTokens.length > 0;
11677
+ const shouldTransformEvents = opts.transformEvent && eventTokens.length > 0;
11678
+ const shouldTransformDirectives = directiveTokens.length > 0;
11679
+ const shouldTransformTagNames = tagNameTokens.length > 0;
11680
+ const shouldTransformScriptModuleTags = resolvedScriptTag !== "wxs" && scriptModuleTagTokens.length > 0;
11681
+ const shouldRemoveConditionals = removalRanges.length > 0;
11682
+ const shouldRemoveComments = opts.removeComment && commentTokens.length > 0;
11683
+ if (!shouldNormalizeImports && !shouldNormalizeTemplateImports && !shouldRemoveLang && !shouldTransformInlineWxs && !shouldTransformEvents && !shouldTransformDirectives && !shouldTransformTagNames && !shouldTransformScriptModuleTags && !shouldRemoveConditionals && !shouldRemoveComments) return setCachedResult(data, cacheKey, {
11684
+ code,
11685
+ components,
11686
+ deps
11687
+ });
11688
+ const ms = new MagicString(code);
11689
+ if (shouldNormalizeImports) for (const { start, end, value } of wxsImportNormalizeTokens) ms.update(start, end, normalizeWxsFilename(value, normalizedScriptExtension ?? "wxs"));
11690
+ if (shouldNormalizeTemplateImports) for (const { start, end, value } of templateImportNormalizeTokens) {
11691
+ let nextValue = changeFileExtension(value, normalizedTemplateExtension);
11692
+ if (value.startsWith("./") && !nextValue.startsWith("./") && !nextValue.startsWith("../") && !nextValue.startsWith("/")) nextValue = `./${nextValue}`;
11693
+ ms.update(start, end, nextValue);
11694
+ }
11695
+ if (shouldRemoveLang) for (const { start, end } of removeWxsLangAttrTokens) ms.update(start, end, "");
11696
+ if (shouldTransformInlineWxs) for (const { end, start, value } of inlineWxsTokens) {
11697
+ const { result } = getCachedInlineWxsTransform(value, normalizedScriptExtension ?? "wxs");
11698
+ if (result?.code) ms.update(start, end, `\n${result.code}`);
11699
+ }
11700
+ if (shouldTransformScriptModuleTags) {
11701
+ const visited = /* @__PURE__ */ new Set();
11702
+ for (const { start, end } of scriptModuleTagTokens) {
11703
+ const key = `${start}:${end}`;
11704
+ if (visited.has(key)) continue;
11705
+ visited.add(key);
11706
+ ms.update(start, end, resolvedScriptTag);
11707
+ }
11708
+ }
11709
+ if (shouldTransformEvents) for (const { end, start, value } of eventTokens) ms.update(start, end, value);
11710
+ if (shouldTransformDirectives) for (const { end, start, value } of directiveTokens) ms.update(start, end, value);
11711
+ if (shouldTransformTagNames) for (const { end, start, value } of tagNameTokens) ms.update(start, end, value);
11712
+ if (shouldRemoveConditionals) {
11713
+ for (const { start, end } of removalRanges) if (end > start) ms.remove(start, end);
11714
+ }
11715
+ if (shouldRemoveComments) for (const { end, start } of commentTokens) ms.remove(start, end);
11716
+ return setCachedResult(data, cacheKey, {
11717
+ code: shouldNormalizeScriptModuleAttributes(resolvedScriptTag) ? normalizeImportSjsAttributes(ms.toString()) : ms.toString(),
11718
+ components,
11719
+ deps
11720
+ });
11700
11721
  }
11701
- function createUsingComponentPathResolver(ctx, configService, reExportResolutionCache) {
11702
- return async (importSource, importerFilename, info) => {
11703
- return resolveUsingComponentPath(ctx, configService, reExportResolutionCache, importSource, importerFilename, info);
11722
+ //#endregion
11723
+ //#region src/plugins/utils/wxmlEmit.ts
11724
+ function resolveWxmlEmitContext(compiler) {
11725
+ const { wxmlService, configService, scanService } = compiler;
11726
+ if (!wxmlService || !configService || !scanService) throw new Error("emitWxmlAssets 需要先初始化 wxmlService、configService 和 scanService。");
11727
+ const { templateExtension, scriptModuleExtension } = resolveCompilerOutputExtensions(configService.outputExtensions);
11728
+ return {
11729
+ wxmlService,
11730
+ configService,
11731
+ scanService,
11732
+ templateExtension,
11733
+ scriptModuleExtension,
11734
+ scriptModuleTag: resolveScriptModuleTagName({
11735
+ platform: configService.platform,
11736
+ scriptModuleExtension
11737
+ })
11704
11738
  };
11705
11739
  }
11706
- //#endregion
11707
- //#region src/plugins/hooks/useLoadEntry/loadEntry/template.ts
11708
- function collectVueTemplateComponentNames(template, filename) {
11709
- return collectVueTemplateTags(template, {
11710
- filename,
11711
- warnLabel: "自动 usingComponents",
11712
- shouldCollect: (tag) => VUE_COMPONENT_TAG_RE.test(tag)
11740
+ function resolveWxmlEmitTargets(options) {
11741
+ const { compiler, subPackageMeta, buildTarget = "app" } = options;
11742
+ const { wxmlService, configService, scanService, templateExtension } = resolveWxmlEmitContext(compiler);
11743
+ return Array.from(wxmlService.tokenMap.entries()).filter(([id]) => isTemplate(id)).map(([id, token]) => {
11744
+ return {
11745
+ id,
11746
+ token,
11747
+ fileName: resolveRelativeOutputFileNameWithExtension(configService, id, templateExtension)
11748
+ };
11749
+ }).filter(({ id, fileName }) => {
11750
+ if (subPackageMeta) return fileName.startsWith(subPackageMeta.subPackage.root);
11751
+ if (buildTarget === "plugin") {
11752
+ const pluginRoot = configService.absolutePluginRoot;
11753
+ if (!pluginRoot) return false;
11754
+ return isPathInside(pluginRoot, id);
11755
+ }
11756
+ return scanService.isMainPackageFileName(fileName);
11713
11757
  });
11714
11758
  }
11715
- function collectVueTemplateAutoImportTags(template, filename) {
11716
- return collectVueTemplateTags(template, {
11717
- filename,
11718
- warnLabel: "自动导入标签",
11719
- shouldCollect: isAutoImportCandidateTag
11759
+ function emitWxmlAssetFile(options) {
11760
+ const { runtime, id, fileName, token, deps, emittedCodeCache, scriptModuleExtension, scriptModuleTag, templateExtension } = options;
11761
+ runtime.addWatchFile?.(normalizeWatchPath(id));
11762
+ if (deps) for (const dep of deps) runtime.addWatchFile?.(normalizeWatchPath(dep));
11763
+ const result = handleWxml(token, {
11764
+ scriptModuleExtension,
11765
+ scriptModuleTag,
11766
+ templateExtension
11720
11767
  });
11768
+ if (emittedCodeCache.get(fileName) === result.code) return false;
11769
+ emittedCodeCache.set(fileName, result.code);
11770
+ runtime.emitFile({
11771
+ type: "asset",
11772
+ fileName,
11773
+ source: result.code
11774
+ });
11775
+ return true;
11721
11776
  }
11722
- function collectScriptSetupImports(scriptSetup, templateComponentNames, options) {
11723
- return collectScriptSetupImportsFromCode(scriptSetup, templateComponentNames, options);
11724
- }
11725
- async function scanTemplateEntry(pluginCtx, id, scanTemplateEntryFn, existsCache, ttlMs) {
11726
- return ensureTemplateScanned(pluginCtx, id, scanTemplateEntryFn, existsCache, ttlMs);
11777
+ function emitWxmlAssetsWithCache(options) {
11778
+ const { runtime, compiler, subPackageMeta, emittedCodeCache, buildTarget = "app" } = options;
11779
+ const { wxmlService, templateExtension, scriptModuleExtension, scriptModuleTag } = resolveWxmlEmitContext(compiler);
11780
+ const currentPackageWxmls = resolveWxmlEmitTargets({
11781
+ compiler,
11782
+ subPackageMeta,
11783
+ buildTarget
11784
+ });
11785
+ const emittedFiles = [];
11786
+ for (const { id, fileName, token } of currentPackageWxmls) {
11787
+ emittedFiles.push(fileName);
11788
+ emitWxmlAssetFile({
11789
+ runtime,
11790
+ id,
11791
+ fileName,
11792
+ token,
11793
+ deps: wxmlService.depsMap.get(id),
11794
+ emittedCodeCache,
11795
+ scriptModuleExtension,
11796
+ scriptModuleTag,
11797
+ templateExtension
11798
+ });
11799
+ }
11800
+ return emittedFiles;
11727
11801
  }
11728
- async function applyScriptSetupUsingComponents(options) {
11729
- const { pluginCtx, vueEntryPath, templatePath, json, configService, wxmlService, reExportResolutionCache } = options;
11730
- try {
11731
- const { descriptor, errors } = await readAndParseSfc(vueEntryPath, { ...createReadAndParseSfcOptions(pluginCtx, configService) });
11732
- if (!errors?.length && descriptor?.template && !templatePath) {
11733
- const tags = collectVueTemplateAutoImportTags(descriptor.template.content, vueEntryPath);
11734
- if (tags.size) {
11735
- const components = Object.fromEntries(Array.from(tags, (tag) => [tag, [{
11736
- start: 0,
11737
- end: 0
11738
- }]]));
11739
- wxmlService?.setWxmlComponentsMap(vueEntryPath, components);
11802
+ function emitJsonAsset(runtime, fileName, source, extension = "json") {
11803
+ runtime.emitFile({
11804
+ type: "asset",
11805
+ fileName: changeFileExtension(fileName, extension),
11806
+ source
11807
+ });
11808
+ }
11809
+ //#endregion
11810
+ //#region src/plugins/hooks/useLoadEntry/loadEntry/emit.ts
11811
+ const NON_VUE_PAGE_RE = /\.vue$|\.jsx$|\.tsx$/;
11812
+ function prepareNormalizedEntries(options) {
11813
+ const { entries, json, jsonPath, templatePath, id, skipOwnEntries, entriesMap, normalizeEntry, extendedLibManager, entryType, explicitEntryTypes } = options;
11814
+ const filteredEntries = skipOwnEntries ? [] : entries.filter((entry) => !extendedLibManager.shouldIgnoreEntry(entry));
11815
+ const normalizedEntries = skipOwnEntries ? [] : filteredEntries.map((entry) => normalizeEntry(entry, jsonPath));
11816
+ if (!skipOwnEntries) for (const normalizedEntry of normalizedEntries) {
11817
+ const resolvedEntryType = explicitEntryTypes?.get(normalizedEntry) ?? entryType ?? (json.component ? "component" : "page");
11818
+ entriesMap.set(normalizedEntry, {
11819
+ type: resolvedEntryType,
11820
+ templatePath,
11821
+ jsonPath,
11822
+ json,
11823
+ path: id
11824
+ });
11825
+ }
11826
+ return normalizedEntries;
11827
+ }
11828
+ async function emitEntryOutput(options) {
11829
+ const { pluginCtx, id, type, json: initialJson, jsonPath, templatePath, isPluginBuild, normalizedEntries, pluginResolvedRecords, pluginJsonPathForRegistration, pluginJsonForRegistration, resolveEntriesWithCache, entryResolveRoot, configService, wxmlService, resolvedEntryMap, loadedEntrySet, dirtyEntrySet, replaceLayoutDependencies, emitEntriesChunks, registerJsonAsset, existsCache, pathExistsTtlMs, debug, relativeCwdId, getTime, emittedWxmlCodeCache } = options;
11830
+ let json = initialJson;
11831
+ async function emitNativeLayoutAssets(layoutBasePath) {
11832
+ if (typeof pluginCtx.emitFile !== "function") return;
11833
+ const resolvedOptions = resolveNativeLayoutOutputOptions({
11834
+ configService,
11835
+ layoutBasePath,
11836
+ outputExtensions: configService.outputExtensions
11837
+ });
11838
+ if (!resolvedOptions) return;
11839
+ const assets = await collectNativeLayoutAssets(layoutBasePath);
11840
+ const emittedLayoutAssets = pluginCtx.__weappViteNativeLayoutAssets ?? (pluginCtx.__weappViteNativeLayoutAssets = /* @__PURE__ */ new Set());
11841
+ if (assets.json) registerJsonAsset({
11842
+ jsonPath: assets.json,
11843
+ json: JSON.parse(await fs$1.readFile(assets.json, "utf8")),
11844
+ type: "component"
11845
+ });
11846
+ const assetEntries = await resolveNativeLayoutStaticAssetEntries({
11847
+ assets,
11848
+ resolvedOptions,
11849
+ readFile: fs$1.readFile
11850
+ });
11851
+ const emittedCodeCache = emittedWxmlCodeCache ?? /* @__PURE__ */ new Map();
11852
+ const wxmlEmitContext = wxmlService ? resolveWxmlEmitContext({
11853
+ wxmlService,
11854
+ configService,
11855
+ scanService: { isMainPackageFileName: () => true }
11856
+ }) : void 0;
11857
+ for (const asset of assetEntries) {
11858
+ if (emittedLayoutAssets.has(asset.fileName)) continue;
11859
+ if (asset.kind === "template" && assets.template && wxmlService && wxmlEmitContext) {
11860
+ const token = wxmlService.analyze(asset.source);
11861
+ wxmlService.tokenMap.set(assets.template, token);
11862
+ const deps = wxmlService.collectDepsFromToken(assets.template, token.deps);
11863
+ await wxmlService.setDeps(assets.template, deps);
11864
+ wxmlService.setWxmlComponentsMap(assets.template, token.components);
11865
+ emitWxmlAssetFile({
11866
+ runtime: {
11867
+ addWatchFile: pluginCtx.addWatchFile?.bind(pluginCtx),
11868
+ emitFile: (payload) => pluginCtx.emitFile(payload)
11869
+ },
11870
+ id: assets.template,
11871
+ fileName: asset.fileName,
11872
+ token,
11873
+ deps: wxmlService.depsMap.get(assets.template),
11874
+ emittedCodeCache,
11875
+ scriptModuleExtension: wxmlEmitContext.scriptModuleExtension,
11876
+ scriptModuleTag: wxmlEmitContext.scriptModuleTag,
11877
+ templateExtension: wxmlEmitContext.templateExtension
11878
+ });
11879
+ emittedLayoutAssets.add(asset.fileName);
11880
+ continue;
11740
11881
  }
11882
+ emittedLayoutAssets.add(asset.fileName);
11883
+ pluginCtx.emitFile({
11884
+ type: "asset",
11885
+ fileName: asset.fileName,
11886
+ source: asset.source
11887
+ });
11741
11888
  }
11742
- if (!errors?.length && descriptor?.scriptSetup && descriptor?.template) {
11743
- const templateComponentNames = collectVueTemplateComponentNames(descriptor.template.content, vueEntryPath);
11744
- if (templateComponentNames.size) {
11745
- const astEngine = resolveAstEngine(configService.weappViteConfig);
11746
- const imports = collectScriptSetupImports(descriptor.scriptSetup.content, templateComponentNames, { astEngine });
11747
- if (imports.length) {
11748
- const usingComponents = json && typeof json.usingComponents === "object" && json.usingComponents && !Array.isArray(json.usingComponents) ? json.usingComponents : {};
11749
- for (const { localName, importSource, importedName, kind } of imports) {
11750
- let { from } = await resolveUsingComponentReference(pluginCtx, configService, reExportResolutionCache, importSource, vueEntryPath, {
11751
- kind,
11752
- importedName,
11753
- fallbackRelativeImporterDir: true
11754
- });
11755
- if (!from && importSource.startsWith("/")) from = removeExtensionDeep(importSource);
11756
- if (!from) continue;
11757
- if (Reflect.has(usingComponents, localName) && usingComponents[localName] !== from) logger_default.warn(`[自动 usingComponents] 冲突:${vueEntryPath} 中 usingComponents['${localName}']='${usingComponents[localName]}' 将被 <script setup> 导入覆盖为 '${from}'`);
11758
- usingComponents[localName] = from;
11759
- }
11760
- json.usingComponents = usingComponents;
11761
- }
11889
+ emitNativeLayoutScriptChunkIfNeeded$1({
11890
+ pluginCtx,
11891
+ scriptId: assets.script,
11892
+ fileName: `${resolvedOptions.relativeBase}.${resolvedOptions.scriptExtension}`
11893
+ });
11894
+ }
11895
+ const shouldSkipEntries = Boolean(options.skipEntries);
11896
+ const resolvedIds = shouldSkipEntries ? [] : normalizedEntries.length ? await resolveEntriesWithCache(pluginCtx, normalizedEntries, entryResolveRoot) : [];
11897
+ debug?.(`resolvedIds ${relativeCwdId} 耗时 ${getTime()}`);
11898
+ const pendingResolvedIds = [];
11899
+ const combinedResolved = shouldSkipEntries ? [] : pluginResolvedRecords ? isPluginBuild ? pluginResolvedRecords : [...resolvedIds, ...pluginResolvedRecords] : resolvedIds;
11900
+ const pluginEntrySet = shouldSkipEntries || !pluginResolvedRecords ? void 0 : new Set(pluginResolvedRecords.map((record) => record.entry));
11901
+ for (const { entry, resolvedId } of combinedResolved) {
11902
+ if (!resolvedId) {
11903
+ if (pluginEntrySet?.has(entry)) logger_default.warn(`没有找到插件入口 \`${entry}\` 对应的脚本文件,请检查路径是否正确!`);
11904
+ else logger_default.warn(`没有找到 \`${entry}\` 的入口文件,请检查路径是否正确!`);
11905
+ continue;
11906
+ }
11907
+ const normalizedResolvedId = normalizeFsResolvedId(resolvedId.id);
11908
+ if (normalizedResolvedId && !isSkippableResolvedId(normalizedResolvedId) && path.isAbsolute(normalizedResolvedId)) addNormalizedWatchFile(pluginCtx, normalizedResolvedId);
11909
+ if (normalizedResolvedId && !isSkippableResolvedId(normalizedResolvedId)) resolvedEntryMap.set(normalizedResolvedId, resolvedId);
11910
+ const isDirtyEntry = dirtyEntrySet.has(normalizedResolvedId);
11911
+ if (!isDirtyEntry && loadedEntrySet.has(normalizedResolvedId)) continue;
11912
+ pendingResolvedIds.push(resolvedId);
11913
+ if (isDirtyEntry) dirtyEntrySet.delete(normalizedResolvedId);
11914
+ }
11915
+ if (pendingResolvedIds.length) await Promise.all(emitEntriesChunks.call(pluginCtx, pendingResolvedIds));
11916
+ debug?.(`emitEntriesChunks ${relativeCwdId} 耗时 ${getTime()}`);
11917
+ let code = await readFile$1(id, { checkMtime: configService.isDev });
11918
+ if (type === "page" && templatePath && !NON_VUE_PAGE_RE.test(id)) {
11919
+ replaceLayoutDependencies(id, []);
11920
+ const layoutPlan = await resolvePageLayoutPlan(code, id, configService);
11921
+ if (layoutPlan) {
11922
+ const layoutDependencies = /* @__PURE__ */ new Set();
11923
+ for (const file of await expandResolvedPageLayoutFiles(layoutPlan.layouts)) {
11924
+ addNormalizedWatchFile(pluginCtx, file);
11925
+ layoutDependencies.add(normalizeFsResolvedId(file));
11926
+ }
11927
+ replaceLayoutDependencies(id, layoutDependencies);
11928
+ const nativeTemplate = await readFile$1(templatePath, { checkMtime: configService.isDev });
11929
+ const transformed = applyPageLayoutPlanToNativePage({
11930
+ script: code,
11931
+ template: nativeTemplate,
11932
+ config: JSON.stringify(json)
11933
+ }, id, layoutPlan);
11934
+ code = transformed.script ?? code;
11935
+ if (transformed.config) json = JSON.parse(transformed.config);
11936
+ if (transformed.template && wxmlService) {
11937
+ const token = wxmlService.analyze(transformed.template);
11938
+ wxmlService.tokenMap.set(templatePath, token);
11939
+ wxmlService.setDeps(templatePath, wxmlService.collectDepsFromToken(templatePath, token.deps));
11940
+ wxmlService.setWxmlComponentsMap(templatePath, token.components);
11762
11941
  }
11942
+ for (const layout of layoutPlan.layouts) if (layout.kind === "native") await emitNativeLayoutAssets(layout.file);
11763
11943
  }
11764
- } catch (error) {
11765
- const message = error instanceof Error ? error.message : String(error);
11766
- logger_default.warn(`[自动 usingComponents] 解析失败:${vueEntryPath}:${message}`);
11944
+ code = injectNativePageLayoutRuntime(code, id, layoutPlan) ?? code;
11767
11945
  }
11946
+ if (!isPluginBuild || type !== "app") registerJsonAsset({
11947
+ jsonPath,
11948
+ json,
11949
+ type
11950
+ });
11951
+ if (pluginJsonPathForRegistration && pluginJsonForRegistration) registerJsonAsset({
11952
+ jsonPath: pluginJsonPathForRegistration,
11953
+ json: pluginJsonForRegistration,
11954
+ type: "plugin"
11955
+ });
11956
+ const styleImports = await collectStyleImports(pluginCtx, id, existsCache, pathExistsTtlMs);
11957
+ debug?.(`loadEntry ${relativeCwdId} 耗时 ${getTime()}`);
11958
+ if (styleImports.length === 0) return { code };
11959
+ const ms = new MagicString(code);
11960
+ for (const styleImport of styleImports) ms.prepend(`import '${styleImport}';\n`);
11961
+ return { code: ms.toString() };
11768
11962
  }
11769
11963
  //#endregion
11770
- //#region src/plugins/hooks/useLoadEntry/loadEntry/index.ts
11771
- function createStopwatch() {
11772
- const start = performance$1.now();
11773
- return () => `${(performance$1.now() - start).toFixed(2)}ms`;
11774
- }
11775
- function createEntryLoader(options) {
11776
- const { ctx, entriesMap, loadedEntrySet, dirtyEntrySet, resolvedEntryMap, replaceLayoutDependencies, normalizeEntry, registerJsonAsset, scanTemplateEntry: scanTemplateEntryFn, emitEntriesChunks, applyAutoImports, extendedLibManager, debug } = options;
11777
- const isPluginBuild = (options.buildTarget ?? "app") === "plugin";
11778
- const { jsonService, configService, wxmlService } = ctx;
11779
- const existsCache = /* @__PURE__ */ new Map();
11780
- const pathExistsTtlMs = getPathExistsTtlMs(configService);
11781
- const reExportResolutionCache = /* @__PURE__ */ new Map();
11782
- const entryResolver = createEntryResolver(configService);
11783
- const appEntriesCache = {};
11784
- const appEntryOutputCache = {};
11785
- const emittedScriptlessVueLayoutJs = /* @__PURE__ */ new Set();
11786
- const scriptlessVueLayoutDecisionCache = /* @__PURE__ */ new Map();
11787
- let resolveCacheVersion = 0;
11788
- const shouldEmitScriptlessVueLayoutJs$1 = async (layoutFile) => {
11789
- const cached = scriptlessVueLayoutDecisionCache.get(layoutFile);
11790
- if (cached) return await cached;
11791
- const task = (async () => {
11792
- return shouldEmitScriptlessVueLayoutJs(await fs.readFile(layoutFile, "utf-8"), layoutFile);
11793
- })();
11794
- scriptlessVueLayoutDecisionCache.set(layoutFile, task);
11795
- try {
11796
- return await task;
11797
- } catch (error) {
11798
- scriptlessVueLayoutDecisionCache.delete(layoutFile);
11799
- throw error;
11964
+ //#region src/plugins/hooks/useLoadEntry/loadEntry/resolve.ts
11965
+ function createEntryResolver(configService) {
11966
+ const entryResolutionCache = /* @__PURE__ */ new Map();
11967
+ async function resolveEntryWithCache(pluginCtx, absPath) {
11968
+ const normalized = path.normalize(absPath);
11969
+ if (entryResolutionCache.has(normalized)) return entryResolutionCache.get(normalized) ?? null;
11970
+ let resolvedSource = normalized;
11971
+ if (!path.extname(normalized)) {
11972
+ const matched = await resolveEntryPath(normalized, createCachedEntryResolveOptions(configService ?? {}, { kind: "default" }));
11973
+ if (matched) resolvedSource = matched;
11974
+ }
11975
+ const resolvedId = await pluginCtx.resolve(resolvedSource) ?? (path.isAbsolute(resolvedSource) && await fs.pathExists(resolvedSource) ? { id: resolvedSource } : null);
11976
+ entryResolutionCache.set(normalized, resolvedId);
11977
+ return resolvedId;
11978
+ }
11979
+ async function resolveEntriesWithCache(pluginCtx, entries, absoluteRoot) {
11980
+ return Promise.all(entries.filter((entry) => !entry.includes(":")).map(async (entry) => {
11981
+ return {
11982
+ entry,
11983
+ resolvedId: await resolveEntryWithCache(pluginCtx, path.resolve(absoluteRoot, entry))
11984
+ };
11985
+ }));
11986
+ }
11987
+ return {
11988
+ resolveEntryWithCache,
11989
+ resolveEntriesWithCache,
11990
+ invalidate() {
11991
+ entryResolutionCache.clear();
11800
11992
  }
11801
11993
  };
11802
- return Object.assign(async function loadEntry(id, type) {
11803
- existsCache.clear();
11804
- const stopwatch = debug ? createStopwatch() : void 0;
11805
- const getTime = () => stopwatch ? stopwatch() : "0.00ms";
11806
- const relativeCwdId = configService.relativeCwd(id);
11807
- const normalizedId = normalizeFsResolvedId(id);
11808
- const libConfig = configService.weappLibConfig;
11994
+ }
11995
+ //#endregion
11996
+ //#region src/plugins/utils/vueSfc.ts
11997
+ function createSfcResolveSrcOptions(pluginCtx, configService) {
11998
+ return {
11999
+ resolveId: async (source, importer) => {
12000
+ if (typeof pluginCtx.resolve !== "function") return;
12001
+ return (await pluginCtx.resolve(source, importer))?.id;
12002
+ },
12003
+ checkMtime: getSfcCheckMtime(configService)
12004
+ };
12005
+ }
12006
+ function createReadAndParseSfcOptions(pluginCtx, configService, options) {
12007
+ const resolveCheckMtime = getSfcCheckMtime(configService);
12008
+ return {
12009
+ source: options?.source,
12010
+ checkMtime: options?.checkMtime ?? resolveCheckMtime,
12011
+ resolveSrc: createSfcResolveSrcOptions(pluginCtx, configService)
12012
+ };
12013
+ }
12014
+ //#endregion
12015
+ //#region src/plugins/vue/transform/usingComponentResolver.ts
12016
+ const JS_LIKE_FILE_RE = /\.(?:[cm]?ts|[cm]?js)$/;
12017
+ async function resolveUsingComponentReference(ctx, configService, reExportResolutionCache, importSource, importerFilename, info) {
12018
+ const resolved = await ctx.resolve(importSource, importerFilename);
12019
+ let clean = resolved?.id ? normalizeFsResolvedId(resolved.id) : void 0;
12020
+ if ((!clean || !path.isAbsolute(clean)) && info?.fallbackRelativeImporterDir && importSource.startsWith(".")) clean = path.resolve(path.dirname(importerFilename), importSource);
12021
+ if (!clean) return {
12022
+ resolvedId: void 0,
12023
+ from: void 0
12024
+ };
12025
+ if (isSkippableResolvedId(clean)) return {
12026
+ resolvedId: void 0,
12027
+ from: void 0
12028
+ };
12029
+ if (path.isAbsolute(clean)) {
12030
+ const resolvedEntry = await resolveEntryPath(clean, createCachedEntryResolveOptions(configService ?? {}, { kind: info?.kind ?? "default" }));
12031
+ if (resolvedEntry) clean = resolvedEntry;
12032
+ }
12033
+ if (info?.kind === "named" && info.importedName && JS_LIKE_FILE_RE.test(clean)) {
12034
+ const exportName = info.importedName;
12035
+ const mapped = await resolveReExportedName(clean, exportName, {
12036
+ astEngine: resolveAstEngine(configService.weappViteConfig),
12037
+ cache: reExportResolutionCache,
12038
+ maxDepth: 4,
12039
+ readFile: (file) => readFile$1(file, { checkMtime: getReadFileCheckMtime(configService) }),
12040
+ resolveId: async (source, importer) => {
12041
+ const hop = await ctx.resolve(source, importer);
12042
+ const hopId = hop?.id ? normalizeFsResolvedId(hop.id) : void 0;
12043
+ if (isSkippableResolvedId(hopId)) return;
12044
+ return hopId;
12045
+ }
12046
+ });
12047
+ if (mapped) clean = mapped;
12048
+ }
12049
+ return {
12050
+ resolvedId: clean,
12051
+ from: usingComponentFromResolvedFile(clean, configService)
12052
+ };
12053
+ }
12054
+ async function resolveUsingComponentPath(ctx, configService, reExportResolutionCache, importSource, importerFilename, info) {
12055
+ return (await resolveUsingComponentReference(ctx, configService, reExportResolutionCache, importSource, importerFilename, info)).from;
12056
+ }
12057
+ function createUsingComponentPathResolver(ctx, configService, reExportResolutionCache) {
12058
+ return async (importSource, importerFilename, info) => {
12059
+ return resolveUsingComponentPath(ctx, configService, reExportResolutionCache, importSource, importerFilename, info);
12060
+ };
12061
+ }
12062
+ //#endregion
12063
+ //#region src/plugins/hooks/useLoadEntry/loadEntry/template.ts
12064
+ function collectVueTemplateComponentNames(template, filename) {
12065
+ return collectVueTemplateTags(template, {
12066
+ filename,
12067
+ warnLabel: "自动 usingComponents",
12068
+ shouldCollect: (tag) => VUE_COMPONENT_TAG_RE.test(tag)
12069
+ });
12070
+ }
12071
+ function collectVueTemplateAutoImportTags(template, filename) {
12072
+ return collectVueTemplateTags(template, {
12073
+ filename,
12074
+ warnLabel: "自动导入标签",
12075
+ shouldCollect: isAutoImportCandidateTag
12076
+ });
12077
+ }
12078
+ function collectScriptSetupImports(scriptSetup, templateComponentNames, options) {
12079
+ return collectScriptSetupImportsFromCode(scriptSetup, templateComponentNames, options);
12080
+ }
12081
+ async function scanTemplateEntry(pluginCtx, id, scanTemplateEntryFn, existsCache, ttlMs) {
12082
+ return ensureTemplateScanned(pluginCtx, id, scanTemplateEntryFn, existsCache, ttlMs);
12083
+ }
12084
+ async function applyScriptSetupUsingComponents(options) {
12085
+ const { pluginCtx, vueEntryPath, templatePath, json, configService, wxmlService, reExportResolutionCache } = options;
12086
+ try {
12087
+ const { descriptor, errors } = await readAndParseSfc(vueEntryPath, { ...createReadAndParseSfcOptions(pluginCtx, configService) });
12088
+ if (!errors?.length && descriptor?.template && !templatePath) {
12089
+ const tags = collectVueTemplateAutoImportTags(descriptor.template.content, vueEntryPath);
12090
+ if (tags.size) {
12091
+ const components = Object.fromEntries(Array.from(tags, (tag) => [tag, [{
12092
+ start: 0,
12093
+ end: 0
12094
+ }]]));
12095
+ wxmlService?.setWxmlComponentsMap(vueEntryPath, components);
12096
+ }
12097
+ }
12098
+ if (!errors?.length && descriptor?.scriptSetup && descriptor?.template) {
12099
+ const templateComponentNames = collectVueTemplateComponentNames(descriptor.template.content, vueEntryPath);
12100
+ if (templateComponentNames.size) {
12101
+ const astEngine = resolveAstEngine(configService.weappViteConfig);
12102
+ const imports = collectScriptSetupImports(descriptor.scriptSetup.content, templateComponentNames, { astEngine });
12103
+ if (imports.length) {
12104
+ const usingComponents = json && typeof json.usingComponents === "object" && json.usingComponents && !Array.isArray(json.usingComponents) ? json.usingComponents : {};
12105
+ for (const { localName, importSource, importedName, kind } of imports) {
12106
+ let { from } = await resolveUsingComponentReference(pluginCtx, configService, reExportResolutionCache, importSource, vueEntryPath, {
12107
+ kind,
12108
+ importedName,
12109
+ fallbackRelativeImporterDir: true
12110
+ });
12111
+ if (!from && importSource.startsWith("/")) from = removeExtensionDeep(importSource);
12112
+ if (!from) continue;
12113
+ if (Reflect.has(usingComponents, localName) && usingComponents[localName] !== from) logger_default.warn(`[自动 usingComponents] 冲突:${vueEntryPath} 中 usingComponents['${localName}']='${usingComponents[localName]}' 将被 <script setup> 导入覆盖为 '${from}'`);
12114
+ usingComponents[localName] = from;
12115
+ }
12116
+ json.usingComponents = usingComponents;
12117
+ }
12118
+ }
12119
+ }
12120
+ } catch (error) {
12121
+ const message = error instanceof Error ? error.message : String(error);
12122
+ logger_default.warn(`[自动 usingComponents] 解析失败:${vueEntryPath}:${message}`);
12123
+ }
12124
+ }
12125
+ //#endregion
12126
+ //#region src/plugins/hooks/useLoadEntry/loadEntry/index.ts
12127
+ function createStopwatch() {
12128
+ const start = performance$1.now();
12129
+ return () => `${(performance$1.now() - start).toFixed(2)}ms`;
12130
+ }
12131
+ function createEntryLoader(options) {
12132
+ const { ctx, entriesMap, loadedEntrySet, dirtyEntrySet, resolvedEntryMap, replaceLayoutDependencies, normalizeEntry, registerJsonAsset, scanTemplateEntry: scanTemplateEntryFn, emitEntriesChunks, applyAutoImports, extendedLibManager, debug } = options;
12133
+ const isPluginBuild = (options.buildTarget ?? "app") === "plugin";
12134
+ const { jsonService, configService, wxmlService } = ctx;
12135
+ const existsCache = /* @__PURE__ */ new Map();
12136
+ const pathExistsTtlMs = getPathExistsTtlMs(configService);
12137
+ const reExportResolutionCache = /* @__PURE__ */ new Map();
12138
+ const entryResolver = createEntryResolver(configService);
12139
+ const appEntriesCache = {};
12140
+ const appEntryOutputCache = {};
12141
+ const emittedScriptlessVueLayoutJs = /* @__PURE__ */ new Set();
12142
+ const scriptlessVueLayoutDecisionCache = /* @__PURE__ */ new Map();
12143
+ let resolveCacheVersion = 0;
12144
+ const shouldEmitScriptlessVueLayoutJs$1 = async (layoutFile) => {
12145
+ const cached = scriptlessVueLayoutDecisionCache.get(layoutFile);
12146
+ if (cached) return await cached;
12147
+ const task = (async () => {
12148
+ return shouldEmitScriptlessVueLayoutJs(await fs.readFile(layoutFile, "utf-8"), layoutFile);
12149
+ })();
12150
+ scriptlessVueLayoutDecisionCache.set(layoutFile, task);
12151
+ try {
12152
+ return await task;
12153
+ } catch (error) {
12154
+ scriptlessVueLayoutDecisionCache.delete(layoutFile);
12155
+ throw error;
12156
+ }
12157
+ };
12158
+ return Object.assign(async function loadEntry(id, type) {
12159
+ existsCache.clear();
12160
+ const stopwatch = debug ? createStopwatch() : void 0;
12161
+ const getTime = () => stopwatch ? stopwatch() : "0.00ms";
12162
+ const relativeCwdId = configService.relativeCwd(id);
12163
+ const normalizedId = normalizeFsResolvedId(id);
12164
+ const libConfig = configService.weappLibConfig;
11809
12165
  const libEntry = libConfig?.enabled && normalizedId ? ctx.runtimeState.lib.entries.get(normalizedId) : void 0;
11810
12166
  addNormalizedWatchFile(this, id);
11811
12167
  const baseName = removeExtensionDeep(id);
@@ -11971,6 +12327,7 @@ function createEntryLoader(options) {
11971
12327
  debug,
11972
12328
  relativeCwdId,
11973
12329
  getTime,
12330
+ emittedWxmlCodeCache: ctx.runtimeState?.wxml?.emittedCode,
11974
12331
  skipEntries: shouldSkipAppEntries
11975
12332
  });
11976
12333
  if (type === "app" && !shouldSkipAppEntries && appResult) appEntryOutputCache.current = {
@@ -11985,497 +12342,169 @@ function createEntryLoader(options) {
11985
12342
  entryResolver.invalidate();
11986
12343
  scriptlessVueLayoutDecisionCache.clear();
11987
12344
  resolveCacheVersion += 1;
11988
- appEntryOutputCache.current = void 0;
11989
- } });
11990
- }
11991
- //#endregion
11992
- //#region src/plugins/hooks/useLoadEntry/normalizer.ts
11993
- const PLUGIN_PROTOCOL_RE = /plugin:\/\//;
11994
- const WINDOWS_PATH_SEPARATOR_RE = /\\/g;
11995
- function resolveImportee(importee, jsonPath, configService) {
11996
- let updated = importee;
11997
- if (jsonPath && Array.isArray(configService.aliasEntries)) {
11998
- const matchedEntry = configService.aliasEntries.find((entry) => matches(entry.find, importee));
11999
- if (matchedEntry) updated = importee.replace(matchedEntry.find, matchedEntry.replacement);
12000
- }
12001
- const baseDir = jsonPath ? path.dirname(jsonPath) : configService.absoluteSrcRoot;
12002
- return path.resolve(baseDir, updated);
12003
- }
12004
- function createEntryNormalizer(configService) {
12005
- return function normalizeEntry(entry, jsonPath) {
12006
- if (PLUGIN_PROTOCOL_RE.test(entry)) return entry;
12007
- const normalizedEntry = normalizeNpmImportLookupPath(entry);
12008
- if (normalizedEntry && isObject(configService.packageJson.dependencies) && hasNpmDependencyPrefix(configService.packageJson.dependencies, normalizedEntry)) return `npm:${normalizedEntry}`;
12009
- if (entry.replace(WINDOWS_PATH_SEPARATOR_RE, "/").startsWith("/")) return normalizedEntry;
12010
- const normalized = resolveImportee(normalizedEntry, jsonPath, configService);
12011
- return configService.relativeAbsoluteSrcRoot(normalized);
12012
- };
12013
- }
12014
- //#endregion
12015
- //#region src/plugins/hooks/useLoadEntry/template.ts
12016
- function createTemplateScanner(wxmlService, debug) {
12017
- return async function scanTemplateEntry(templateEntry) {
12018
- const start = performance$1.now();
12019
- const wxmlToken = await wxmlService.scan(templateEntry);
12020
- if (wxmlToken) {
12021
- const { components } = wxmlToken;
12022
- wxmlService.setWxmlComponentsMap(templateEntry, components);
12023
- }
12024
- debug?.(`scanTemplateEntry ${templateEntry} 耗时 ${(performance$1.now() - start).toFixed(2)}ms`);
12025
- };
12026
- }
12027
- //#endregion
12028
- //#region src/plugins/hooks/useLoadEntry/index.ts
12029
- function useLoadEntry(ctx, options) {
12030
- const debug = createDebugger("weapp-vite:load-entry");
12031
- const buildTarget = options?.buildTarget ?? "app";
12032
- const entriesMap = /* @__PURE__ */ new Map();
12033
- const loadedEntrySet = /* @__PURE__ */ new Set();
12034
- const dirtyEntrySet = /* @__PURE__ */ new Set();
12035
- const dirtyEntryReasons = /* @__PURE__ */ new Map();
12036
- const resolvedEntryMap = /* @__PURE__ */ new Map();
12037
- const layoutEntryDependents = /* @__PURE__ */ new Map();
12038
- const entryLayoutDependencies = /* @__PURE__ */ new Map();
12039
- const jsonEmitManager = createJsonEmitManager(ctx.configService);
12040
- const registerJsonAsset = jsonEmitManager.register.bind(jsonEmitManager);
12041
- const normalizeEntry = createEntryNormalizer(ctx.configService);
12042
- const scanTemplateEntry = createTemplateScanner(ctx.wxmlService, debug);
12043
- const emitEntriesChunks = createChunkEmitter(ctx.configService, loadedEntrySet, debug);
12044
- const loadEntry = createEntryLoader({
12045
- ctx,
12046
- entriesMap,
12047
- loadedEntrySet,
12048
- dirtyEntrySet,
12049
- resolvedEntryMap,
12050
- replaceLayoutDependencies(entryId, dependencies) {
12051
- const previousDependencies = entryLayoutDependencies.get(entryId);
12052
- if (previousDependencies) for (const dependency of previousDependencies) {
12053
- const dependents = layoutEntryDependents.get(dependency);
12054
- if (!dependents) continue;
12055
- dependents.delete(entryId);
12056
- if (dependents.size === 0) layoutEntryDependents.delete(dependency);
12057
- }
12058
- const normalizedDependencies = new Set(dependencies);
12059
- if (normalizedDependencies.size === 0) {
12060
- entryLayoutDependencies.delete(entryId);
12061
- return;
12062
- }
12063
- entryLayoutDependencies.set(entryId, normalizedDependencies);
12064
- for (const dependency of normalizedDependencies) {
12065
- let dependents = layoutEntryDependents.get(dependency);
12066
- if (!dependents) {
12067
- dependents = /* @__PURE__ */ new Set();
12068
- layoutEntryDependents.set(dependency, dependents);
12069
- }
12070
- dependents.add(entryId);
12071
- }
12072
- },
12073
- normalizeEntry,
12074
- registerJsonAsset,
12075
- scanTemplateEntry,
12076
- emitEntriesChunks,
12077
- applyAutoImports: createAutoImportAugmenter(ctx.autoImportService, ctx.wxmlService),
12078
- extendedLibManager: createExtendedLibManager(),
12079
- buildTarget,
12080
- debug
12081
- });
12082
- const hmrSharedChunksMode = options?.hmr?.sharedChunks ?? "auto";
12083
- const hmrSharedChunkImporters = options?.hmr?.sharedChunkImporters;
12084
- return {
12085
- loadEntry,
12086
- entriesMap,
12087
- loadedEntrySet,
12088
- dirtyEntrySet,
12089
- resolvedEntryMap,
12090
- layoutEntryDependents,
12091
- jsonEmitFilesMap: jsonEmitManager.map,
12092
- normalizeEntry,
12093
- markEntryDirty(entryId, reason = "direct") {
12094
- dirtyEntrySet.add(entryId);
12095
- dirtyEntryReasons.set(entryId, reason);
12096
- loadedEntrySet.delete(entryId);
12097
- },
12098
- async emitDirtyEntries() {
12099
- if (!dirtyEntrySet.size) {
12100
- options?.hmr?.setDidEmitAllEntries?.(false);
12101
- options?.hmr?.setLastEmittedEntries?.(/* @__PURE__ */ new Set());
12102
- return;
12103
- }
12104
- const dirtyCount = dirtyEntrySet.size;
12105
- const pendingEntryIds = resolvePendingEntryIds({
12106
- isDev: Boolean(ctx.configService?.isDev),
12107
- mode: hmrSharedChunksMode,
12108
- resolvedEntryMap,
12109
- dirtyEntrySet,
12110
- dirtyEntryReasons,
12111
- sharedChunkImporters: hmrSharedChunkImporters,
12112
- subPackageRoots: new Set(ctx.scanService?.subPackageMap?.keys?.() ?? []),
12113
- relativeAbsoluteSrcRoot: ctx.configService.relativeAbsoluteSrcRoot.bind(ctx.configService)
12114
- });
12115
- const pending = [];
12116
- const shouldEmitAllEntries = pendingEntryIds.size > 0 && pendingEntryIds.size === resolvedEntryMap.size;
12117
- options?.hmr?.setDidEmitAllEntries?.(shouldEmitAllEntries);
12118
- options?.hmr?.setLastEmittedEntries?.(new Set(pendingEntryIds));
12119
- for (const entryId of pendingEntryIds) {
12120
- const resolvedId = resolvedEntryMap.get(entryId);
12121
- if (!resolvedId) continue;
12122
- pending.push(resolvedId);
12123
- dirtyEntrySet.delete(entryId);
12124
- dirtyEntryReasons.delete(entryId);
12125
- }
12126
- if (debug) debug(`hmr emit dirty=${dirtyCount} resolved=${resolvedEntryMap.size} emitAll=${shouldEmitAllEntries} pending=${pending.length}`);
12127
- if (pending.length) await Promise.all(emitEntriesChunks.call(this, pending));
12128
- }
12129
- };
12130
- }
12131
- function resolvePendingEntryIds(options) {
12132
- const pending = new Set(options.dirtyEntrySet);
12133
- if (options.mode === "full") return new Set(options.resolvedEntryMap.keys());
12134
- if (!options.isDev || options.mode === "off") return pending;
12135
- if (!options.sharedChunkImporters?.size) return pending;
12136
- for (const importers of options.sharedChunkImporters.values()) {
12137
- if (importers.size <= 1) continue;
12138
- let hasDependencyDrivenImporter = false;
12139
- let hasDirectDirtyImporter = false;
12140
- for (const importer of importers) {
12141
- if (options.dirtyEntrySet.has(importer) && options.dirtyEntryReasons.get(importer) === "dependency") {
12142
- hasDependencyDrivenImporter = true;
12143
- break;
12144
- }
12145
- if (options.dirtyEntrySet.has(importer) && options.dirtyEntryReasons.get(importer) === "direct") hasDirectDirtyImporter = true;
12146
- }
12147
- if (!hasDependencyDrivenImporter && !hasDirectDirtyImporter) continue;
12148
- for (const importer of importers) pending.add(importer);
12149
- }
12150
- return pending;
12151
- }
12152
- //#endregion
12153
- //#region src/utils/wxmlScriptModule.ts
12154
- const IMPORT_SJS_TAG_RE = /<import-sjs([\s\S]*?)>/g;
12155
- const IMPORT_SJS_SRC_RE = /\bsrc\s*=\s*/g;
12156
- const IMPORT_SJS_MODULE_RE = /\bmodule\s*=\s*/g;
12157
- const DEFAULT_SCRIPT_MODULE_TAG_NAMES = ["wxs", "sjs"];
12158
- const DEFAULT_SCRIPT_MODULE_TAG_BY_EXTENSION = Object.freeze({
12159
- wxs: "wxs",
12160
- sjs: "sjs"
12161
- });
12162
- const SCRIPT_MODULE_IMPORT_ATTRS = Object.freeze({
12163
- "wxs": ["src"],
12164
- "sjs": ["src"],
12165
- "import-sjs": ["from"]
12166
- });
12167
- function resolveScriptModuleTagByPlatform(platform, scriptModuleExtension) {
12168
- return getPlatformScriptModuleTag(platform, scriptModuleExtension);
12169
- }
12170
- function normalizeScriptModuleExtension(scriptModuleExtension) {
12171
- if (!scriptModuleExtension) return;
12172
- return scriptModuleExtension.startsWith(".") ? scriptModuleExtension.slice(1) : scriptModuleExtension;
12173
- }
12174
- function getDefaultScriptModuleTagByExtension(scriptModuleExtension) {
12175
- if (!scriptModuleExtension) return "wxs";
12176
- return DEFAULT_SCRIPT_MODULE_TAG_BY_EXTENSION[normalizeScriptModuleExtension(scriptModuleExtension)] ?? "wxs";
12177
- }
12178
- function resolveScriptModuleTagName(options) {
12179
- if (options?.scriptModuleTag) return options.scriptModuleTag;
12180
- return resolveScriptModuleTagByPlatform(options?.platform, options?.scriptModuleExtension) ?? getDefaultScriptModuleTagByExtension(options?.scriptModuleExtension);
12181
- }
12182
- function getDerivedScriptModuleTagNames() {
12183
- return MINI_PROGRAM_PLATFORM_ADAPTERS.flatMap((adapter) => Object.values(adapter.scriptModuleTagByExtension ?? {})).filter((value) => typeof value === "string" && value.length > 0);
12184
- }
12185
- function getScriptModuleTagNames() {
12186
- return [...new Set([...DEFAULT_SCRIPT_MODULE_TAG_NAMES, ...getDerivedScriptModuleTagNames()])];
12187
- }
12188
- function isScriptModuleTagName(tagName) {
12189
- return typeof tagName === "string" && getScriptModuleTagNames().includes(tagName);
12190
- }
12191
- function getScriptModuleImportAttrs(tagName) {
12192
- if (!tagName) return;
12193
- return SCRIPT_MODULE_IMPORT_ATTRS[tagName];
12194
- }
12195
- function isScriptModuleImportAttr(tagName, attrName) {
12196
- if (!tagName) return false;
12197
- return getScriptModuleImportAttrs(tagName)?.includes(attrName) === true;
12198
- }
12199
- function shouldNormalizeScriptModuleAttributes(tagName) {
12200
- return tagName === "import-sjs";
12201
- }
12202
- function normalizeImportSjsAttributes(source) {
12203
- return source.replace(IMPORT_SJS_TAG_RE, (tag) => {
12204
- return tag.replace(IMPORT_SJS_SRC_RE, "from=").replace(IMPORT_SJS_MODULE_RE, "name=");
12205
- });
12206
- }
12207
- //#endregion
12208
- //#region src/wxs/utils.ts
12209
- function normalizeWxsFilename(value, extension = "wxs") {
12210
- const normalized = extension.startsWith(".") ? extension.slice(1) : extension;
12211
- let filename = value;
12212
- filename = filename.replace(/\.[jt]s$/i, "");
12213
- filename = filename.replace(/\.(wxs|sjs)$/i, "");
12214
- return addExtension(filename, `.${normalized}`);
12215
- }
12216
- //#endregion
12217
- //#region src/wxs/index.ts
12218
- function transformWxsCode(code, options) {
12219
- const filename = options?.filename ?? "script.ts";
12220
- const extension = options?.extension ?? "wxs";
12221
- const importees = [];
12222
- const maybePushImportee = (value) => {
12223
- if (typeof value !== "string" || !value) return;
12224
- importees.push({ source: value });
12225
- };
12226
- const tryCollectArgument = (path) => {
12227
- const node = path.node;
12228
- if (t.isStringLiteral(node)) {
12229
- maybePushImportee(node.value);
12230
- return;
12231
- }
12232
- if (t.isTemplateLiteral(node) && node.expressions.length === 0) {
12233
- maybePushImportee(node.quasis.map((q) => q.value.cooked ?? q.value.raw ?? "").join(""));
12234
- return;
12235
- }
12236
- try {
12237
- const evaluated = path.evaluate();
12238
- if (evaluated.confident) maybePushImportee(evaluated.value);
12239
- } catch {}
12240
- };
12241
- return {
12242
- result: babel.transformSync(code, {
12243
- babelrc: false,
12244
- configFile: false,
12245
- presets: [["@babel/preset-env"], ["@babel/preset-typescript"]],
12246
- filename,
12247
- plugins: [{ visitor: {
12248
- Directive: { enter(p) {
12249
- p.remove();
12250
- } },
12251
- CallExpression: { enter(p) {
12252
- const node = p.node;
12253
- if (!t.isIdentifier(node.callee, { name: "require" })) return;
12254
- if (node.arguments.length !== 1) return;
12255
- tryCollectArgument(p.get("arguments.0"));
12256
- const arg = node.arguments[0];
12257
- if (t.isStringLiteral(arg)) arg.value = normalizeWxsFilename(arg.value, extension);
12258
- } },
12259
- ExpressionStatement(p) {
12260
- const expression = p.node.expression;
12261
- if (expression.type === "CallExpression" && expression.callee.type === "MemberExpression" && t.isIdentifier(expression.callee.object) && expression.callee.object.name === "Object" && t.isIdentifier(expression.callee.property) && expression.callee.property.name === "defineProperty" && expression.arguments.length >= 2 && t.isIdentifier(expression.arguments[0]) && expression.arguments[0].name === "exports" && t.isStringLiteral(expression.arguments[1]) && expression.arguments[1].value === "__esModule") p.remove();
12262
- },
12263
- NewExpression: { enter(p) {
12264
- const node = p.node;
12265
- if (t.isIdentifier(node.callee, { name: "RegExp" })) p.replaceWith(t.callExpression(t.identifier("getRegExp"), node.arguments));
12266
- else if (t.isIdentifier(node.callee, { name: "Date" })) p.replaceWith(t.callExpression(t.identifier("getDate"), node.arguments));
12267
- } },
12268
- RegExpLiteral: { enter(p) {
12269
- const args = [t.stringLiteral(p.node.pattern)];
12270
- if (p.node.flags) args.push(t.stringLiteral(p.node.flags));
12271
- p.replaceWith(t.callExpression(t.identifier("getRegExp"), args));
12272
- } },
12273
- MemberExpression: { enter(p) {
12274
- const node = p.node;
12275
- if (!t.isIdentifier(node.object, { name: "exports" })) return;
12276
- const moduleExports = t.memberExpression(t.identifier("module"), t.identifier("exports"));
12277
- p.replaceWith(t.memberExpression(moduleExports, node.property, node.computed, node.optional));
12278
- } },
12279
- ImportDeclaration: { enter(p) {
12280
- maybePushImportee(p.node.source.value);
12281
- } }
12282
- } }]
12283
- }),
12284
- importees
12285
- };
12286
- }
12287
- //#endregion
12288
- //#region src/wxml/handle.ts
12289
- const handleCache = /* @__PURE__ */ new WeakMap();
12290
- const inlineWxsTransformCache = /* @__PURE__ */ new Map();
12291
- const INLINE_WXS_CACHE_LIMIT = 256;
12292
- function createCacheKey$1(options) {
12293
- const extension = options.scriptModuleExtension ?? "";
12294
- const tag = options.scriptModuleTag ?? "";
12295
- const templateExt = options.templateExtension ?? "";
12296
- return `${options.removeComment ? 1 : 0}|${options.transformEvent ? 1 : 0}|${extension}|${tag}|${templateExt}`;
12297
- }
12298
- function getCachedResult(data, cacheKey) {
12299
- return handleCache.get(data)?.get(cacheKey);
12300
- }
12301
- function setCachedResult(data, cacheKey, result) {
12302
- let cacheForToken = handleCache.get(data);
12303
- if (!cacheForToken) {
12304
- cacheForToken = /* @__PURE__ */ new Map();
12305
- handleCache.set(data, cacheForToken);
12306
- }
12307
- cacheForToken.set(cacheKey, result);
12308
- return result;
12309
- }
12310
- function getCachedInlineWxsTransform(code, extension) {
12311
- const key = `${extension}::${code}`;
12312
- const cached = inlineWxsTransformCache.get(key);
12313
- if (cached) {
12314
- inlineWxsTransformCache.delete(key);
12315
- inlineWxsTransformCache.set(key, cached);
12316
- return cached;
12317
- }
12318
- const transformed = transformWxsCode(code, { extension });
12319
- inlineWxsTransformCache.set(key, transformed);
12320
- if (inlineWxsTransformCache.size > INLINE_WXS_CACHE_LIMIT) {
12321
- const firstKey = inlineWxsTransformCache.keys().next().value;
12322
- if (firstKey) inlineWxsTransformCache.delete(firstKey);
12323
- }
12324
- return transformed;
12325
- }
12326
- function handleWxml(data, options) {
12327
- const opts = defu(options, {
12328
- removeComment: true,
12329
- transformEvent: true,
12330
- scriptModuleExtension: void 0,
12331
- scriptModuleTag: void 0,
12332
- templateExtension: void 0
12333
- });
12334
- const cacheKey = createCacheKey$1(opts);
12335
- const cached = getCachedResult(data, cacheKey);
12336
- if (cached) return cached;
12337
- const { code, removalRanges = [], commentTokens = [], eventTokens = [], directiveTokens = [], tagNameTokens = [], inlineWxsTokens = [], removeWxsLangAttrTokens = [], scriptModuleTagTokens = [], wxsImportNormalizeTokens = [], templateImportNormalizeTokens = [], components, deps } = data;
12338
- const normalizedScriptExtension = opts.scriptModuleExtension?.startsWith(".") ? opts.scriptModuleExtension.slice(1) : opts.scriptModuleExtension;
12339
- const normalizedTemplateExtension = opts.templateExtension?.startsWith(".") ? opts.templateExtension.slice(1) : opts.templateExtension;
12340
- const resolvedScriptTag = resolveScriptModuleTagName({
12341
- scriptModuleExtension: normalizedScriptExtension,
12342
- scriptModuleTag: opts.scriptModuleTag
12343
- });
12344
- const shouldNormalizeImports = wxsImportNormalizeTokens.length > 0;
12345
- const shouldNormalizeTemplateImports = templateImportNormalizeTokens.length > 0 && normalizedTemplateExtension;
12346
- const shouldRemoveLang = removeWxsLangAttrTokens.length > 0;
12347
- const shouldTransformInlineWxs = inlineWxsTokens.length > 0;
12348
- const shouldTransformEvents = opts.transformEvent && eventTokens.length > 0;
12349
- const shouldTransformDirectives = directiveTokens.length > 0;
12350
- const shouldTransformTagNames = tagNameTokens.length > 0;
12351
- const shouldTransformScriptModuleTags = resolvedScriptTag !== "wxs" && scriptModuleTagTokens.length > 0;
12352
- const shouldRemoveConditionals = removalRanges.length > 0;
12353
- const shouldRemoveComments = opts.removeComment && commentTokens.length > 0;
12354
- if (!shouldNormalizeImports && !shouldNormalizeTemplateImports && !shouldRemoveLang && !shouldTransformInlineWxs && !shouldTransformEvents && !shouldTransformDirectives && !shouldTransformTagNames && !shouldTransformScriptModuleTags && !shouldRemoveConditionals && !shouldRemoveComments) return setCachedResult(data, cacheKey, {
12355
- code,
12356
- components,
12357
- deps
12358
- });
12359
- const ms = new MagicString(code);
12360
- if (shouldNormalizeImports) for (const { start, end, value } of wxsImportNormalizeTokens) ms.update(start, end, normalizeWxsFilename(value, normalizedScriptExtension ?? "wxs"));
12361
- if (shouldNormalizeTemplateImports) for (const { start, end, value } of templateImportNormalizeTokens) {
12362
- let nextValue = changeFileExtension(value, normalizedTemplateExtension);
12363
- if (value.startsWith("./") && !nextValue.startsWith("./") && !nextValue.startsWith("../") && !nextValue.startsWith("/")) nextValue = `./${nextValue}`;
12364
- ms.update(start, end, nextValue);
12365
- }
12366
- if (shouldRemoveLang) for (const { start, end } of removeWxsLangAttrTokens) ms.update(start, end, "");
12367
- if (shouldTransformInlineWxs) for (const { end, start, value } of inlineWxsTokens) {
12368
- const { result } = getCachedInlineWxsTransform(value, normalizedScriptExtension ?? "wxs");
12369
- if (result?.code) ms.update(start, end, `\n${result.code}`);
12370
- }
12371
- if (shouldTransformScriptModuleTags) {
12372
- const visited = /* @__PURE__ */ new Set();
12373
- for (const { start, end } of scriptModuleTagTokens) {
12374
- const key = `${start}:${end}`;
12375
- if (visited.has(key)) continue;
12376
- visited.add(key);
12377
- ms.update(start, end, resolvedScriptTag);
12378
- }
12379
- }
12380
- if (shouldTransformEvents) for (const { end, start, value } of eventTokens) ms.update(start, end, value);
12381
- if (shouldTransformDirectives) for (const { end, start, value } of directiveTokens) ms.update(start, end, value);
12382
- if (shouldTransformTagNames) for (const { end, start, value } of tagNameTokens) ms.update(start, end, value);
12383
- if (shouldRemoveConditionals) {
12384
- for (const { start, end } of removalRanges) if (end > start) ms.remove(start, end);
12385
- }
12386
- if (shouldRemoveComments) for (const { end, start } of commentTokens) ms.remove(start, end);
12387
- return setCachedResult(data, cacheKey, {
12388
- code: shouldNormalizeScriptModuleAttributes(resolvedScriptTag) ? normalizeImportSjsAttributes(ms.toString()) : ms.toString(),
12389
- components,
12390
- deps
12391
- });
12345
+ appEntryOutputCache.current = void 0;
12346
+ } });
12392
12347
  }
12393
12348
  //#endregion
12394
- //#region src/plugins/utils/wxmlEmit.ts
12395
- function resolveWxmlEmitContext(compiler) {
12396
- const { wxmlService, configService, scanService } = compiler;
12397
- if (!wxmlService || !configService || !scanService) throw new Error("emitWxmlAssets 需要先初始化 wxmlService、configService 和 scanService。");
12398
- const { templateExtension, scriptModuleExtension } = resolveCompilerOutputExtensions(configService.outputExtensions);
12399
- return {
12400
- wxmlService,
12401
- configService,
12402
- scanService,
12403
- templateExtension,
12404
- scriptModuleExtension,
12405
- scriptModuleTag: resolveScriptModuleTagName({
12406
- platform: configService.platform,
12407
- scriptModuleExtension
12408
- })
12349
+ //#region src/plugins/hooks/useLoadEntry/normalizer.ts
12350
+ const PLUGIN_PROTOCOL_RE = /plugin:\/\//;
12351
+ const WINDOWS_PATH_SEPARATOR_RE = /\\/g;
12352
+ function resolveImportee(importee, jsonPath, configService) {
12353
+ let updated = importee;
12354
+ if (jsonPath && Array.isArray(configService.aliasEntries)) {
12355
+ const matchedEntry = configService.aliasEntries.find((entry) => matches(entry.find, importee));
12356
+ if (matchedEntry) updated = importee.replace(matchedEntry.find, matchedEntry.replacement);
12357
+ }
12358
+ const baseDir = jsonPath ? path.dirname(jsonPath) : configService.absoluteSrcRoot;
12359
+ return path.resolve(baseDir, updated);
12360
+ }
12361
+ function createEntryNormalizer(configService) {
12362
+ return function normalizeEntry(entry, jsonPath) {
12363
+ if (PLUGIN_PROTOCOL_RE.test(entry)) return entry;
12364
+ const normalizedEntry = normalizeNpmImportLookupPath(entry);
12365
+ if (normalizedEntry && isObject(configService.packageJson.dependencies) && hasNpmDependencyPrefix(configService.packageJson.dependencies, normalizedEntry)) return `npm:${normalizedEntry}`;
12366
+ if (entry.replace(WINDOWS_PATH_SEPARATOR_RE, "/").startsWith("/")) return normalizedEntry;
12367
+ const normalized = resolveImportee(normalizedEntry, jsonPath, configService);
12368
+ return configService.relativeAbsoluteSrcRoot(normalized);
12409
12369
  };
12410
12370
  }
12411
- function resolveWxmlEmitTargets(options) {
12412
- const { compiler, subPackageMeta, buildTarget = "app" } = options;
12413
- const { wxmlService, configService, scanService, templateExtension } = resolveWxmlEmitContext(compiler);
12414
- return Array.from(wxmlService.tokenMap.entries()).map(([id, token]) => {
12415
- return {
12416
- id,
12417
- token,
12418
- fileName: resolveRelativeOutputFileNameWithExtension(configService, id, templateExtension)
12419
- };
12420
- }).filter(({ id, fileName }) => {
12421
- if (subPackageMeta) return fileName.startsWith(subPackageMeta.subPackage.root);
12422
- if (buildTarget === "plugin") {
12423
- const pluginRoot = configService.absolutePluginRoot;
12424
- if (!pluginRoot) return false;
12425
- return isPathInside(pluginRoot, id);
12371
+ //#endregion
12372
+ //#region src/plugins/hooks/useLoadEntry/template.ts
12373
+ function createTemplateScanner(wxmlService, debug) {
12374
+ return async function scanTemplateEntry(templateEntry) {
12375
+ const start = performance$1.now();
12376
+ const wxmlToken = await wxmlService.scan(templateEntry);
12377
+ if (wxmlToken) {
12378
+ const { components } = wxmlToken;
12379
+ wxmlService.setWxmlComponentsMap(templateEntry, components);
12426
12380
  }
12427
- return scanService.isMainPackageFileName(fileName);
12428
- });
12381
+ debug?.(`scanTemplateEntry ${templateEntry} 耗时 ${(performance$1.now() - start).toFixed(2)}ms`);
12382
+ };
12429
12383
  }
12430
- function emitWxmlAssetFile(options) {
12431
- const { runtime, id, fileName, token, deps, emittedCodeCache, scriptModuleExtension, scriptModuleTag, templateExtension } = options;
12432
- runtime.addWatchFile?.(normalizeWatchPath(id));
12433
- if (deps) for (const dep of deps) runtime.addWatchFile?.(normalizeWatchPath(dep));
12434
- const result = handleWxml(token, {
12435
- scriptModuleExtension,
12436
- scriptModuleTag,
12437
- templateExtension
12438
- });
12439
- if (emittedCodeCache.get(fileName) === result.code) return false;
12440
- emittedCodeCache.set(fileName, result.code);
12441
- runtime.emitFile({
12442
- type: "asset",
12443
- fileName,
12444
- source: result.code
12384
+ //#endregion
12385
+ //#region src/plugins/hooks/useLoadEntry/index.ts
12386
+ function useLoadEntry(ctx, options) {
12387
+ const debug = createDebugger("weapp-vite:load-entry");
12388
+ const buildTarget = options?.buildTarget ?? "app";
12389
+ const entriesMap = /* @__PURE__ */ new Map();
12390
+ const loadedEntrySet = /* @__PURE__ */ new Set();
12391
+ const dirtyEntrySet = /* @__PURE__ */ new Set();
12392
+ const dirtyEntryReasons = /* @__PURE__ */ new Map();
12393
+ const resolvedEntryMap = /* @__PURE__ */ new Map();
12394
+ const layoutEntryDependents = /* @__PURE__ */ new Map();
12395
+ const entryLayoutDependencies = /* @__PURE__ */ new Map();
12396
+ const jsonEmitManager = createJsonEmitManager(ctx.configService);
12397
+ const registerJsonAsset = jsonEmitManager.register.bind(jsonEmitManager);
12398
+ const normalizeEntry = createEntryNormalizer(ctx.configService);
12399
+ const scanTemplateEntry = createTemplateScanner(ctx.wxmlService, debug);
12400
+ const emitEntriesChunks = createChunkEmitter(ctx.configService, loadedEntrySet, debug);
12401
+ const loadEntry = createEntryLoader({
12402
+ ctx,
12403
+ entriesMap,
12404
+ loadedEntrySet,
12405
+ dirtyEntrySet,
12406
+ resolvedEntryMap,
12407
+ replaceLayoutDependencies(entryId, dependencies) {
12408
+ const previousDependencies = entryLayoutDependencies.get(entryId);
12409
+ if (previousDependencies) for (const dependency of previousDependencies) {
12410
+ const dependents = layoutEntryDependents.get(dependency);
12411
+ if (!dependents) continue;
12412
+ dependents.delete(entryId);
12413
+ if (dependents.size === 0) layoutEntryDependents.delete(dependency);
12414
+ }
12415
+ const normalizedDependencies = new Set(dependencies);
12416
+ if (normalizedDependencies.size === 0) {
12417
+ entryLayoutDependencies.delete(entryId);
12418
+ return;
12419
+ }
12420
+ entryLayoutDependencies.set(entryId, normalizedDependencies);
12421
+ for (const dependency of normalizedDependencies) {
12422
+ let dependents = layoutEntryDependents.get(dependency);
12423
+ if (!dependents) {
12424
+ dependents = /* @__PURE__ */ new Set();
12425
+ layoutEntryDependents.set(dependency, dependents);
12426
+ }
12427
+ dependents.add(entryId);
12428
+ }
12429
+ },
12430
+ normalizeEntry,
12431
+ registerJsonAsset,
12432
+ scanTemplateEntry,
12433
+ emitEntriesChunks,
12434
+ applyAutoImports: createAutoImportAugmenter(ctx.autoImportService, ctx.wxmlService),
12435
+ extendedLibManager: createExtendedLibManager(),
12436
+ buildTarget,
12437
+ debug
12445
12438
  });
12446
- return true;
12439
+ const hmrSharedChunksMode = options?.hmr?.sharedChunks ?? "auto";
12440
+ const hmrSharedChunkImporters = options?.hmr?.sharedChunkImporters;
12441
+ return {
12442
+ loadEntry,
12443
+ entriesMap,
12444
+ loadedEntrySet,
12445
+ dirtyEntrySet,
12446
+ resolvedEntryMap,
12447
+ layoutEntryDependents,
12448
+ jsonEmitFilesMap: jsonEmitManager.map,
12449
+ normalizeEntry,
12450
+ markEntryDirty(entryId, reason = "direct") {
12451
+ dirtyEntrySet.add(entryId);
12452
+ dirtyEntryReasons.set(entryId, reason);
12453
+ loadedEntrySet.delete(entryId);
12454
+ },
12455
+ async emitDirtyEntries() {
12456
+ if (!dirtyEntrySet.size) {
12457
+ options?.hmr?.setDidEmitAllEntries?.(false);
12458
+ options?.hmr?.setLastEmittedEntries?.(/* @__PURE__ */ new Set());
12459
+ return;
12460
+ }
12461
+ const dirtyCount = dirtyEntrySet.size;
12462
+ const pendingEntryIds = resolvePendingEntryIds({
12463
+ isDev: Boolean(ctx.configService?.isDev),
12464
+ mode: hmrSharedChunksMode,
12465
+ resolvedEntryMap,
12466
+ dirtyEntrySet,
12467
+ dirtyEntryReasons,
12468
+ sharedChunkImporters: hmrSharedChunkImporters,
12469
+ subPackageRoots: new Set(ctx.scanService?.subPackageMap?.keys?.() ?? []),
12470
+ relativeAbsoluteSrcRoot: ctx.configService.relativeAbsoluteSrcRoot.bind(ctx.configService)
12471
+ });
12472
+ const pending = [];
12473
+ const shouldEmitAllEntries = pendingEntryIds.size > 0 && pendingEntryIds.size === resolvedEntryMap.size;
12474
+ options?.hmr?.setDidEmitAllEntries?.(shouldEmitAllEntries);
12475
+ options?.hmr?.setLastEmittedEntries?.(new Set(pendingEntryIds));
12476
+ for (const entryId of pendingEntryIds) {
12477
+ const resolvedId = resolvedEntryMap.get(entryId);
12478
+ if (!resolvedId) continue;
12479
+ pending.push(resolvedId);
12480
+ dirtyEntrySet.delete(entryId);
12481
+ dirtyEntryReasons.delete(entryId);
12482
+ }
12483
+ if (debug) debug(`hmr emit dirty=${dirtyCount} resolved=${resolvedEntryMap.size} emitAll=${shouldEmitAllEntries} pending=${pending.length}`);
12484
+ if (pending.length) await Promise.all(emitEntriesChunks.call(this, pending));
12485
+ }
12486
+ };
12447
12487
  }
12448
- function emitWxmlAssetsWithCache(options) {
12449
- const { runtime, compiler, subPackageMeta, emittedCodeCache, buildTarget = "app" } = options;
12450
- const { wxmlService, templateExtension, scriptModuleExtension, scriptModuleTag } = resolveWxmlEmitContext(compiler);
12451
- const currentPackageWxmls = resolveWxmlEmitTargets({
12452
- compiler,
12453
- subPackageMeta,
12454
- buildTarget
12455
- });
12456
- const emittedFiles = [];
12457
- for (const { id, fileName, token } of currentPackageWxmls) {
12458
- emittedFiles.push(fileName);
12459
- emitWxmlAssetFile({
12460
- runtime,
12461
- id,
12462
- fileName,
12463
- token,
12464
- deps: wxmlService.depsMap.get(id),
12465
- emittedCodeCache,
12466
- scriptModuleExtension,
12467
- scriptModuleTag,
12468
- templateExtension
12469
- });
12488
+ function resolvePendingEntryIds(options) {
12489
+ const pending = new Set(options.dirtyEntrySet);
12490
+ if (options.mode === "full") return new Set(options.resolvedEntryMap.keys());
12491
+ if (!options.isDev || options.mode === "off") return pending;
12492
+ if (!options.sharedChunkImporters?.size) return pending;
12493
+ for (const importers of options.sharedChunkImporters.values()) {
12494
+ if (importers.size <= 1) continue;
12495
+ let hasDependencyDrivenImporter = false;
12496
+ let hasDirectDirtyImporter = false;
12497
+ for (const importer of importers) {
12498
+ if (options.dirtyEntrySet.has(importer) && options.dirtyEntryReasons.get(importer) === "dependency") {
12499
+ hasDependencyDrivenImporter = true;
12500
+ break;
12501
+ }
12502
+ if (options.dirtyEntrySet.has(importer) && options.dirtyEntryReasons.get(importer) === "direct") hasDirectDirtyImporter = true;
12503
+ }
12504
+ if (!hasDependencyDrivenImporter && !hasDirectDirtyImporter) continue;
12505
+ for (const importer of importers) pending.add(importer);
12470
12506
  }
12471
- return emittedFiles;
12472
- }
12473
- function emitJsonAsset(runtime, fileName, source, extension = "json") {
12474
- runtime.emitFile({
12475
- type: "asset",
12476
- fileName: changeFileExtension(fileName, extension),
12477
- source
12478
- });
12507
+ return pending;
12479
12508
  }
12480
12509
  //#endregion
12481
12510
  //#region src/plugins/core/helpers/bundle.ts
@@ -14032,11 +14061,20 @@ function invalidateSharedStyleCache() {
14032
14061
  //#region src/plugins/utils/invalidateEntry/shared.ts
14033
14062
  const watchedCssExts = new Set(supportedCssLangs.map((ext) => `.${ext}`));
14034
14063
  const watchedTemplateExts = new Set(templateExtensions.map((ext) => `.${ext}`));
14064
+ const watchedScriptModuleExts = new Set([
14065
+ ".wxs",
14066
+ ".sjs",
14067
+ ".wxs.ts",
14068
+ ".wxs.js",
14069
+ ".sjs.ts",
14070
+ ".sjs.js"
14071
+ ]);
14035
14072
  const configSuffixes$1 = configExtensions.map((ext) => `.${ext}`);
14036
14073
  const sidecarSuffixes = [
14037
14074
  ...configSuffixes$1,
14038
14075
  ...watchedCssExts,
14039
- ...watchedTemplateExts
14076
+ ...watchedTemplateExts,
14077
+ ...watchedScriptModuleExts
14040
14078
  ];
14041
14079
  const defaultIgnoredDirNames = new Set([
14042
14080
  "node_modules",
@@ -14210,15 +14248,26 @@ async function invalidateEntryForSidecar(ctx, filePath, event = "update") {
14210
14248
  if (configSuffix) scriptBasePath = filePath.slice(0, -configSuffix.length);
14211
14249
  else if (ext && watchedCssExts.has(ext)) scriptBasePath = filePath.slice(0, -ext.length);
14212
14250
  else if (ext && watchedTemplateExts.has(ext)) scriptBasePath = filePath.slice(0, -ext.length);
14213
- if (!scriptBasePath) return;
14251
+ const isScriptModuleSidecar = Array.from(watchedScriptModuleExts).some((suffix) => normalizedPath.endsWith(suffix));
14252
+ if (!scriptBasePath && !isScriptModuleSidecar) return;
14214
14253
  const touchedTargets = /* @__PURE__ */ new Set();
14215
14254
  const touchedScripts = /* @__PURE__ */ new Set();
14216
- const primaryScript = await findJsEntry(scriptBasePath);
14217
- if (primaryScript.path) touchedScripts.add(primaryScript.path);
14218
- if (!primaryScript.path && ext && watchedCssExts.has(ext)) {
14219
- const { importers, scripts } = await collectAffectedScriptsAndImporters(ctx, normalizedPath);
14255
+ if (isScriptModuleSidecar || ext && watchedTemplateExts.has(ext)) {
14256
+ const importers = ctx.wxmlService?.getImporters(normalizedPath) ?? /* @__PURE__ */ new Set();
14220
14257
  for (const importer of importers) touchedTargets.add(importer);
14221
- for (const script of scripts) touchedScripts.add(script);
14258
+ }
14259
+ if (scriptBasePath) {
14260
+ const primaryScript = await findJsEntry(scriptBasePath);
14261
+ if (primaryScript.path) touchedScripts.add(primaryScript.path);
14262
+ else if (ext && watchedTemplateExts.has(ext)) {
14263
+ const primaryVueEntry = await findVueEntry(scriptBasePath);
14264
+ if (primaryVueEntry) touchedTargets.add(primaryVueEntry);
14265
+ }
14266
+ if (!primaryScript.path && ext && watchedCssExts.has(ext)) {
14267
+ const { importers, scripts } = await collectAffectedScriptsAndImporters(ctx, normalizedPath);
14268
+ for (const importer of importers) touchedTargets.add(importer);
14269
+ for (const script of scripts) touchedScripts.add(script);
14270
+ }
14222
14271
  }
14223
14272
  const isCssSidecar = Boolean(ext && watchedCssExts.has(ext));
14224
14273
  const isTemplateSidecar = Boolean(ext && watchedTemplateExts.has(ext));
@@ -14231,7 +14280,7 @@ async function invalidateEntryForSidecar(ctx, filePath, event = "update") {
14231
14280
  await touch(script);
14232
14281
  } catch {}
14233
14282
  if (!touchedTargets.size && !touchedScripts.size) {
14234
- if (event === "create" && (isCssSidecar || isTemplateSidecar)) logger_default.info(`[sidecar:${event}] ${relativeSource} 新增,但未找到引用方,等待后续关联`);
14283
+ if (event === "create" && (isCssSidecar || isTemplateSidecar || isScriptModuleSidecar)) logger_default.info(`[sidecar:${event}] ${relativeSource} 新增,但未找到引用方,等待后续关联`);
14235
14284
  return;
14236
14285
  }
14237
14286
  const touchedList = [];
@@ -14256,9 +14305,12 @@ function ensureSidecarWatcher(ctx, rootDir) {
14256
14305
  if (!isSidecarFile(filePath)) return;
14257
14306
  const ext = path.extname(filePath);
14258
14307
  const isCssFile = Boolean(ext && watchedCssExts.has(ext));
14308
+ const isTemplateFile = Boolean(ext && watchedTemplateExts.has(ext));
14309
+ const isScriptModuleFile = Array.from(watchedScriptModuleExts).some((suffix) => filePath.endsWith(suffix));
14310
+ const hasReverseImporters = Boolean(isTemplateFile || isScriptModuleFile) && (ctx.wxmlService?.getImporters(filePath).size ?? 0) > 0;
14259
14311
  if (isCssFile && (event === "create" || event === "update")) extractCssImportDependencies(ctx, filePath);
14260
14312
  const isDeleteEvent = event === "delete";
14261
- if (event === "create" && ready || isDeleteEvent) {
14313
+ if (event === "create" && ready || isDeleteEvent || event === "update" && hasReverseImporters) {
14262
14314
  (async () => {
14263
14315
  await invalidateEntryForSidecar(ctx, filePath, event);
14264
14316
  if (isCssFile && isDeleteEvent) cleanupCssImporterGraph(ctx, filePath);
@@ -14270,7 +14322,8 @@ function ensureSidecarWatcher(ctx, rootDir) {
14270
14322
  const patterns = [
14271
14323
  ...configExtensions.map((ext) => path.join(absRoot, `**/*.${ext}`)),
14272
14324
  ...supportedCssLangs.map((ext) => path.join(absRoot, `**/*.${ext}`)),
14273
- ...templateExtensions.map((ext) => path.join(absRoot, `**/*.${ext}`))
14325
+ ...templateExtensions.map((ext) => path.join(absRoot, `**/*.${ext}`)),
14326
+ ...Array.from(watchedScriptModuleExts).map((ext) => path.join(absRoot, `**/*${ext}`))
14274
14327
  ];
14275
14328
  const ignoredMatcher = createSidecarIgnoredMatcher(ctx, absRoot);
14276
14329
  const watcher = chokidar.watch(patterns, createSidecarWatchOptions(ctx.configService, {
@@ -14693,8 +14746,9 @@ function injectSharedStyleImports(css, modulePath, fileName, sharedStyles, confi
14693
14746
  }
14694
14747
  //#endregion
14695
14748
  //#region src/plugins/css.ts
14749
+ const LEADING_BLANK_LINES_RE = /^(?:[ \t]*\r?\n)+/;
14696
14750
  function stripLeadingBlankLines(code) {
14697
- return code.replace(/^(?:[ \t]*\r?\n)+/, "");
14751
+ return code.replace(LEADING_BLANK_LINES_RE, "");
14698
14752
  }
14699
14753
  async function handleBundleEntry(bundle, bundleKey, asset, configService, sharedStyles, emitted) {
14700
14754
  if (asset.type !== "asset") return;
@@ -14893,6 +14947,7 @@ function registerVueTemplateToken(ctx, filename, template) {
14893
14947
  try {
14894
14948
  const token = wxmlService.analyze(template);
14895
14949
  wxmlService.tokenMap.set(filename, token);
14950
+ wxmlService.setDeps(filename, wxmlService.collectDepsFromToken(filename, token.deps));
14896
14951
  wxmlService.setWxmlComponentsMap(filename, token.components);
14897
14952
  } catch {}
14898
14953
  }
@@ -18852,10 +18907,10 @@ function createDependenciesCache(ctx) {
18852
18907
  }
18853
18908
  //#endregion
18854
18909
  //#region src/runtime/npmPlugin/relations.ts
18855
- const TRAILING_SLASHES_RE = /\/+$/;
18910
+ const TRAILING_SLASHES_RE$1 = /\/+$/;
18856
18911
  const EMPTY_VALUE_RE = /^$/;
18857
18912
  function normalizeRelativeDir(value) {
18858
- const normalized = toPosixPath(value).replace(TRAILING_SLASHES_RE, "");
18913
+ const normalized = toPosixPath(value).replace(TRAILING_SLASHES_RE$1, "");
18859
18914
  return (normalized.startsWith("./") ? normalized.slice(2) : normalized).replace(EMPTY_VALUE_RE, ".");
18860
18915
  }
18861
18916
  function resolvePlatformProjectRoot(configService) {
@@ -18905,6 +18960,8 @@ function getPackNpmRelationList(ctx) {
18905
18960
  //#endregion
18906
18961
  //#region src/runtime/npmPlugin/service.ts
18907
18962
  const LEADING_SLASHES_RE = /^\/+/;
18963
+ const WINDOWS_PATH_RE = /\\|^[A-Z]:[\\/]/i;
18964
+ const TRAILING_SLASHES_RE = /\/+$/;
18908
18965
  function matchDependencyName(patterns, dep) {
18909
18966
  return patterns.some((pattern) => {
18910
18967
  if (typeof pattern === "string") return pattern === dep;
@@ -18922,6 +18979,13 @@ function matchDependencyPath(patterns, value) {
18922
18979
  return pattern.test(value);
18923
18980
  });
18924
18981
  }
18982
+ function resolveCopyFilterRelativePath(sourceRoot, sourcePath) {
18983
+ const normalizedRoot = normalizePath$1(sourceRoot).replace(TRAILING_SLASHES_RE, "");
18984
+ const normalizedPath = normalizePath$1(sourcePath);
18985
+ if (normalizedPath === normalizedRoot) return "";
18986
+ if (normalizedPath.startsWith(`${normalizedRoot}/`)) return normalizedPath.slice(normalizedRoot.length + 1);
18987
+ return toPosixPath(WINDOWS_PATH_RE.test(sourceRoot) || WINDOWS_PATH_RE.test(sourcePath) ? win32.relative(sourceRoot, sourcePath) : relative(sourceRoot, sourcePath));
18988
+ }
18925
18989
  function resolveTargetDependencies(allDependencies, patterns) {
18926
18990
  if (patterns === false) return [];
18927
18991
  if (!Array.isArray(patterns)) return allDependencies;
@@ -19020,7 +19084,7 @@ function createNpmService(ctx) {
19020
19084
  overwrite: true,
19021
19085
  filter: (src) => {
19022
19086
  if (Array.isArray(meta.subPackage.dependencies)) {
19023
- const relPath = toPosixPath(path.relative(sourceOutDir, src));
19087
+ const relPath = resolveCopyFilterRelativePath(sourceOutDir, String(src));
19024
19088
  if (relPath === "") return true;
19025
19089
  return matchDependencyPath(meta.subPackage.dependencies, relPath);
19026
19090
  }
@@ -19233,6 +19297,7 @@ function createRuntimeState() {
19233
19297
  },
19234
19298
  wxml: {
19235
19299
  depsMap: /* @__PURE__ */ new Map(),
19300
+ importerMap: /* @__PURE__ */ new Map(),
19236
19301
  tokenMap: /* @__PURE__ */ new Map(),
19237
19302
  componentsMap: /* @__PURE__ */ new Map(),
19238
19303
  cache: new FileCache(),
@@ -19241,6 +19306,7 @@ function createRuntimeState() {
19241
19306
  scan: {
19242
19307
  subPackageMap: /* @__PURE__ */ new Map(),
19243
19308
  independentSubPackageMap: /* @__PURE__ */ new Map(),
19309
+ warnedMessages: /* @__PURE__ */ new Set(),
19244
19310
  isDirty: true,
19245
19311
  independentDirtyRoots: /* @__PURE__ */ new Set(),
19246
19312
  pluginJsonPath: void 0
@@ -19545,7 +19611,12 @@ function resolveScanJsonEntryBasename(appDirname, location, fallbackName) {
19545
19611
  }
19546
19612
  function createScanService(ctx) {
19547
19613
  const scanState = ctx.runtimeState.scan;
19548
- const { subPackageMap, independentSubPackageMap, independentDirtyRoots } = scanState;
19614
+ const { subPackageMap, independentSubPackageMap, independentDirtyRoots, warnedMessages } = scanState;
19615
+ function warnOnce(message) {
19616
+ if (warnedMessages.has(message)) return;
19617
+ warnedMessages.add(message);
19618
+ logger_default.warn(message);
19619
+ }
19549
19620
  function mergeAutoRoutePages(pages, routePages) {
19550
19621
  if (routePages.length === 0) return pages;
19551
19622
  const existingPages = Array.isArray(pages) ? pages.filter((page) => typeof page === "string" && page.length > 0) : [];
@@ -19618,12 +19689,12 @@ function createScanService(ctx) {
19618
19689
  const vueAppPath = await findVueEntry(appBasename);
19619
19690
  let configFromVue;
19620
19691
  if (!appConfigFile && vueAppPath) {
19621
- const { extractConfigFromVue } = await import("./file-BAUXs16l.mjs").then((n) => n.r);
19692
+ const { extractConfigFromVue } = await import("./file-DgJb3pIf.mjs");
19622
19693
  configFromVue = await extractConfigFromVue(vueAppPath);
19623
19694
  if (configFromVue) appConfigFile = vueAppPath;
19624
19695
  }
19625
- if (appEntryPath && vueAppPath) logger_default.warn(`[app] 检测到 ${path.basename(appEntryPath)} 与 ${path.basename(vueAppPath)} 同时存在,当前将优先使用 ${path.basename(appEntryPath)} 作为应用入口,${path.basename(vueAppPath)} 将被忽略。`);
19626
- if (discoveredAppConfigFile && vueAppPath) logger_default.warn(`[app] 检测到 ${path.basename(discoveredAppConfigFile)} 与 ${path.basename(vueAppPath)} 同时存在,当前将优先使用 ${path.basename(discoveredAppConfigFile)} 作为应用配置来源,${path.basename(vueAppPath)} 中的 app 配置不会生效。`);
19696
+ if (appEntryPath && vueAppPath) warnOnce(`[app] 检测到 ${path.basename(appEntryPath)} 与 ${path.basename(vueAppPath)} 同时存在,当前将优先使用 ${path.basename(appEntryPath)} 作为应用入口,${path.basename(vueAppPath)} 将被忽略。`);
19697
+ if (discoveredAppConfigFile && vueAppPath) warnOnce(`[app] 检测到 ${path.basename(discoveredAppConfigFile)} 与 ${path.basename(vueAppPath)} 同时存在,当前将优先使用 ${path.basename(discoveredAppConfigFile)} 作为应用配置来源,${path.basename(vueAppPath)} 中的 app 配置不会生效。`);
19627
19698
  if (ctx.configService.absolutePluginRoot) {
19628
19699
  const { path: pluginConfigFile } = await findJsonEntry(resolveScanPluginBasename(ctx.configService.absolutePluginRoot));
19629
19700
  if (pluginConfigFile) {
@@ -19681,10 +19752,12 @@ function createScanService(ctx) {
19681
19752
  const metas = [];
19682
19753
  const independentSubPackages = [...json.subPackages ?? [], ...json.subpackages ?? []];
19683
19754
  for (const subPackage of independentSubPackages) {
19684
- const subPackageConfig = configService.weappViteConfig?.subPackages?.[subPackage.root];
19685
- const npmSubPackageConfig = configService.weappViteConfig?.npm?.subPackages?.[subPackage.root];
19755
+ const normalizedRoot = subPackage.root ? normalizeRoot(subPackage.root) : void 0;
19756
+ const subPackageConfig = normalizedRoot ? configService.weappViteConfig?.subPackages?.[normalizedRoot] : void 0;
19757
+ const npmSubPackageConfig = normalizedRoot ? configService.weappViteConfig?.npm?.subPackages?.[normalizedRoot] : void 0;
19686
19758
  const resolvedSubPackage = {
19687
19759
  ...subPackage,
19760
+ ...normalizedRoot ? { root: normalizedRoot } : {},
19688
19761
  dependencies: npmSubPackageConfig?.dependencies,
19689
19762
  inlineConfig: subPackageConfig?.inlineConfig
19690
19763
  };
@@ -19696,11 +19769,11 @@ function createScanService(ctx) {
19696
19769
  meta.styleEntries = normalizeSubPackageStyleEntries(subPackageConfig?.styles, resolvedSubPackage, configService);
19697
19770
  meta.watchSharedStyles = subPackageConfig?.watchSharedStyles ?? true;
19698
19771
  metas.push(meta);
19699
- if (subPackage.root) {
19700
- subPackageMap.set(subPackage.root, meta);
19772
+ if (normalizedRoot) {
19773
+ subPackageMap.set(normalizedRoot, meta);
19701
19774
  if (subPackage.independent) {
19702
- independentSubPackageMap.set(subPackage.root, meta);
19703
- if (scanState.isDirty) independentDirtyRoots.add(subPackage.root);
19775
+ independentSubPackageMap.set(normalizedRoot, meta);
19776
+ if (scanState.isDirty) independentDirtyRoots.add(normalizedRoot);
19704
19777
  }
19705
19778
  }
19706
19779
  }
@@ -19711,8 +19784,9 @@ function createScanService(ctx) {
19711
19784
  throw new Error(`在 ${configService.absoluteSrcRoot} 目录下没有找到 \`app.json\`, 请确保你初始化了小程序项目,或者在 \`vite.config.ts\` 中设置的正确的 \`weapp.srcRoot\` 配置路径 `);
19712
19785
  }
19713
19786
  function isMainPackageFileName(fileName) {
19787
+ const normalizedFileName = toPosixPath(fileName);
19714
19788
  return [...independentSubPackageMap.keys()].every((root) => {
19715
- return !fileName.startsWith(root);
19789
+ return !normalizedFileName.startsWith(root);
19716
19790
  });
19717
19791
  }
19718
19792
  return {
@@ -19756,7 +19830,8 @@ function createScanService(ctx) {
19756
19830
  },
19757
19831
  markIndependentDirty(root) {
19758
19832
  if (!root) return;
19759
- if (independentSubPackageMap.has(root)) independentDirtyRoots.add(root);
19833
+ const normalizedRoot = normalizeRoot(root);
19834
+ if (independentSubPackageMap.has(normalizedRoot)) independentDirtyRoots.add(normalizedRoot);
19760
19835
  },
19761
19836
  drainIndependentDirtyRoots() {
19762
19837
  const roots = [...independentDirtyRoots];
@@ -19885,17 +19960,49 @@ function createWebServicePlugin(ctx) {
19885
19960
  //#endregion
19886
19961
  //#region src/runtime/wxmlPlugin.ts
19887
19962
  function createWxmlService(ctx) {
19888
- const { depsMap, tokenMap, componentsMap, cache, emittedCode } = ctx.runtimeState.wxml;
19963
+ const { depsMap, importerMap, tokenMap, componentsMap, cache, emittedCode } = ctx.runtimeState.wxml;
19964
+ function linkImporter(dep, importer) {
19965
+ let importers = importerMap.get(dep);
19966
+ if (!importers) {
19967
+ importers = /* @__PURE__ */ new Set();
19968
+ importerMap.set(dep, importers);
19969
+ }
19970
+ importers.add(importer);
19971
+ }
19972
+ function unlinkImporter(dep, importer) {
19973
+ const importers = importerMap.get(dep);
19974
+ if (!importers) return;
19975
+ importers.delete(importer);
19976
+ if (importers.size === 0) importerMap.delete(dep);
19977
+ }
19978
+ async function setDeps(filepath, deps = []) {
19979
+ const nextDeps = new Set(deps);
19980
+ const previousDeps = depsMap.get(filepath) ?? /* @__PURE__ */ new Set();
19981
+ for (const previousDep of previousDeps) if (!nextDeps.has(previousDep)) unlinkImporter(previousDep, filepath);
19982
+ for (const dep of nextDeps) linkImporter(dep, filepath);
19983
+ depsMap.set(filepath, nextDeps);
19984
+ await Promise.all(Array.from(nextDeps).filter((dep) => isTemplate(dep)).map((dep) => {
19985
+ return scan(dep);
19986
+ }));
19987
+ }
19889
19988
  async function addDeps(filepath, deps = []) {
19890
- if (!depsMap.has(filepath)) {
19891
- const set = /* @__PURE__ */ new Set();
19892
- for (const dep of deps) set.add(dep);
19893
- depsMap.set(filepath, set);
19894
- await Promise.all(deps.map((dep) => scan(dep)));
19895
- } else {
19896
- const setRef = depsMap.get(filepath);
19897
- if (setRef) for (const dep of deps) setRef.add(dep);
19898
- }
19989
+ await setDeps(filepath, [...depsMap.get(filepath) ?? /* @__PURE__ */ new Set(), ...deps]);
19990
+ }
19991
+ function resolveDepPath(filepath, value) {
19992
+ const configService = requireConfigService(ctx, "解析 WXML 依赖前必须初始化 configService。");
19993
+ const dirname = path.dirname(filepath);
19994
+ if (value.startsWith("/")) return path.resolve(configService.absoluteSrcRoot, value.slice(1));
19995
+ return path.resolve(dirname, value);
19996
+ }
19997
+ function collectDepsFromToken(filepath, deps = []) {
19998
+ return deps.filter((dep) => {
19999
+ if (!dep.value) return false;
20000
+ if (isTemplateImportTag(dep.tagName)) return isTemplate(dep.value);
20001
+ return isScriptModuleTagName(dep.tagName);
20002
+ }).map((dep) => resolveDepPath(filepath, dep.value));
20003
+ }
20004
+ function getImporters(filepath) {
20005
+ return new Set(importerMap.get(filepath) ?? []);
19899
20006
  }
19900
20007
  function getAllDeps() {
19901
20008
  const set = /* @__PURE__ */ new Set();
@@ -19909,6 +20016,7 @@ function createWxmlService(ctx) {
19909
20016
  const currentRoot = ctx.configService?.currentSubPackageRoot;
19910
20017
  if (!currentRoot) {
19911
20018
  depsMap.clear();
20019
+ importerMap.clear();
19912
20020
  tokenMap.clear();
19913
20021
  componentsMap.clear();
19914
20022
  cache.cache.clear();
@@ -19922,14 +20030,20 @@ function createWxmlService(ctx) {
19922
20030
  };
19923
20031
  for (const key of Array.from(depsMap.keys())) {
19924
20032
  if (shouldClear(key)) {
20033
+ const depSet = depsMap.get(key);
20034
+ if (depSet) for (const dep of depSet) unlinkImporter(dep, key);
19925
20035
  depsMap.delete(key);
19926
20036
  continue;
19927
20037
  }
19928
20038
  const depSet = depsMap.get(key);
19929
20039
  if (depSet) {
19930
- for (const dep of Array.from(depSet)) if (shouldClear(dep)) depSet.delete(dep);
20040
+ for (const dep of Array.from(depSet)) if (shouldClear(dep)) {
20041
+ unlinkImporter(dep, key);
20042
+ depSet.delete(dep);
20043
+ }
19931
20044
  }
19932
20045
  }
20046
+ for (const key of Array.from(importerMap.keys())) if (shouldClear(key)) importerMap.delete(key);
19933
20047
  for (const key of Array.from(tokenMap.keys())) if (shouldClear(key)) tokenMap.delete(key);
19934
20048
  for (const key of Array.from(componentsMap.keys())) if (shouldClear(key)) componentsMap.delete(key);
19935
20049
  for (const key of Array.from(cache.cache.keys())) if (shouldClear(key)) cache.delete(key);
@@ -19970,14 +20084,10 @@ function createWxmlService(ctx) {
19970
20084
  return cached;
19971
20085
  }
19972
20086
  }
19973
- const dirname = path.dirname(filepath);
19974
20087
  const res = analyze(await fs.readFile(filepath, "utf8"));
19975
20088
  tokenMap.set(filepath, res);
19976
20089
  cache.set(filepath, res);
19977
- await addDeps(filepath, res.deps.filter((x) => isTemplateImportTag(x.tagName) && isTemplate(x.value)).map((x) => {
19978
- if (x.value.startsWith("/")) return path.resolve(configService.absoluteSrcRoot, x.value.slice(1));
19979
- else return path.resolve(dirname, x.value);
19980
- }));
20090
+ await setDeps(filepath, collectDepsFromToken(filepath, res.deps));
19981
20091
  return res;
19982
20092
  }
19983
20093
  function setWxmlComponentsMap(absPath, components) {
@@ -19985,9 +20095,13 @@ function createWxmlService(ctx) {
19985
20095
  }
19986
20096
  return {
19987
20097
  depsMap,
20098
+ importerMap,
19988
20099
  tokenMap,
19989
20100
  wxmlComponentsMap: componentsMap,
19990
20101
  addDeps,
20102
+ setDeps,
20103
+ collectDepsFromToken,
20104
+ getImporters,
19991
20105
  getAllDeps,
19992
20106
  clearAll,
19993
20107
  analyze,
@@ -20031,11 +20145,6 @@ function createCompilerContextInstance() {
20031
20145
  }
20032
20146
  //#endregion
20033
20147
  //#region src/context/getInstance.ts
20034
- var getInstance_exports = /* @__PURE__ */ __exportAll({
20035
- getCompilerContext: () => getCompilerContext,
20036
- resetCompilerContext: () => resetCompilerContext,
20037
- setActiveCompilerContextKey: () => setActiveCompilerContextKey
20038
- });
20039
20148
  const compilerContextMap = /* @__PURE__ */ new Map();
20040
20149
  const DEFAULT_KEY = "default";
20041
20150
  let activeCompilerContextKey = DEFAULT_KEY;
@@ -20422,4 +20531,4 @@ async function createCompilerContext(options) {
20422
20531
  return ctx;
20423
20532
  }
20424
20533
  //#endregion
20425
- export { getDefaultIdeProjectRoot as _, getInstance_exports as a, shouldPassPlatformArgToIdeOpen as b, SHARED_CHUNK_VIRTUAL_PREFIX as c, checkRuntime as d, getProjectConfigFileName as f, DEFAULT_MP_PLATFORM as g, createCjsConfigLoadError as h, getCompilerContext as i, getRouteRuntimeGlobalKeys as l, parseCommentJson as m, syncProjectSupportFiles as n, formatBytes as o, loadViteConfigFile as p, syncManagedTsconfigBootstrapFiles as r, createSharedBuildConfig as s, createCompilerContext as t, resolveWeappConfigFile as u, normalizeMiniPlatform as v, isPathInside as x, resolveMiniPlatform as y };
20534
+ export { isPathInside as S, DEFAULT_MP_PLATFORM as _, resetCompilerContext as a, resolveMiniPlatform as b, createSharedBuildConfig as c, resolveWeappConfigFile as d, checkRuntime as f, createCjsConfigLoadError as g, parseCommentJson as h, getCompilerContext as i, SHARED_CHUNK_VIRTUAL_PREFIX as l, loadViteConfigFile as m, syncProjectSupportFiles as n, setActiveCompilerContextKey as o, getProjectConfigFileName as p, syncManagedTsconfigBootstrapFiles as r, formatBytes as s, createCompilerContext as t, getRouteRuntimeGlobalKeys as u, getDefaultIdeProjectRoot as v, shouldPassPlatformArgToIdeOpen as x, normalizeMiniPlatform as y };