weapp-vite 6.19.4 → 6.20.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,24 +1,24 @@
1
1
  import { n as applyWeappViteHostMeta } from "./pluginHost--CaeyWpA.mjs";
2
2
  import { n as configureLogger, r as logger_default } from "./logger-mt4mSTqV.mjs";
3
- import { _ as jsExtensions, a as findJsonEntry, b as vueExtensions, c as isJsOrTs, d as touch, g as configExtensions, i as findJsEntry, l as isTemplate, n as changeFileExtension, o as findTemplateEntry, p as inlineAutoRoutesImports, r as findCssEntry, s as findVueEntry, t as extractConfigFromVue, v as supportedCssLangs, y as templateExtensions } from "./file-C-T36DmG.mjs";
3
+ import { _ as jsExtensions, a as findJsonEntry, b as templateExtensions, c as isJsOrTs, d as touch, g as configExtensions, i as findJsEntry, l as isTemplate, n as changeFileExtension, o as findTemplateEntry, p as inlineAutoRoutesImports, r as findCssEntry, s as findVueEntry, t as extractConfigFromVue, v as scriptExtensions, x as vueExtensions, y as supportedCssLangs } from "./file-NyBgGJm2.mjs";
4
4
  import { createRequire, isBuiltin } from "node:module";
5
5
  import { createDebug } from "obug";
6
6
  import fs, { existsSync, readFileSync, realpathSync } from "node:fs";
7
- import { APP_PRELUDE_CHUNK_MARKER, APP_PRELUDE_GUARD_KEY, APP_PRELUDE_REQUIRE_MARKER, REQUEST_GLOBAL_ACTUALS_KEY, REQUEST_GLOBAL_BUNDLE_HOST_REF, REQUEST_GLOBAL_BUNDLE_MARKER, REQUEST_GLOBAL_BUNDLE_MARKER as REQUEST_GLOBAL_BUNDLE_MARKER$1, REQUEST_GLOBAL_CHUNK_HOST_REF, REQUEST_GLOBAL_CHUNK_MODULE_REF, REQUEST_GLOBAL_EXPOSE_HELPER, REQUEST_GLOBAL_INSTALLER_HOST_REF, REQUEST_GLOBAL_LAZY_CONSTRUCTOR_HELPER, REQUEST_GLOBAL_LAZY_FUNCTION_HELPER, REQUEST_GLOBAL_LOCAL_BINDINGS_MARKER, REQUEST_GLOBAL_LOCAL_BINDINGS_MARKER as REQUEST_GLOBAL_LOCAL_BINDINGS_MARKER$1, REQUEST_GLOBAL_MARK_PLACEHOLDER_HELPER, REQUEST_GLOBAL_PASSIVE_BINDINGS_MARKER, REQUEST_GLOBAL_PASSIVE_BINDINGS_MARKER as REQUEST_GLOBAL_PASSIVE_BINDINGS_MARKER$1, REQUEST_GLOBAL_PLACEHOLDER_KEY, REQUEST_GLOBAL_PRELUDE_GUARD_KEY, REQUEST_GLOBAL_PRELUDE_MARKER, REQUEST_GLOBAL_SYNTHETIC_EXPORT_NAME, REQUEST_GLOBAL_USABLE_CONSTRUCTOR_HELPER, WEAPP_VITE_EXTERNAL_OUTPUT_DIRECTORY, WEAPP_VITE_IMPORT_META_ENV_KEY, WEAPP_VITE_INJECTED_API_IDENTIFIER, WEAPP_VITE_LOGICAL_ENTRY_RESOLVED_PREFIX, WEAPP_VITE_LOGICAL_ENTRY_VIRTUAL_PREFIX, WEAPP_VITE_RUNTIME_CONTRACT_VERSION, WEAPP_VITE_RUNTIME_REACTIVITY_VIRTUAL_ID, WEAPP_VITE_RUNTIME_TEMPLATE_VIRTUAL_ID, WEAPP_VITE_RUNTIME_VIRTUAL_ID, WEAPP_VITE_RUNTIME_VIRTUAL_IDS, WEAPP_VITE_SIDECAR_OWNER_QUERY_MARKER, WEAPP_VITE_SIDECAR_QUERY_MARKER, WEAPP_VITE_SIDECAR_RESOLVED_PREFIX, WEAPP_VITE_SIDECAR_VIRTUAL_PREFIX, WEAPP_VITE_STATEFUL_HMR_BRIDGE_KEY, WEAPP_VITE_STATEFUL_HMR_CLIENT_KEY, WEAPP_VITE_STATEFUL_HMR_CONTROL_FILE, WEAPP_VITE_STATEFUL_HMR_CONTROL_KEY, WEAPP_VITE_STATEFUL_HMR_PRELOAD_FILE, WEAPP_VITE_STATEFUL_HMR_UPDATE_FILE, WEVU_APP_SHELL_COMPONENT_BASE, WEVU_APP_SHELL_TAG_NAME, WEVU_EXPRESSION_ERROR_IDENTIFIER, WEVU_INTERNAL_KEY_IDENTIFIER, WEVU_LAYOUT_BIND_PREFIX, WEVU_PAGE_LAYOUT_CURRENT_NAME_IDENTIFIER, WEVU_PAGE_LAYOUT_CURRENT_PROPS_IDENTIFIER, WEVU_PAGE_LAYOUT_NAME_KEY, WEVU_PAGE_LAYOUT_NEXT_NAME_IDENTIFIER, WEVU_PAGE_LAYOUT_NEXT_PROPS_IDENTIFIER, WEVU_PAGE_LAYOUT_NONE, WEVU_PAGE_LAYOUT_PROPS_KEY, WEVU_PAGE_LAYOUT_SETTER_KEY, WEVU_SCOPED_SLOT_CREATOR_KEY, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_BASE, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_GLOBAL_PATH, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_TAG_NAME, WEVU_SLOT_NAMES_PROP, WEVU_SLOT_OWNER_ID_ATTR, WEVU_SLOT_OWNER_ID_KEY, WEVU_SLOT_OWNER_ID_PROP, WEVU_SLOT_PROPS_ATTR, WEVU_SLOT_SCOPE_ATTR, WEVU_SLOT_SCOPE_KEY } from "@weapp-core/constants";
7
+ import { APP_PRELUDE_CHUNK_MARKER, APP_PRELUDE_GUARD_KEY, APP_PRELUDE_REQUIRE_MARKER, REQUEST_GLOBAL_ACTUALS_KEY, REQUEST_GLOBAL_BUNDLE_HOST_REF, REQUEST_GLOBAL_BUNDLE_MARKER, REQUEST_GLOBAL_BUNDLE_MARKER as REQUEST_GLOBAL_BUNDLE_MARKER$1, REQUEST_GLOBAL_CHUNK_HOST_REF, REQUEST_GLOBAL_CHUNK_MODULE_REF, REQUEST_GLOBAL_EXPOSE_HELPER, REQUEST_GLOBAL_INSTALLER_HOST_REF, REQUEST_GLOBAL_LAZY_CONSTRUCTOR_HELPER, REQUEST_GLOBAL_LAZY_FUNCTION_HELPER, REQUEST_GLOBAL_LOCAL_BINDINGS_MARKER, REQUEST_GLOBAL_LOCAL_BINDINGS_MARKER as REQUEST_GLOBAL_LOCAL_BINDINGS_MARKER$1, REQUEST_GLOBAL_MARK_PLACEHOLDER_HELPER, REQUEST_GLOBAL_PASSIVE_BINDINGS_MARKER, REQUEST_GLOBAL_PASSIVE_BINDINGS_MARKER as REQUEST_GLOBAL_PASSIVE_BINDINGS_MARKER$1, REQUEST_GLOBAL_PLACEHOLDER_KEY, REQUEST_GLOBAL_PRELUDE_GUARD_KEY, REQUEST_GLOBAL_PRELUDE_MARKER, REQUEST_GLOBAL_SYNTHETIC_EXPORT_NAME, REQUEST_GLOBAL_USABLE_CONSTRUCTOR_HELPER, WEAPP_REACT_EVENT_METHOD_NAME, WEAPP_VITE_EXTERNAL_OUTPUT_DIRECTORY, WEAPP_VITE_IMPORT_META_ENV_KEY, WEAPP_VITE_INJECTED_API_IDENTIFIER, WEAPP_VITE_LOGICAL_ENTRY_RESOLVED_PREFIX, WEAPP_VITE_LOGICAL_ENTRY_VIRTUAL_PREFIX, WEAPP_VITE_RUNTIME_CONTRACT_VERSION, WEAPP_VITE_RUNTIME_REACTIVITY_VIRTUAL_ID, WEAPP_VITE_RUNTIME_TEMPLATE_VIRTUAL_ID, WEAPP_VITE_RUNTIME_VIRTUAL_ID, WEAPP_VITE_RUNTIME_VIRTUAL_IDS, WEAPP_VITE_SIDECAR_OWNER_QUERY_MARKER, WEAPP_VITE_SIDECAR_QUERY_MARKER, WEAPP_VITE_SIDECAR_RESOLVED_PREFIX, WEAPP_VITE_SIDECAR_VIRTUAL_PREFIX, WEAPP_VITE_STATEFUL_HMR_BRIDGE_KEY, WEAPP_VITE_STATEFUL_HMR_CLIENT_KEY, WEAPP_VITE_STATEFUL_HMR_CONTROL_FILE, WEAPP_VITE_STATEFUL_HMR_CONTROL_KEY, WEAPP_VITE_STATEFUL_HMR_PRELOAD_FILE, WEAPP_VITE_STATEFUL_HMR_UPDATE_FILE, WEVU_APP_SHELL_COMPONENT_BASE, WEVU_APP_SHELL_TAG_NAME, WEVU_EXPRESSION_ERROR_IDENTIFIER, WEVU_INTERNAL_KEY_IDENTIFIER, WEVU_LAYOUT_BIND_PREFIX, WEVU_PAGE_LAYOUT_CURRENT_NAME_IDENTIFIER, WEVU_PAGE_LAYOUT_CURRENT_PROPS_IDENTIFIER, WEVU_PAGE_LAYOUT_NAME_KEY, WEVU_PAGE_LAYOUT_NEXT_NAME_IDENTIFIER, WEVU_PAGE_LAYOUT_NEXT_PROPS_IDENTIFIER, WEVU_PAGE_LAYOUT_NONE, WEVU_PAGE_LAYOUT_PROPS_KEY, WEVU_PAGE_LAYOUT_SETTER_KEY, WEVU_SCOPED_SLOT_CREATOR_KEY, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_BASE, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_GLOBAL_PATH, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_TAG_NAME, WEVU_SLOT_NAMES_PROP, WEVU_SLOT_OWNER_ID_ATTR, WEVU_SLOT_OWNER_ID_KEY, WEVU_SLOT_OWNER_ID_PROP, WEVU_SLOT_PROPS_ATTR, WEVU_SLOT_SCOPE_ATTR, WEVU_SLOT_SCOPE_KEY } from "@weapp-core/constants";
8
8
  import path, { posix } from "pathe";
9
9
  import { fileURLToPath } from "node:url";
10
10
  import path$1, { normalize, relative, win32 } from "node:path";
11
11
  import { MINI_PROGRAM_PLATFORM_ALIASES, MINI_PROGRAM_PLATFORM_DESCRIPTORS, MINI_PROGRAM_PLATFORM_DESCRIPTORS as MINI_PROGRAM_PLATFORM_ADAPTERS, addExtension, defu, escapeStringRegexp, get, getDefaultMiniProgramPlatform, getMiniProgramAppTypesPackage, getMiniProgramDefaultBuildTarget, getMiniProgramDirectivePrefix, getMiniProgramRouteRuntimeGlobalKeys, getMiniProgramRuntimeGlobalKey, getMiniProgramRuntimeGlobalKeys, getMiniProgramRuntimeGlobalKeysByResolvePriority, getSupportedMiniProgramDirectivePrefixes, getSupportedMiniProgramPlatforms, isEmptyObject, isObject, normalizeMiniProgramPlatform, removeExtension, removeExtensionDeep, resolveMiniProgramPlatform, set, supportsMiniProgramAutoTouchAppStyle } from "@weapp-core/shared";
12
12
  import { fs as fs$1 } from "@weapp-core/shared/fs";
13
- import { analyzeScript, analyzeScripts, collectComponentPropsFromCode, collectRequireTokens, collectScriptSetupImportsFromCode, generate, mayContainPlatformApiIdentifierByText, mayContainStaticRequireLiteral, parseJsLikeWithEngine, platformApiIdentifiers } from "@weapp-vite/ast";
13
+ import { BABEL_TS_MODULE_PARSER_OPTIONS, analyzeScript, analyzeScripts, collectComponentPropsFromCode, collectRequireTokens, collectScriptSetupImportsFromCode, generate, mayContainPlatformApiIdentifierByText, mayContainStaticRequireLiteral, parse, parseJsLikeWithEngine, platformApiIdentifiers } from "@weapp-vite/ast";
14
14
  import { collectOnPageScrollPerformanceWarnings } from "@weapp-vite/ast/operations/onPageScroll";
15
15
  import { collectSetDataPickKeysFromTemplateCode } from "@weapp-vite/ast/operations/setDataPick";
16
- import { compileScript, parse } from "vue/compiler-sfc";
17
- import { BABEL_TS_MODULE_PARSER_OPTIONS, generate as generate$1, getVisitorKeys, parse as parse$2, parseJsLike, traverse } from "@weapp-vite/ast/babel";
16
+ import { compileScript, parse as parse$1 } from "vue/compiler-sfc";
17
+ import { BABEL_TS_MODULE_PARSER_OPTIONS as BABEL_TS_MODULE_PARSER_OPTIONS$1, generate as generate$1, getVisitorKeys, parse as parse$3, parseJsLike, traverse } from "@weapp-vite/ast/babel";
18
18
  import pm from "picomatch";
19
19
  import { VUE_COMPONENT_TAG_RE, WE_VU_COMPILER_REACTIVITY_MODULE_ID, WE_VU_COMPILER_RUNTIME_MODULE_ID, WE_VU_COMPILER_TEMPLATE_MODULE_ID, WE_VU_RUNTIME_APIS, buildClassStyleComputedCode, collectVueTemplateTags, compileJsxFile, compileVueFile, compileVueStyleToWxss, createJsonMerger, createPageEntryMatcher, createPageEntryMatcher as createPageEntryMatcher$1, generateScopedId, getClassStyleWxsSource, getMiniProgramTemplatePlatform, getSfcCheckMtime, injectWevuPageFeaturesInJsWithResolver, invalidateFileCache, isAutoImportCandidateTag, isBuiltinComponent, isUniAppCompatibilityFile, pathExists, readAndParseSfc, readFile as readFile$1, refreshVueFileJsonConfig, resolveClassStyleWxsLocation, stripJsonMacroCallsFromCode, transformNestedWxssVars, transformUniAppSource, transformVueDeepSelectors } from "wevu/compiler";
20
20
  import process from "node:process";
21
- import { parse as parse$1, stringify } from "comment-json";
21
+ import { parse as parse$2, stringify } from "comment-json";
22
22
  import fs$2, { appendFile, copyFile, mkdir, readFile, readdir, rm } from "node:fs/promises";
23
23
  import { build, createLogger, createServer, loadConfigFromFile, preprocessCSS, transformWithOxc } from "vite";
24
24
  import { createHash, randomBytes } from "node:crypto";
@@ -36,10 +36,10 @@ import { spawn } from "node:child_process";
36
36
  import PQueue from "p-queue";
37
37
  import { Buffer } from "node:buffer";
38
38
  import MagicString from "magic-string";
39
+ import * as t from "@weapp-vite/ast/babelTypes";
39
40
  import babelPresetEnv from "@babel/preset-env";
40
41
  import babelPresetTypescript from "@babel/preset-typescript";
41
42
  import * as babel from "@weapp-vite/ast/babelCore";
42
- import * as t from "@weapp-vite/ast/babelTypes";
43
43
  import { Parser } from "htmlparser2";
44
44
  import { detect } from "package-manager-detector/detect";
45
45
  import tsconfigPaths from "vite-tsconfig-paths";
@@ -116,6 +116,7 @@ function parseSidecarModuleId(id) {
116
116
  const [kind, ownerId, sourceId, ...rest] = request.slice(0, -10).split(":");
117
117
  if (rest.length || !kind || !ownerId || !sourceId || ![
118
118
  "json",
119
+ "jsx",
119
120
  "layout",
120
121
  "script",
121
122
  "style",
@@ -142,6 +143,7 @@ function parseSidecarSourceRequest(id) {
142
143
  const ownerId = query.get(WEAPP_VITE_SIDECAR_OWNER_QUERY_MARKER);
143
144
  if (!kind || ![
144
145
  "json",
146
+ "jsx",
145
147
  "layout",
146
148
  "script",
147
149
  "style",
@@ -313,6 +315,10 @@ function createModuleGraphService() {
313
315
  const collectAffectedEntries = (rawFile) => {
314
316
  const file = normalizeSourceId(rawFile);
315
317
  const affected = /* @__PURE__ */ new Set();
318
+ for (const [ownerId, dependenciesByKind] of entryDependencies) for (const sourceIds of dependenciesByKind.values()) if (sourceIds.has(file)) {
319
+ affected.add(ownerId);
320
+ break;
321
+ }
316
322
  if (devServer) collectFromDevGraph(file, affected);
317
323
  else collectFromBuildGraph(file, affected);
318
324
  return affected;
@@ -572,7 +578,7 @@ function createDefaultAutoImportComponents(configService) {
572
578
  addDefaultComponentGlobs(globs, configService, "wxml");
573
579
  return globs.size ? { globs: [...globs] } : void 0;
574
580
  }
575
- function hasWevuDependency$1(configService) {
581
+ function hasWevuDependency$2(configService) {
576
582
  const packageJson = configService.packageJson ?? {};
577
583
  return Boolean(packageJson.dependencies?.wevu || packageJson.devDependencies?.wevu || packageJson.peerDependencies?.wevu);
578
584
  }
@@ -580,7 +586,7 @@ function createEnabledAutoImportComponents(configService) {
580
586
  const defaults = createDefaultAutoImportComponents(configService);
581
587
  if (!defaults) return;
582
588
  const globs = new Set(defaults.globs ?? []);
583
- if (hasWevuDependency$1(configService)) addDefaultComponentGlobs(globs, configService, "vue");
589
+ if (hasWevuDependency$2(configService)) addDefaultComponentGlobs(globs, configService, "vue");
584
590
  return {
585
591
  ...defaults,
586
592
  globs: [...globs],
@@ -588,7 +594,7 @@ function createEnabledAutoImportComponents(configService) {
588
594
  typedComponents: true,
589
595
  htmlCustomData: true,
590
596
  vueComponents: true,
591
- vueComponentsModule: hasWevuDependency$1(configService) ? "wevu" : void 0
597
+ vueComponentsModule: hasWevuDependency$2(configService) ? "wevu" : void 0
592
598
  };
593
599
  }
594
600
  function getAutoImportConfig(configService) {
@@ -1321,8 +1327,8 @@ function extractFromPropsInterfaceMembers(node) {
1321
1327
  }
1322
1328
  function extractComponentPropsFromDts(code) {
1323
1329
  let props = /* @__PURE__ */ new Map();
1324
- const ast = parse$2(code, {
1325
- ...BABEL_TS_MODULE_PARSER_OPTIONS,
1330
+ const ast = parse$3(code, {
1331
+ ...BABEL_TS_MODULE_PARSER_OPTIONS$1,
1326
1332
  errorRecovery: true
1327
1333
  });
1328
1334
  traverse(ast, {
@@ -1368,12 +1374,12 @@ function extractComponentPropsFromDts(code) {
1368
1374
  }
1369
1375
  function extractInlinePropsTypeFromCode(code) {
1370
1376
  const source = code.includes("<script") ? (() => {
1371
- const parsed = parse(code, { filename: "layout.vue" });
1377
+ const parsed = parse$1(code, { filename: "layout.vue" });
1372
1378
  return parsed.descriptor.scriptSetup?.content ?? parsed.descriptor.script?.content ?? code;
1373
1379
  })() : code;
1374
1380
  const props = /* @__PURE__ */ new Map();
1375
- const ast = parse$2(source, {
1376
- ...BABEL_TS_MODULE_PARSER_OPTIONS,
1381
+ const ast = parse$3(source, {
1382
+ ...BABEL_TS_MODULE_PARSER_OPTIONS$1,
1377
1383
  errorRecovery: true
1378
1384
  });
1379
1385
  const typeAliases = /* @__PURE__ */ new Map();
@@ -2210,7 +2216,7 @@ function createVueComponentsDefinition(componentNames, getMetadata, options = {}
2210
2216
  function extractVueComponentProps(source, filename, options = {}) {
2211
2217
  const inlineProps = extractInlinePropsTypeFromCode(source);
2212
2218
  if (inlineProps.size > 0) return inlineProps;
2213
- const { descriptor, errors } = parse(source, { filename });
2219
+ const { descriptor, errors } = parse$1(source, { filename });
2214
2220
  if (errors.length || !descriptor.script && !descriptor.scriptSetup) return /* @__PURE__ */ new Map();
2215
2221
  const compiled = compileScript(descriptor, {
2216
2222
  id: filename,
@@ -5079,7 +5085,7 @@ function buildCandidates(base, extensions) {
5079
5085
  return extensions.map((ext) => changeFileExtension(base, ext));
5080
5086
  }
5081
5087
  function resolveEntryExtensions(kind, isDir) {
5082
- return kind === "named" || isDir ? [...jsExtensions, ...vueExtensions] : [...vueExtensions, ...jsExtensions];
5088
+ return kind === "named" || isDir ? [...scriptExtensions, ...vueExtensions] : [...vueExtensions, ...scriptExtensions];
5083
5089
  }
5084
5090
  function createCachedEntryResolveOptions(configService, options) {
5085
5091
  return {
@@ -5125,7 +5131,7 @@ const COMPONENT_NAME_MULTI_UPPER_RE = /([A-Z]+)([A-Z][a-z])/g;
5125
5131
  const COMPONENT_NAME_HAS_UPPER_RE = /[A-Z]/;
5126
5132
  const SCOPED_SLOT_GENERIC_KEY_RE$1 = /^scoped-slots-/;
5127
5133
  function parseCommentJson(json) {
5128
- return parse$1(json, void 0, true);
5134
+ return parse$2(json, void 0, true);
5129
5135
  }
5130
5136
  function jsonFileRemoveJsExtension(fileName) {
5131
5137
  return fileName.replace(JSON_FILE_JS_EXTENSION_RE, "");
@@ -5387,7 +5393,7 @@ function parseModuleForReExport(code, astEngine) {
5387
5393
  engine: "oxc",
5388
5394
  filename: "inline.ts"
5389
5395
  });
5390
- return parse$2(code, BABEL_TS_MODULE_PARSER_OPTIONS).program;
5396
+ return parse$3(code, BABEL_TS_MODULE_PARSER_OPTIONS$1).program;
5391
5397
  }
5392
5398
  async function resolveReExportedInternal(exporterFile, exportName, depth, visited, options) {
5393
5399
  if (depth <= 0) return;
@@ -6413,7 +6419,7 @@ async function resolveDefaultSearchRoots(absoluteSrcRoot, subPackageRoots) {
6413
6419
  }
6414
6420
  //#endregion
6415
6421
  //#region src/runtime/autoRoutesPlugin/candidates.ts
6416
- const SCRIPT_EXTENSIONS = new Set(jsExtensions.map((ext) => `.${ext}`));
6422
+ const SCRIPT_EXTENSIONS = new Set(scriptExtensions.map((ext) => `.${ext}`));
6417
6423
  const TEMPLATE_EXTENSIONS = new Set(templateExtensions.map((ext) => `.${ext}`));
6418
6424
  const VUE_EXTENSIONS = new Set(vueExtensions.map((ext) => `.${ext}`));
6419
6425
  const STYLE_EXTENSIONS = new Set(supportedCssLangs.map((ext) => `.${ext}`));
@@ -6784,11 +6790,6 @@ function applyBuildScopeToAutoRoutes(routes, scope) {
6784
6790
  subPackages
6785
6791
  };
6786
6792
  }
6787
- function applyBuildScopeToSubPackageRoots(roots, scope) {
6788
- if (!scope?.enabled) return roots;
6789
- const scopedRoots = new Set(scope.subPackageRoots);
6790
- return roots.map((root) => normalizeRoot(root)).filter((root) => scopedRoots.has(root));
6791
- }
6792
6793
  //#endregion
6793
6794
  //#region src/utils/miniProgramGlobals.ts
6794
6795
  function getMiniProgramGlobalKeys() {
@@ -6934,7 +6935,7 @@ function getAutoRoutesSubPackageRoots(ctx) {
6934
6935
  const npmSubPackageRoots = Object.keys(ctx.configService?.weappViteConfig?.npm?.subPackages ?? {});
6935
6936
  for (const root of npmSubPackageRoots) roots.add(root);
6936
6937
  for (const root of collectAppJsonSubPackageRoots(ctx)) roots.add(root);
6937
- return applyBuildScopeToSubPackageRoots([...roots], resolveBuildScope(ctx.configService?.weappViteConfig?.buildScope));
6938
+ return [...roots];
6938
6939
  }
6939
6940
  //#endregion
6940
6941
  //#region src/runtime/autoRoutesPlugin/shared.ts
@@ -7648,7 +7649,7 @@ function collectResolverPlugins(config) {
7648
7649
  return (Array.isArray(config.plugins) ? config.plugins : config.plugins ? [config.plugins] : []).filter((plugin) => !isInternalPlugin(plugin));
7649
7650
  }
7650
7651
  async function transformVueSource(code, id) {
7651
- const { descriptor, errors } = parse(code, { filename: id });
7652
+ const { descriptor, errors } = parse$1(code, { filename: id });
7652
7653
  if (errors.length) throw errors[0];
7653
7654
  const blocks = [descriptor.script, descriptor.scriptSetup].filter((block) => block?.content);
7654
7655
  const source = blocks.map((block) => block.content).join("\n") || "export default {}";
@@ -11142,6 +11143,512 @@ function isStatefulHmrRuntimeCompatibilityError(error) {
11142
11143
  return error instanceof StatefulHmrRuntimeCompatibilityError || typeof error === "object" && error !== null && Reflect.get(error, "code") === "WEAPP_VITE_STATEFUL_HMR_RUNTIME_INCOMPATIBLE";
11143
11144
  }
11144
11145
  //#endregion
11146
+ //#region src/plugins/react/baseTemplate.ts
11147
+ const MAX_TEMPLATE_DEPTH = 4;
11148
+ function renderHostAttributes(tag) {
11149
+ const common = "id=\"{{i.p.id}}\" class=\"{{i.cl}}\" style=\"{{i.st}}\" data-sid=\"{{i.sid}}\"";
11150
+ if (tag === "button") return `${common} disabled="{{i.p.disabled}}" bindtap="${WEAPP_REACT_EVENT_METHOD_NAME}"`;
11151
+ if (tag === "input") return `${common} value="{{i.p.value}}" type="{{i.p.type}}" checked="{{i.p.checked}}" disabled="{{i.p.disabled}}" placeholder="{{i.p.placeholder}}" bindinput="${WEAPP_REACT_EVENT_METHOD_NAME}" bindchange="${WEAPP_REACT_EVENT_METHOD_NAME}"`;
11152
+ return `${common} hidden="{{i.p.hidden}}" bindtap="${WEAPP_REACT_EVENT_METHOD_NAME}"`;
11153
+ }
11154
+ function renderHost(tag, depth) {
11155
+ const attributes = renderHostAttributes(tag);
11156
+ if (tag === "input" || depth === MAX_TEMPLATE_DEPTH) return ` <${tag} wx:elif="{{i.nn === '${tag}'}}" ${attributes} />`;
11157
+ return [
11158
+ ` <${tag} wx:elif="{{i.nn === '${tag}'}}" ${attributes}>`,
11159
+ " <block wx:for=\"{{i.cn}}\" wx:key=\"sid\" wx:for-item=\"child\">",
11160
+ ` <template is="react_node_${depth + 1}" data="{{i:child}}" />`,
11161
+ " </block>",
11162
+ ` </${tag}>`
11163
+ ].join("\n");
11164
+ }
11165
+ function renderNodeTemplate(depth) {
11166
+ return [
11167
+ `<template name="react_node_${depth}">`,
11168
+ " <block wx:if=\"{{i.nn === '#text'}}\">{{i.v}}</block>",
11169
+ renderHost("view", depth),
11170
+ renderHost("text", depth),
11171
+ renderHost("button", depth),
11172
+ renderHost("input", depth),
11173
+ "</template>"
11174
+ ].join("\n");
11175
+ }
11176
+ const baseTemplate = [
11177
+ "<template name=\"react_root\">",
11178
+ " <block wx:for=\"{{root.cn}}\" wx:key=\"sid\" wx:for-item=\"child\">",
11179
+ " <template is=\"react_node_0\" data=\"{{i:child}}\" />",
11180
+ " </block>",
11181
+ "</template>",
11182
+ "",
11183
+ ...Array.from({ length: 5 }, (_, depth) => renderNodeTemplate(depth)),
11184
+ ""
11185
+ ].join("\n");
11186
+ //#endregion
11187
+ //#region src/plugins/react/staticTemplate/style.ts
11188
+ const UNITLESS_STYLE_PROPERTIES = /* @__PURE__ */ new Set([
11189
+ "flex",
11190
+ "flexGrow",
11191
+ "flexShrink",
11192
+ "fontWeight",
11193
+ "lineHeight",
11194
+ "opacity",
11195
+ "order",
11196
+ "zIndex"
11197
+ ]);
11198
+ function toKebabCase$2(value) {
11199
+ return value.replace(/[A-Z]/g, (char) => `-${char.toLowerCase()}`);
11200
+ }
11201
+ function readPropertyName(node) {
11202
+ if (t.isIdentifier(node)) return node.name;
11203
+ if (t.isStringLiteral(node)) return node.value;
11204
+ }
11205
+ function readPropertyValue(node) {
11206
+ if (t.isStringLiteral(node) || t.isNumericLiteral(node)) return node.value;
11207
+ }
11208
+ function compileStaticStyle(expression) {
11209
+ const declarations = [];
11210
+ for (const property of expression.properties) {
11211
+ if (!t.isObjectProperty(property) || property.computed) return;
11212
+ const name = readPropertyName(property.key);
11213
+ const value = readPropertyValue(property.value);
11214
+ if (!name || value === void 0) return;
11215
+ const normalized = typeof value === "number" && !UNITLESS_STYLE_PROPERTIES.has(name) ? `${value}px` : String(value);
11216
+ declarations.push(`${toKebabCase$2(name)}:${normalized}`);
11217
+ }
11218
+ return declarations.join(";");
11219
+ }
11220
+ //#endregion
11221
+ //#region src/plugins/react/staticTemplate/render.ts
11222
+ const HOST_TAGS = {
11223
+ Button: "button",
11224
+ Input: "input",
11225
+ Text: "text",
11226
+ View: "view",
11227
+ button: "button",
11228
+ input: "input",
11229
+ text: "text",
11230
+ view: "view"
11231
+ };
11232
+ const EVENT_NAMES = {
11233
+ onChange: "bindchange",
11234
+ onInput: "bindinput",
11235
+ onTap: "bindtap",
11236
+ onTapCapture: "capture-bind:tap"
11237
+ };
11238
+ const EVENT_PROP_RE = /^on[A-Z]/;
11239
+ const IDENTIFIER_RE = /^[A-Z_$][\w$]*$/i;
11240
+ function escapeAttribute(value) {
11241
+ return value.replaceAll("&", "&amp;").replaceAll("\"", "&quot;").replaceAll("<", "&lt;");
11242
+ }
11243
+ function escapeText(value) {
11244
+ return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
11245
+ }
11246
+ function normalizeJsxText(value) {
11247
+ return value.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).join(" ");
11248
+ }
11249
+ function readTagName(node, context) {
11250
+ if (!t.isJSXIdentifier(node)) throw new Error("static template 暂不支持 member/namespaced JSX tag");
11251
+ const tag = HOST_TAGS[node.name];
11252
+ if (tag) return {
11253
+ kind: "host",
11254
+ tag
11255
+ };
11256
+ if (context.slotComponentNames.has(node.name) || node.name === "slot") return {
11257
+ kind: "slot",
11258
+ tag: "slot"
11259
+ };
11260
+ const nativeTag = context.nativeComponentTags.get(node.name);
11261
+ if (nativeTag) {
11262
+ context.usedNativeComponents.add(nativeTag);
11263
+ return {
11264
+ kind: "native",
11265
+ tag: nativeTag
11266
+ };
11267
+ }
11268
+ throw new Error(`static template 暂不支持动态组件 <${node.name}>`);
11269
+ }
11270
+ function readAttributeExpression(attribute) {
11271
+ if (!attribute.value) return t.booleanLiteral(true);
11272
+ if (t.isStringLiteral(attribute.value)) return attribute.value;
11273
+ if (!t.isJSXExpressionContainer(attribute.value) || t.isJSXEmptyExpression(attribute.value.expression)) return;
11274
+ return attribute.value.expression;
11275
+ }
11276
+ function readStaticPrimitive(expression) {
11277
+ if (t.isStringLiteral(expression) || t.isNumericLiteral(expression) || t.isBooleanLiteral(expression)) return expression.value;
11278
+ if (t.isTemplateLiteral(expression) && expression.expressions.length === 0) return expression.quasis[0]?.value.cooked ?? "";
11279
+ }
11280
+ function appendInternalAttribute(element, name, value) {
11281
+ element.openingElement.attributes.push(t.jsxAttribute(t.jsxIdentifier(name), t.stringLiteral(value)));
11282
+ }
11283
+ function toKebabCase$1(value) {
11284
+ return value.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
11285
+ }
11286
+ function resolveNativeEvent(name) {
11287
+ if (!EVENT_PROP_RE.test(name)) return;
11288
+ const capture = name.endsWith("Capture");
11289
+ const eventName = name.slice(2, capture ? -7 : void 0);
11290
+ if (!eventName) return;
11291
+ return `${capture ? "capture-bind" : "bind"}:${toKebabCase$1(eventName)}`;
11292
+ }
11293
+ function renderBindingExpression(slot, name) {
11294
+ return IDENTIFIER_RE.test(name) ? `slots.${slot}.${name}` : `slots.${slot}['${name}']`;
11295
+ }
11296
+ function compileAttributes(element, slot, bindingFields, tagKind) {
11297
+ const output = [];
11298
+ let hasEvent = false;
11299
+ for (const attribute of element.openingElement.attributes) {
11300
+ if (!t.isJSXAttribute(attribute) || !t.isJSXIdentifier(attribute.name)) throw new Error("static template 暂不支持 JSX spread 或动态属性名");
11301
+ const name = attribute.name.name;
11302
+ if (name === "key") continue;
11303
+ const eventName = tagKind === "native" ? resolveNativeEvent(name) : EVENT_NAMES[name];
11304
+ if (eventName) {
11305
+ hasEvent = true;
11306
+ output.push(`${eventName}="${WEAPP_REACT_EVENT_METHOD_NAME}"`);
11307
+ continue;
11308
+ }
11309
+ if (EVENT_PROP_RE.test(name)) throw new Error(`static template 暂不支持事件 ${name}`);
11310
+ const expression = readAttributeExpression(attribute);
11311
+ if (!expression) continue;
11312
+ const outputName = name === "className" ? "class" : name;
11313
+ if (name === "style" && t.isObjectExpression(expression)) {
11314
+ const style = compileStaticStyle(expression);
11315
+ if (style !== void 0) {
11316
+ output.push(`style="${escapeAttribute(style)}"`);
11317
+ continue;
11318
+ }
11319
+ }
11320
+ const staticValue = readStaticPrimitive(expression);
11321
+ if (staticValue !== void 0) {
11322
+ output.push(`${outputName}="${escapeAttribute(String(staticValue))}"`);
11323
+ continue;
11324
+ }
11325
+ bindingFields.add(name);
11326
+ output.push(`${outputName}="{{${renderBindingExpression(slot, name)}}}"`);
11327
+ }
11328
+ if (hasEvent) output.push(`data-sid="${slot}"`);
11329
+ return output;
11330
+ }
11331
+ function isDynamicTextExpression(node) {
11332
+ return !t.isJSXEmptyExpression(node.expression) && readStaticPrimitive(node.expression) === void 0;
11333
+ }
11334
+ function compileStaticChildren(children, context) {
11335
+ return children.map((child) => {
11336
+ if (t.isJSXText(child)) return escapeText(normalizeJsxText(child.value));
11337
+ if (t.isJSXElement(child)) return compileStaticElement(child, context);
11338
+ if (t.isJSXFragment(child)) return compileStaticFragment(child, context);
11339
+ if (t.isJSXExpressionContainer(child)) {
11340
+ if (t.isJSXEmptyExpression(child.expression)) return "";
11341
+ const value = readStaticPrimitive(child.expression);
11342
+ if (value !== void 0) return escapeText(String(value));
11343
+ throw new Error("static template 的容器节点暂不支持动态结构表达式");
11344
+ }
11345
+ return "";
11346
+ }).join("");
11347
+ }
11348
+ function compileStaticFragment(fragment, context) {
11349
+ return compileStaticChildren(fragment.children, context);
11350
+ }
11351
+ function compileStaticElement(element, context) {
11352
+ const resolvedTag = readTagName(element.openingElement.name, context);
11353
+ const { tag } = resolvedTag;
11354
+ const slot = `s${context.slotSeed++}`;
11355
+ const bindingFields = /* @__PURE__ */ new Set();
11356
+ const slotRecord = {
11357
+ bindings: [],
11358
+ id: slot,
11359
+ tag
11360
+ };
11361
+ context.slots.push(slotRecord);
11362
+ const attributes = compileAttributes(element, slot, bindingFields, resolvedTag.kind);
11363
+ const children = element.children;
11364
+ const hasDynamicText = (tag === "text" || tag === "button") && children.some((child) => t.isJSXExpressionContainer(child) && isDynamicTextExpression(child));
11365
+ let content;
11366
+ if (hasDynamicText) {
11367
+ if (children.some((child) => t.isJSXElement(child) || t.isJSXFragment(child))) throw new Error(`static template 的 <${tag}> 不支持动态文本与元素子节点混用`);
11368
+ bindingFields.add("text");
11369
+ content = `{{slots.${slot}.text}}`;
11370
+ } else content = compileStaticChildren(children, context);
11371
+ appendInternalAttribute(element, "__slot", slot);
11372
+ if (bindingFields.size > 0) appendInternalAttribute(element, "__bindingFields", [...bindingFields].join(","));
11373
+ slotRecord.bindings = [...bindingFields];
11374
+ const attributeSegment = attributes.length > 0 ? ` ${attributes.join(" ")}` : "";
11375
+ if (resolvedTag.kind === "slot" && children.length > 0) throw new Error("static template 的 <Slot> 不支持子节点");
11376
+ if (element.openingElement.selfClosing) return `<${tag}${attributeSegment} />`;
11377
+ return `<${tag}${attributeSegment}>${content}</${tag}>`;
11378
+ }
11379
+ function renderStaticTemplate(root, context) {
11380
+ return t.isJSXElement(root) ? compileStaticElement(root, context) : compileStaticFragment(root, context);
11381
+ }
11382
+ //#endregion
11383
+ //#region src/plugins/react/staticTemplate/index.ts
11384
+ const REACT_RUNTIME_MODULE_ID = "@weapp-vite/react";
11385
+ var ReactNativeBridgeStaticError = class extends Error {
11386
+ constructor(filename, cause) {
11387
+ const message = cause instanceof Error ? cause.message : String(cause);
11388
+ super(`[react] ${filename} 使用了原生组件 bridge,组件结构必须可静态分析:${message}`, { cause });
11389
+ this.name = "ReactNativeBridgeStaticError";
11390
+ }
11391
+ };
11392
+ function collectRuntimeImportNames(ast, importedName) {
11393
+ const names = /* @__PURE__ */ new Set();
11394
+ for (const statement of ast.program.body) {
11395
+ if (!t.isImportDeclaration(statement) || statement.source.value !== REACT_RUNTIME_MODULE_ID) continue;
11396
+ for (const specifier of statement.specifiers) if (t.isImportSpecifier(specifier) && t.isIdentifier(specifier.imported, { name: importedName })) names.add(specifier.local.name);
11397
+ }
11398
+ return names;
11399
+ }
11400
+ function collectNativeComponentTags(ast, factoryNames) {
11401
+ const tags = /* @__PURE__ */ new Map();
11402
+ for (const statement of ast.program.body) {
11403
+ const declaration = t.isVariableDeclaration(statement) ? statement : t.isExportNamedDeclaration(statement) && t.isVariableDeclaration(statement.declaration) ? statement.declaration : void 0;
11404
+ if (!declaration) continue;
11405
+ for (const item of declaration.declarations) {
11406
+ if (!t.isIdentifier(item.id) || !t.isCallExpression(item.init) || !t.isIdentifier(item.init.callee) || !factoryNames.has(item.init.callee.name)) continue;
11407
+ const [tagArgument] = item.init.arguments;
11408
+ if (!t.isStringLiteral(tagArgument) || !tagArgument.value) throw new Error("createNativeComponent 的 tagName 必须是非空字符串字面量");
11409
+ tags.set(item.id.name, tagArgument.value);
11410
+ }
11411
+ }
11412
+ return tags;
11413
+ }
11414
+ function collectNativeBridgeContext(ast) {
11415
+ return {
11416
+ nativeComponentTags: collectNativeComponentTags(ast, collectRuntimeImportNames(ast, "createNativeComponent")),
11417
+ slotComponentNames: collectRuntimeImportNames(ast, "Slot")
11418
+ };
11419
+ }
11420
+ function hasNativeComponentBridge(source) {
11421
+ return collectNativeBridgeContext(parse(source, BABEL_TS_MODULE_PARSER_OPTIONS)).nativeComponentTags.size > 0;
11422
+ }
11423
+ function findFunctionDeclaration(ast, componentName) {
11424
+ for (const statement of ast.program.body) {
11425
+ if (t.isFunctionDeclaration(statement) && statement.id?.name === componentName) return statement;
11426
+ if (t.isExportNamedDeclaration(statement) && t.isFunctionDeclaration(statement.declaration) && statement.declaration.id?.name === componentName) return statement.declaration;
11427
+ }
11428
+ }
11429
+ function findReturnedTemplate(component) {
11430
+ for (const statement of component.body.body) {
11431
+ if (!t.isReturnStatement(statement) || !statement.argument) continue;
11432
+ if (t.isJSXElement(statement.argument) || t.isJSXFragment(statement.argument)) return statement.argument;
11433
+ }
11434
+ }
11435
+ function findFirstFunctionDeclaration(ast) {
11436
+ for (const statement of ast.program.body) {
11437
+ const candidate = t.isFunctionDeclaration(statement) ? statement : t.isExportNamedDeclaration(statement) && t.isFunctionDeclaration(statement.declaration) ? statement.declaration : void 0;
11438
+ if (candidate?.id && findReturnedTemplate(candidate)) return candidate;
11439
+ }
11440
+ }
11441
+ function compileStaticReactPage(source, filename, componentName) {
11442
+ const ast = parse(source, BABEL_TS_MODULE_PARSER_OPTIONS);
11443
+ const bridgeContext = collectNativeBridgeContext(ast);
11444
+ try {
11445
+ const component = componentName ? findFunctionDeclaration(ast, componentName) : findFirstFunctionDeclaration(ast);
11446
+ if (!component) throw new Error(`未找到直接 return JSX 的 static template 组件${componentName ? ` ${componentName}` : ""}`);
11447
+ const root = findReturnedTemplate(component);
11448
+ if (!root) throw new Error(`static template 组件 ${componentName ?? component.id?.name ?? ""} 必须直接 return JSX`);
11449
+ const context = {
11450
+ ...bridgeContext,
11451
+ slots: [],
11452
+ slotSeed: 0,
11453
+ usedNativeComponents: /* @__PURE__ */ new Set()
11454
+ };
11455
+ const template = renderStaticTemplate(root, context);
11456
+ return {
11457
+ code: generate(ast, {
11458
+ sourceFileName: filename,
11459
+ sourceMaps: true
11460
+ }, source).code,
11461
+ nativeComponents: [...context.usedNativeComponents].sort(),
11462
+ slots: context.slots,
11463
+ template
11464
+ };
11465
+ } catch (error) {
11466
+ if (bridgeContext.nativeComponentTags.size > 0 && !(error instanceof ReactNativeBridgeStaticError)) throw new ReactNativeBridgeStaticError(filename, error);
11467
+ throw error;
11468
+ }
11469
+ }
11470
+ //#endregion
11471
+ //#region src/plugins/react/index.ts
11472
+ const REACT_PLUGIN_NAME = "weapp-vite:react";
11473
+ const REACT_FILE_RE = /\.(?:jsx|tsx)(?:\?.*)?$/;
11474
+ function resolveStaticTemplateFileName(cwd, id) {
11475
+ const cleanId = id.split("?", 1)[0] ?? id;
11476
+ let fileName = path$1.relative(cwd, cleanId).replaceAll("\\", "/").replace(/\.(?:jsx|tsx)$/, ".wxml").replace(/^src\//, "");
11477
+ if (fileName.endsWith("/view.wxml")) fileName = fileName.replace(/\/view\.wxml$/, "/index.wxml");
11478
+ return fileName;
11479
+ }
11480
+ function createDynamicTemplate(fileName) {
11481
+ const relative = path$1.posix.relative(path$1.posix.dirname(fileName), "runtime/base.wxml");
11482
+ return `<import src="${relative.startsWith(".") ? relative : `./${relative}`}" />\n<template is="react_root" data="{{root:root}}" />`;
11483
+ }
11484
+ function resolveReactConfig(value) {
11485
+ if (!value) return;
11486
+ return value === true ? {} : value;
11487
+ }
11488
+ function isReactEnabled(ctx) {
11489
+ return Boolean(resolveReactConfig(ctx.configService?.weappViteConfig?.react));
11490
+ }
11491
+ function resolveReactConfigValue(value) {
11492
+ const config = resolveReactConfig(value);
11493
+ if (!config) return;
11494
+ return {
11495
+ compiler: config.compiler ?? false,
11496
+ renderMode: config.renderMode ?? "auto",
11497
+ devWarnings: config.devWarnings ?? true
11498
+ };
11499
+ }
11500
+ function isReactStaticTemplateSource(value, id) {
11501
+ const config = resolveReactConfigValue(value);
11502
+ return Boolean(config && config.renderMode !== "dynamic" && REACT_FILE_RE.test(id) && !id.includes("/node_modules/"));
11503
+ }
11504
+ async function transformWithSwc$1(source, id, compilationMode) {
11505
+ try {
11506
+ const { transform } = await import("@swc/core");
11507
+ const result = await transform(source, {
11508
+ filename: id,
11509
+ jsc: {
11510
+ parser: {
11511
+ syntax: "typescript",
11512
+ tsx: true
11513
+ },
11514
+ target: "es2020",
11515
+ transform: {
11516
+ react: {
11517
+ importSource: "react",
11518
+ runtime: "automatic"
11519
+ },
11520
+ reactCompiler: { compilationMode }
11521
+ }
11522
+ },
11523
+ module: { type: "es6" },
11524
+ sourceMaps: true
11525
+ });
11526
+ return {
11527
+ code: result.code,
11528
+ map: result.map
11529
+ };
11530
+ } catch (error) {
11531
+ return {
11532
+ fallback: true,
11533
+ warning: `[react] React Compiler transform failed for ${id}; falling back to Oxc: ${error instanceof Error ? error.message : String(error)}`
11534
+ };
11535
+ }
11536
+ }
11537
+ function createReactPlugin(ctx) {
11538
+ const resolved = resolveReactConfigValue(ctx.configService?.weappViteConfig?.react);
11539
+ if (!resolved) return [];
11540
+ const reactConfig = resolved;
11541
+ let config;
11542
+ const templates = /* @__PURE__ */ new Map();
11543
+ async function refreshStaticTemplate(id, event, warn) {
11544
+ if (!isReactStaticTemplateSource(reactConfig, id)) return;
11545
+ const cleanId = id.split("?", 1)[0] ?? id;
11546
+ const fileName = resolveStaticTemplateFileName(ctx.configService?.cwd ?? process.cwd(), cleanId);
11547
+ if (event === "delete") {
11548
+ templates.delete(fileName);
11549
+ return;
11550
+ }
11551
+ try {
11552
+ const compiled = compileStaticReactPage(await readFile(cleanId, "utf8"), cleanId);
11553
+ templates.set(fileName, {
11554
+ nativeComponents: compiled.nativeComponents,
11555
+ source: compiled.template
11556
+ });
11557
+ } catch (error) {
11558
+ if (error instanceof ReactNativeBridgeStaticError) throw error;
11559
+ if (reactConfig.renderMode === "static") throw error;
11560
+ templates.set(fileName, {
11561
+ nativeComponents: [],
11562
+ source: createDynamicTemplate(fileName)
11563
+ });
11564
+ if (reactConfig.devWarnings && error instanceof Error) warn(`[react] dynamic island fallback for ${cleanId}: ${error.message}`);
11565
+ }
11566
+ }
11567
+ return [{
11568
+ name: REACT_PLUGIN_NAME,
11569
+ enforce: "pre",
11570
+ configResolved(next) {
11571
+ config = next;
11572
+ },
11573
+ async watchChange(id, change) {
11574
+ await refreshStaticTemplate(id, change.event, (message) => this.warn(message));
11575
+ },
11576
+ async handleHotUpdate(context) {
11577
+ await refreshStaticTemplate(context.file, "update", (message) => this.warn(message));
11578
+ },
11579
+ transform: async function transformReact(source, id) {
11580
+ if (!REACT_FILE_RE.test(id) || id.includes("/node_modules/")) return null;
11581
+ let transformedSource = source;
11582
+ const fileName = resolveStaticTemplateFileName(ctx.configService?.cwd ?? process.cwd(), id);
11583
+ if (resolved.renderMode === "dynamic" && hasNativeComponentBridge(source)) throw new Error(`[react] ${id} 使用了原生组件 bridge,renderMode: 'dynamic' 不支持自定义组件`);
11584
+ if (resolved.renderMode !== "dynamic") try {
11585
+ const compiled = compileStaticReactPage(source, id);
11586
+ templates.set(fileName, {
11587
+ nativeComponents: compiled.nativeComponents,
11588
+ source: compiled.template
11589
+ });
11590
+ transformedSource = compiled.code;
11591
+ } catch (error) {
11592
+ if (resolved.renderMode === "static" || error instanceof ReactNativeBridgeStaticError) throw error;
11593
+ templates.set(fileName, {
11594
+ nativeComponents: [],
11595
+ source: createDynamicTemplate(fileName)
11596
+ });
11597
+ if (resolved.devWarnings && error instanceof Error) this.warn(`[react] dynamic island fallback for ${id}: ${error.message}`);
11598
+ }
11599
+ else templates.set(fileName, {
11600
+ nativeComponents: [],
11601
+ source: createDynamicTemplate(fileName)
11602
+ });
11603
+ if (resolved.compiler !== false) {
11604
+ const compilerConfig = typeof resolved.compiler === "object" ? resolved.compiler : {};
11605
+ const result = await transformWithSwc$1(transformedSource, id, compilerConfig.compilationMode ?? "infer");
11606
+ if (!result.fallback) return result;
11607
+ if (resolved.devWarnings !== false) this.warn(result.warning);
11608
+ }
11609
+ return await transformWithOxc(transformedSource, id, {
11610
+ jsx: {
11611
+ importSource: "react",
11612
+ runtime: "automatic"
11613
+ },
11614
+ lang: "tsx",
11615
+ sourcemap: Boolean(config?.command === "serve")
11616
+ });
11617
+ },
11618
+ generateBundle(_options, bundle) {
11619
+ for (const [fileName, template] of templates) {
11620
+ if (template.nativeComponents.length > 0) {
11621
+ const jsonFileName = fileName.replace(/\.wxml$/, ".json");
11622
+ const jsonAsset = bundle[jsonFileName];
11623
+ if (jsonAsset?.type !== "asset") throw new Error(`[react] ${fileName} 使用了原生组件 bridge,但缺少对应配置 ${jsonFileName}`);
11624
+ let json;
11625
+ try {
11626
+ json = JSON.parse(String(jsonAsset.source));
11627
+ } catch (error) {
11628
+ throw new Error(`[react] 无法解析原生组件配置 ${jsonFileName}`, { cause: error });
11629
+ }
11630
+ const usingComponents = json.usingComponents;
11631
+ const registered = usingComponents && typeof usingComponents === "object" && !Array.isArray(usingComponents) ? usingComponents : {};
11632
+ const missing = template.nativeComponents.filter((tag) => typeof registered[tag] !== "string");
11633
+ if (missing.length > 0) throw new Error(`[react] ${fileName} 的原生组件 bridge 未在 ${jsonFileName} 的 usingComponents 注册:${missing.join(", ")}`);
11634
+ }
11635
+ const existing = bundle[fileName];
11636
+ if (existing?.type === "asset") existing.source = template.source;
11637
+ else this.emitFile({
11638
+ type: "asset",
11639
+ fileName,
11640
+ source: template.source
11641
+ });
11642
+ }
11643
+ if (resolved.renderMode !== "static" && !bundle["runtime/base.wxml"]) this.emitFile({
11644
+ type: "asset",
11645
+ fileName: "runtime/base.wxml",
11646
+ source: baseTemplate
11647
+ });
11648
+ }
11649
+ }];
11650
+ }
11651
+ //#endregion
11145
11652
  //#region src/runtime/statefulHmr/outputWriter.ts
11146
11653
  /**
11147
11654
  * @description 通过独立的 Vite write 阶段持久化 DevEngine 已生成的文件,不重新解析业务源码。
@@ -11891,7 +12398,7 @@ var StatefulHmrSession = class {
11891
12398
  const normalizedFile = normalizeFsResolvedId(path.isAbsolute(file) ? file : path.resolve(this.server.config.root, file));
11892
12399
  const normalizedOutDir = normalizeFsResolvedId(this.ctx.configService.outDir).replace(/\/$/, "");
11893
12400
  if (normalizedFile === normalizedOutDir || normalizedFile.startsWith(`${normalizedOutDir}/`)) return;
11894
- if (shouldRestartStatefulHmrServer([normalizedFile], this.ctx.configService?.configFileDependencies)) {
12401
+ if (shouldRestartStatefulHmrServer([normalizedFile], this.ctx.configService?.configFileDependencies, this.ctx.configService?.weappViteConfig?.react)) {
11895
12402
  this.requestServerRestart();
11896
12403
  return;
11897
12404
  }
@@ -11930,7 +12437,7 @@ var StatefulHmrSession = class {
11930
12437
  if (output.type === "Noop") return false;
11931
12438
  if (!isSafeJavaScriptPatch(files, output, this.ctx.runtimeState.build.hmr.profile.dirtyReasonSummary, this.ctx.runtimeState.build.hmr.resolvedEntryMap.keys(), this.server.config.root)) {
11932
12439
  if (shouldRestartStatefulHmrServer(files, this.ctx.configService?.configFileDependencies)) this.requestServerRestart();
11933
- else if (files.length > 0 && files.every(isStatefulHmrAssetFile) || shouldUseStatefulHmrSnapshotOnly(this.ctx.runtimeState.build.hmr.profile.dirtyReasonSummary ?? [])) {
12440
+ else if (this.snapshotScheduler.isPending() || files.length > 0 && files.every(isStatefulHmrAssetFile) || shouldUseStatefulHmrSnapshotOnly(this.ctx.runtimeState.build.hmr.profile.dirtyReasonSummary ?? [])) {
11934
12441
  if (!this.snapshotScheduler.isPending()) this.requestSnapshotRefresh(files);
11935
12442
  } else this.requestFullBuild(files);
11936
12443
  return false;
@@ -11998,9 +12505,9 @@ var StatefulHmrSession = class {
11998
12505
  await this.outputChain;
11999
12506
  }
12000
12507
  };
12001
- function shouldRestartStatefulHmrServer(files, configFileDependencies = []) {
12508
+ function shouldRestartStatefulHmrServer(files, configFileDependencies = [], react) {
12002
12509
  const normalizedConfigDependencies = new Set(Array.from(configFileDependencies, (dependency) => normalizeFsResolvedId(dependency)));
12003
- return Array.from(files).some((file) => normalizedConfigDependencies.has(normalizeFsResolvedId(file)));
12510
+ return Array.from(files).some((file) => normalizedConfigDependencies.has(normalizeFsResolvedId(file)) || isReactStaticTemplateSource(react, file));
12004
12511
  }
12005
12512
  function mergeStatefulHmrSnapshotAssets(output, snapshotAssets) {
12006
12513
  for (const asset of snapshotAssets) {
@@ -12067,13 +12574,13 @@ function isSafeJavaScriptPatch(files, output, dirtyReasonSummary = [], entryIds,
12067
12574
  })) && !output.changedIds?.some(isNonJavaScriptSidecarId) && !dirtyReasonSummary.some(isUnsafeStatefulHmrReason);
12068
12575
  }
12069
12576
  function requiresStatefulHmrSnapshot(file, dirtyReasonSummary = []) {
12070
- return !/\.(?:[cm]?[jt]sx?|vue)$/.test(file) || dirtyReasonSummary.some(isUnsafeStatefulHmrReason);
12577
+ return /\.(?:jsx|tsx)$/.test(file) || !/\.(?:[cm]?[jt]sx?|vue)$/.test(file) || dirtyReasonSummary.some(isUnsafeStatefulHmrReason);
12071
12578
  }
12072
12579
  function isStatefulHmrAssetFile(file) {
12073
12580
  return !/\.(?:[cm]?[jt]sx?|vue)$/.test(file);
12074
12581
  }
12075
12582
  function isUnsafeStatefulHmrReason(reason) {
12076
- return /^(?:entry-json-only|entry-local-asset|entry-style-only|tailwind-content):/.test(reason);
12583
+ return /^(?:entry-json-only|entry-local-asset|entry-style-only|react-template|tailwind-content):/.test(reason);
12077
12584
  }
12078
12585
  function shouldUseStatefulHmrSnapshotOnly(dirtyReasonSummary) {
12079
12586
  return dirtyReasonSummary.some((reason) => /^(?:entry-json-only|entry-local-asset|entry-style-only):/.test(reason)) && dirtyReasonSummary.every((reason) => /^(?:entry-json-only|entry-local-asset|entry-style-only|tailwind-content):/.test(reason));
@@ -12154,7 +12661,7 @@ const GLOB_WILDCARD_RE$1 = /[*?[{]/;
12154
12661
  const TRAILING_SLASHES_RE$2 = /\/+$/;
12155
12662
  const AUTO_IMPORT_WATCHER_KEY = "__auto-import-vue-watcher__";
12156
12663
  const AUTO_IMPORT_CONFIG_SUFFIXES = configExtensions.map((ext) => `.${ext}`);
12157
- const AUTO_IMPORT_JS_SUFFIXES = new Set(jsExtensions.map((ext) => `.${ext}`));
12664
+ const AUTO_IMPORT_JS_SUFFIXES = new Set(scriptExtensions.map((ext) => `.${ext}`));
12158
12665
  const AUTO_IMPORT_TEMPLATE_SUFFIXES = new Set(templateExtensions.map((ext) => `.${ext}`));
12159
12666
  const AUTO_IMPORT_VUE_SUFFIXES = new Set(vueExtensions.map((ext) => `.${ext}`));
12160
12667
  function hasOwn$4(source, key) {
@@ -13240,6 +13747,7 @@ function shouldNormalizeTemplateImportSource(value) {
13240
13747
  }
13241
13748
  //#endregion
13242
13749
  //#region src/wxml/scan/parser.ts
13750
+ const wxsScriptExtensions = /* @__PURE__ */ new Set(["js", "ts"]);
13243
13751
  const TAG_NAME_LOWER_TO_UPPER_RE = /([a-z0-9])([A-Z])/g;
13244
13752
  const TAG_NAME_MULTI_UPPER_RE = /([A-Z]+)([A-Z][a-z])/g;
13245
13753
  const TAG_NAME_HAS_UPPER_RE = /[A-Z]/;
@@ -13351,7 +13859,7 @@ function parseWxml(options) {
13351
13859
  });
13352
13860
  }
13353
13861
  }
13354
- if (currentTagName && isScriptModuleTagName(currentTagName) && name === "lang" && jsExtensions.includes(value)) removeWxsLangAttrTokens.push({
13862
+ if (currentTagName && isScriptModuleTagName(currentTagName) && name === "lang" && wxsScriptExtensions.has(value)) removeWxsLangAttrTokens.push({
13355
13863
  start: parser.startIndex,
13356
13864
  end: parser.endIndex,
13357
13865
  value
@@ -13399,7 +13907,7 @@ function parseWxml(options) {
13399
13907
  tagStartIndex = 0;
13400
13908
  },
13401
13909
  ontext(data) {
13402
- if (currentTagName && isScriptModuleTagName(currentTagName) && jsExtensions.includes(attrs.lang)) inlineWxsTokens.push({
13910
+ if (currentTagName && isScriptModuleTagName(currentTagName) && wxsScriptExtensions.has(attrs.lang)) inlineWxsTokens.push({
13403
13911
  start: parser.startIndex,
13404
13912
  end: parser.endIndex,
13405
13913
  value: data
@@ -13529,7 +14037,7 @@ function getManagedTypeScriptConfig(ctx) {
13529
14037
  async function readLegacyManagedTsconfigFile(filePath) {
13530
14038
  try {
13531
14039
  const content = await fs$1.readFile(filePath, "utf8");
13532
- const parsed = parse$1(content, void 0, true);
14040
+ const parsed = parse$2(content, void 0, true);
13533
14041
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return;
13534
14042
  return parsed;
13535
14043
  } catch {
@@ -13769,7 +14277,7 @@ async function readTsconfigData(filePath) {
13769
14277
  const content = await fs$1.readFile(filePath, "utf8").catch(() => void 0);
13770
14278
  if (!content) return;
13771
14279
  try {
13772
- const parsed = parse$1(content, void 0, true);
14280
+ const parsed = parse$2(content, void 0, true);
13773
14281
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
13774
14282
  } catch {
13775
14283
  return;
@@ -13854,7 +14362,7 @@ async function syncManagedTsconfigBootstrapFiles(cwd) {
13854
14362
  function parseJsonObject(content) {
13855
14363
  if (!content) return;
13856
14364
  try {
13857
- const parsed = parse$1(content, void 0, true);
14365
+ const parsed = parse$2(content, void 0, true);
13858
14366
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
13859
14367
  } catch {
13860
14368
  return;
@@ -13922,7 +14430,7 @@ async function collectAutoImportTemplateTags(ctx) {
13922
14430
  const source = await readFile(filePath, "utf8").catch(() => void 0);
13923
14431
  if (!source) return;
13924
14432
  if (filePath.endsWith(".vue")) {
13925
- const { descriptor, errors } = parse(source, { filename: filePath });
14433
+ const { descriptor, errors } = parse$1(source, { filename: filePath });
13926
14434
  if (errors.length > 0 || !descriptor.template?.content) return;
13927
14435
  for (const tag of collectVueTemplateAutoImportTags(descriptor.template.content, filePath)) tags.set(tag, removeExtensionDeep(filePath));
13928
14436
  return;
@@ -16516,7 +17024,7 @@ async function inspectTsconfigPathsState(filePath, visited) {
16516
17024
  }
16517
17025
  let parsed;
16518
17026
  try {
16519
- parsed = parse$1(content);
17027
+ parsed = parse$2(content);
16520
17028
  } catch {
16521
17029
  return {
16522
17030
  root: false,
@@ -19790,7 +20298,7 @@ function buildTailwindContentPayload(descriptor, filename) {
19790
20298
  };
19791
20299
  }
19792
20300
  function buildVueSfcSignaturePayloadWithTs(source, filename) {
19793
- const { descriptor, errors } = parse(source, { filename });
20301
+ const { descriptor, errors } = parse$1(source, { filename });
19794
20302
  if (errors.length) return;
19795
20303
  return {
19796
20304
  nonJson: buildNonJsonDescriptorPayload(descriptor, filename),
@@ -20041,7 +20549,7 @@ function stripTypeSyntaxFromAst(ast) {
20041
20549
  });
20042
20550
  }
20043
20551
  function parseExpressionAst(expression) {
20044
- const file = parse$2(`const __wv_layout_expr__ = ${expression}`, BABEL_TS_MODULE_PARSER_OPTIONS);
20552
+ const file = parse$3(`const __wv_layout_expr__ = ${expression}`, BABEL_TS_MODULE_PARSER_OPTIONS$1);
20045
20553
  stripTypeSyntaxFromAst(file);
20046
20554
  const stmt = file.program.body[0];
20047
20555
  if (!stmt || !t.isVariableDeclaration(stmt)) return null;
@@ -20102,7 +20610,7 @@ function injectLayoutBindingComputed(script, props) {
20102
20610
  if (!script || !props) return script;
20103
20611
  const runtimeEntries = Object.entries(props).filter((entry) => typeof entry[1] === "object" && entry[1] !== null && "kind" in entry[1] && entry[1].kind === "expression");
20104
20612
  if (runtimeEntries.length === 0) return script;
20105
- const ast = parse$2(script, BABEL_TS_MODULE_PARSER_OPTIONS);
20613
+ const ast = parse$3(script, BABEL_TS_MODULE_PARSER_OPTIONS$1);
20106
20614
  const optionsObject = findWevuOptionsObject(ast);
20107
20615
  if (!optionsObject) return script;
20108
20616
  const computedEntries = runtimeEntries.map(([key, value]) => {
@@ -20171,7 +20679,7 @@ function injectNativePageLayoutState(pageOptions, currentLayout) {
20171
20679
  }
20172
20680
  function injectNativePageLayoutRuntime(script, filename, plan) {
20173
20681
  if (!script) return script;
20174
- const ast = parse$2(script, BABEL_TS_MODULE_PARSER_OPTIONS);
20682
+ const ast = parse$3(script, BABEL_TS_MODULE_PARSER_OPTIONS$1);
20175
20683
  stripTypeSyntaxFromAst(ast);
20176
20684
  const strippedMeta = stripDefinePageMetaCalls(ast);
20177
20685
  const shouldInjectSetter = Boolean(plan?.dynamicSwitch);
@@ -20354,10 +20862,10 @@ function collectSetPageLayoutPropKeysFromProgram(ast) {
20354
20862
  return [...keys];
20355
20863
  }
20356
20864
  function parseScriptAst(content) {
20357
- return parse$2(content, BABEL_TS_MODULE_PARSER_OPTIONS);
20865
+ return parse$3(content, BABEL_TS_MODULE_PARSER_OPTIONS$1);
20358
20866
  }
20359
20867
  function analyzeVueScriptBlocks(source, filename) {
20360
- const { descriptor } = parse(source, { filename });
20868
+ const { descriptor } = parse$1(source, { filename });
20361
20869
  return {
20362
20870
  descriptor,
20363
20871
  scriptAst: descriptor.script?.content ? parseScriptAst(descriptor.script.content) : void 0,
@@ -20674,7 +21182,7 @@ function hasWevuTemplateRuntimeBindings(template) {
20674
21182
  return typeof template === "string" && WEVU_TEMPLATE_RUNTIME_BINDING_ATTR_RE.test(template);
20675
21183
  }
20676
21184
  function isDefineComponentJsonOnlyScript(content) {
20677
- const ast = parse$2(content, BABEL_TS_MODULE_PARSER_OPTIONS);
21185
+ const ast = parse$3(content, BABEL_TS_MODULE_PARSER_OPTIONS$1);
20678
21186
  let hasDefineComponentJson = false;
20679
21187
  for (const statement of ast.program.body) {
20680
21188
  if (t.isEmptyStatement(statement)) continue;
@@ -20686,7 +21194,7 @@ function isDefineComponentJsonOnlyScript(content) {
20686
21194
  return hasDefineComponentJson;
20687
21195
  }
20688
21196
  function shouldEmitScriptlessVueLayoutJs(source, filename) {
20689
- const { descriptor } = parse(source, { filename });
21197
+ const { descriptor } = parse$1(source, { filename });
20690
21198
  if (hasWevuTemplateRuntimeBindings(descriptor.template?.content)) return false;
20691
21199
  const blocks = [descriptor.script?.content, descriptor.scriptSetup?.content].filter((content) => typeof content === "string" && content.trim().length > 0);
20692
21200
  if (blocks.length === 0) return true;
@@ -21534,7 +22042,10 @@ async function emitEntryOutput(options) {
21534
22042
  continue;
21535
22043
  }
21536
22044
  const normalizedResolvedId = normalizeFsResolvedId(resolvedId.id);
21537
- if (normalizedResolvedId && !isSkippableResolvedId(normalizedResolvedId)) resolvedEntryMap.set(normalizedResolvedId, resolvedId);
22045
+ if (normalizedResolvedId && !isSkippableResolvedId(normalizedResolvedId)) {
22046
+ resolvedEntryMap.set(normalizedResolvedId, resolvedId);
22047
+ if (/\.(?:jsx|tsx)$/.test(normalizedResolvedId)) addNormalizedWatchFile(pluginCtx, normalizedResolvedId);
22048
+ }
21538
22049
  const isForcedEntry = forceEmitEntrySet?.has(entry) === true || forceEmitEntrySet?.has(normalizedResolvedId) === true;
21539
22050
  const isForcedReloadEntry = forceReloadEntrySet?.has(entry) === true || forceReloadEntrySet?.has(normalizedResolvedId) === true;
21540
22051
  const isDirtyEntry = dirtyEntrySet.has(normalizedResolvedId);
@@ -23278,24 +23789,27 @@ function resolveWevuExportAliasMap(wevuChunk) {
23278
23789
  const exportMatch = new RegExp(`\\b([A-Za-z_$][\\w$]*)\\s+as\\s+${exportName}\\b`).exec(code);
23279
23790
  if (exportMatch?.[1]) aliases.set(exportName, exportMatch[1]);
23280
23791
  }
23281
- const propertyExports = Array.from(code.matchAll(/Object\.defineProperty\(exports,\s*["']([^"']+)["'][\s\S]*?return\s+([A-Za-z_$][\w$]*)\s*(?:;\s*)?\}/g));
23792
+ const propertyExports = Array.from(code.matchAll(/Object\.defineProperty\(exports,\s*(["'`])([^"'`]+)\1,\s*\{[^{}]*\bget\s*:\s*function\s*\(\)\s*\{([^{}]*)\}\s*\}\s*\)/g)).flatMap((match) => {
23793
+ const getterReturn = /^return\s+([A-Za-z_$][\w$]*);?$/.exec((match[3] ?? "").trim());
23794
+ return getterReturn?.[1] ? [[match[2], getterReturn[1]]] : [];
23795
+ });
23282
23796
  for (const [exportName] of WEVU_EXPORT_ALIASES) {
23283
23797
  if (aliases.has(exportName)) continue;
23284
- const semanticExport = propertyExports.find((match) => match[1] === exportName);
23285
- if (semanticExport?.[2]) {
23286
- aliases.set(exportName, semanticExport[2]);
23798
+ const semanticExport = propertyExports.find((match) => match[0] === exportName);
23799
+ if (semanticExport?.[1]) {
23800
+ aliases.set(exportName, semanticExport[1]);
23287
23801
  continue;
23288
23802
  }
23289
- const stableExport = propertyExports.find((match) => match[1] === `__wevu${exportName[0].toUpperCase()}${exportName.slice(1)}`);
23290
- if (stableExport?.[2]) {
23291
- aliases.set(exportName, stableExport[2]);
23803
+ const stableExport = propertyExports.find((match) => match[0] === `__wevu${exportName[0].toUpperCase()}${exportName.slice(1)}`);
23804
+ if (stableExport?.[1]) {
23805
+ aliases.set(exportName, stableExport[1]);
23292
23806
  continue;
23293
23807
  }
23294
23808
  }
23295
- if (!aliases.has("defineComponent") && localIdentifiers.has("eo")) aliases.set("defineComponent", "eo");
23296
- if (!aliases.has("createWevuComponent") && localIdentifiers.has("to")) aliases.set("createWevuComponent", "to");
23809
+ if (WEVU_SRC_CHUNK_RE.test(wevuChunk.fileName) && !aliases.has("defineComponent") && localIdentifiers.has("eo")) aliases.set("defineComponent", "eo");
23810
+ if (WEVU_SRC_CHUNK_RE.test(wevuChunk.fileName) && !aliases.has("createWevuComponent") && localIdentifiers.has("to")) aliases.set("createWevuComponent", "to");
23297
23811
  if (!aliases.has("defineComponent")) {
23298
- const createWevuComponentLocal = (propertyExports.find((match) => match[1] === "createWevuComponent") ?? propertyExports.find((match) => match[1] === "__wevuCreateWevuComponent"))?.[2];
23812
+ const createWevuComponentLocal = (propertyExports.find((match) => match[0] === "createWevuComponent") ?? propertyExports.find((match) => match[0] === "__wevuCreateWevuComponent"))?.[1];
23299
23813
  if (createWevuComponentLocal) {
23300
23814
  const functionMatch = new RegExp(`function\\s+${createWevuComponentLocal}\\s*\\([^)]*\\)\\s*\\{[\\s\\S]{0,500}?\\b([A-Za-z_$][\\w$]*)\\s*\\(`).exec(code);
23301
23815
  if (functionMatch?.[1]) aliases.set("defineComponent", functionMatch[1]);
@@ -23356,7 +23870,7 @@ function appendWevuRuntimeExports(chunk, aliases, importedMembers) {
23356
23870
  const localIdentifiers = collectLocalRuntimeIdentifiers(chunk.code);
23357
23871
  for (const [exportName, stableName] of WEVU_EXPORT_ALIASES) {
23358
23872
  const localName = aliases.get(exportName);
23359
- if (!localName || existingExports.has(stableName)) continue;
23873
+ if (!localName || !localIdentifiers.has(localName) || existingExports.has(stableName)) continue;
23360
23874
  lines.push(`Object.defineProperty(exports, ${JSON.stringify(stableName)}, { enumerable: false, get: function() { return ${localName}; } });`);
23361
23875
  existingExports.add(stableName);
23362
23876
  }
@@ -24024,7 +24538,7 @@ function mayContainRequestGlobalsUsageByText(code, allowedTargets) {
24024
24538
  }
24025
24539
  function extractRequestGlobalsUsageSource(code) {
24026
24540
  if (!code.includes("<script")) return code;
24027
- const { descriptor, errors } = parse(code, {
24541
+ const { descriptor, errors } = parse$1(code, {
24028
24542
  filename: "request-globals-usage.vue",
24029
24543
  ignoreEmpty: false
24030
24544
  });
@@ -24175,7 +24689,7 @@ function injectCodeIntoSfcBlock(source, startOffset, injection) {
24175
24689
  */
24176
24690
  function injectRequestGlobalsIntoSfc(source, targets, options) {
24177
24691
  if (targets.length === 0) return source;
24178
- const { descriptor, errors } = parse(source, {
24692
+ const { descriptor, errors } = parse$1(source, {
24179
24693
  filename: "request-globals.vue",
24180
24694
  ignoreEmpty: false
24181
24695
  });
@@ -25299,7 +25813,7 @@ function replaceImportMetaAccess(code, options) {
25299
25813
  }
25300
25814
  function replaceImportMetaAccessInSfc(source, options) {
25301
25815
  if (!source.includes("import.meta")) return source;
25302
- const { descriptor, errors } = parse(source, {
25816
+ const { descriptor, errors } = parse$1(source, {
25303
25817
  filename: "import-meta.vue",
25304
25818
  ignoreEmpty: false
25305
25819
  });
@@ -25591,10 +26105,7 @@ function rewriteBundlePlatformApi(bundle, globalName, options) {
25591
26105
  cache: options?.analysisCache
25592
26106
  });
25593
26107
  if (analysis && !analysis.hasPlatformApiAccess) continue;
25594
- const magicString = createMiniProgramPlatformApiRewrite(chunk.code, globalName, {
25595
- ...options,
25596
- analysis
25597
- });
26108
+ const magicString = createMiniProgramPlatformApiRewrite(chunk.code, globalName);
25598
26109
  if (!magicString) continue;
25599
26110
  applyMagicStringChunkRewrite(chunk, magicString);
25600
26111
  }
@@ -27185,7 +27696,34 @@ function resolveRootEntryBasename(state) {
27185
27696
  }
27186
27697
  //#endregion
27187
27698
  //#region src/plugins/core/lifecycle/load/options.ts
27188
- function collectMainLogicalInputs(state, appEntry) {
27699
+ const LOCAL_IMPORT_RE = /\bimport\s+(?:[\s\S]*?\s+from\s+)?(['"])([^'"\n]+)\1/g;
27700
+ async function collectImportedVueComponents(state, candidates) {
27701
+ const { absoluteSrcRoot } = state.ctx.configService;
27702
+ const importedComponents = /* @__PURE__ */ new Set();
27703
+ for (const candidate of candidates) {
27704
+ if (candidate.type !== "page" || candidate.entry.includes(":")) continue;
27705
+ const pageBase = path.resolve(absoluteSrcRoot, candidate.entry);
27706
+ const pageSource = (await findJsEntry(pageBase)).path ?? await findVueEntry(pageBase);
27707
+ if (!pageSource || !await fs$1.pathExists(pageSource)) continue;
27708
+ let source;
27709
+ try {
27710
+ source = await fs$1.readFile(pageSource, "utf8");
27711
+ } catch {
27712
+ continue;
27713
+ }
27714
+ for (const match of source.matchAll(LOCAL_IMPORT_RE)) {
27715
+ const importSource = match[2];
27716
+ if (!importSource.startsWith(".") && !importSource.startsWith("/")) continue;
27717
+ const importedBase = path.resolve(path.dirname(pageSource), importSource);
27718
+ const importedVue = importedBase.endsWith(".vue") ? importedBase : await findVueEntry(importedBase);
27719
+ if (!importedVue || !await fs$1.pathExists(importedVue)) continue;
27720
+ const relativeEntry = path.relative(absoluteSrcRoot, removeExtensionDeep(importedVue)).replaceAll("\\", "/");
27721
+ if (relativeEntry && !relativeEntry.startsWith("../")) importedComponents.add(relativeEntry);
27722
+ }
27723
+ }
27724
+ return [...importedComponents];
27725
+ }
27726
+ async function collectMainLogicalInputs(state, appEntry) {
27189
27727
  const { absoluteSrcRoot } = state.ctx.configService;
27190
27728
  const appJson = normalizeAppJson(appEntry.json ?? {});
27191
27729
  const inputs = { app: {
@@ -27216,6 +27754,10 @@ function collectMainLogicalInputs(state, appEntry) {
27216
27754
  entry: "app-bar/index",
27217
27755
  type: "component"
27218
27756
  });
27757
+ for (const entry of await collectImportedVueComponents(state, candidates)) candidates.push({
27758
+ entry,
27759
+ type: "component"
27760
+ });
27219
27761
  for (const { entry: rawEntry, type } of candidates) {
27220
27762
  if (!rawEntry || rawEntry.includes(":")) continue;
27221
27763
  const name = removeExtensionDeep(rawEntry).replace(/^[/\\]+/, "");
@@ -27335,7 +27877,7 @@ function createOptionsHook(state) {
27335
27877
  currentSubPackageRoot: previousSubPackageRoot
27336
27878
  };
27337
27879
  state.pendingIndependentBuilds = pendingIndependentBuilds;
27338
- scannedInput = collectMainLogicalInputs(state, appEntry);
27880
+ scannedInput = await collectMainLogicalInputs(state, appEntry);
27339
27881
  }
27340
27882
  }
27341
27883
  const logicalInput = {};
@@ -27589,6 +28131,7 @@ async function collectLogicalEntryDependencies(state, ownerId) {
27589
28131
  dependencies.push(...await collectUsingComponentDependencies(state, ownerId, entry?.json));
27590
28132
  for (const kind of [
27591
28133
  "json",
28134
+ "jsx",
27592
28135
  "layout",
27593
28136
  "script",
27594
28137
  "style",
@@ -28004,7 +28547,8 @@ async function processChangedFile(state, id, event) {
28004
28547
  const dirtyReasonStats = /* @__PURE__ */ new Map();
28005
28548
  const markEntryDirtyWithCause = (entryId, reason, cause) => {
28006
28549
  state.markEntryDirty(entryId, reason);
28007
- if (entryId.endsWith(".vue") && reason !== "dependency") {
28550
+ const isJsxTemplateDependency = reason === "dependency" && /\.(?:jsx|tsx)$/.test(normalizedId);
28551
+ if (/\.(?:vue|jsx|tsx)$/.test(entryId) && (reason !== "dependency" || isJsxTemplateDependency)) {
28008
28552
  const hmr = ctx.runtimeState.build.hmr;
28009
28553
  hmr.dirtyVueEntryIds ??= /* @__PURE__ */ new Set();
28010
28554
  hmr.dirtyVueEntryIds.add(entryId);
@@ -28015,6 +28559,7 @@ async function processChangedFile(state, id, event) {
28015
28559
  const isDeletedMissingSelf = event === "delete" && !await fs$1.pathExists(normalizedId);
28016
28560
  const isAutoRouteFile = Boolean(ctx.autoRoutesService?.isRouteFile(normalizedId));
28017
28561
  const pathKind = resolveWatchPathKind(normalizedId);
28562
+ const isReactStaticTemplateUpdate = event === "update" && isReactStaticTemplateSource(configService.weappViteConfig?.react, normalizedId);
28018
28563
  const isScriptModuleSidecar = pathKind.isScriptModuleSidecar;
28019
28564
  const concreteChangedEntryId = isAppVueFile(normalizedId) && scanService.appEntry?.path ? normalizeFsResolvedId(scanService.appEntry.path) : normalizedId;
28020
28565
  const vueEntryUpdateInspector = normalizedId.endsWith(".vue") ? createVueEntryUpdateInspector(state, normalizedId) : void 0;
@@ -28142,8 +28687,9 @@ async function processChangedFile(state, id, event) {
28142
28687
  const isAutoRoutesStaleAppEntry = isJsonOnlyVueEntryUpdate && isAppEntryAutoRoutesSignatureStale(state, normalizedId);
28143
28688
  const isLocalAssetOnlyVueEntryUpdate = !isJsonOnlyVueEntryUpdate && !isAppShellTopologyChanged && event === "update" && (vueEntryUpdateInspector ? await vueEntryUpdateInspector.isLocalAssetOnlyUpdate() : false);
28144
28689
  const isStyleOnlyVueEntryUpdate = isLocalAssetOnlyVueEntryUpdate && (vueEntryUpdateInspector ? await vueEntryUpdateInspector.isStyleOnlyUpdate() : false);
28145
- markChangedEntryDirty(sidecarDirtyCause ? "metadata" : isJsonOnlyVueEntryUpdate && !isAutoRoutesStaleAppEntry || isLocalAssetOnlyVueEntryUpdate ? "metadata" : "direct", sidecarDirtyCause ?? (isJsonOnlyVueEntryUpdate ? isAutoRoutesStaleAppEntry ? "entry-auto-routes" : "entry-json-only" : isAppShellTopologyChanged ? "entry-direct" : isLocalAssetOnlyVueEntryUpdate ? isStyleOnlyVueEntryUpdate ? "entry-style-only" : "entry-local-asset" : "entry-direct"));
28146
- } else if (!handledSidecarMetadataUpdate && importerGraphAffectedEntryIds.size) for (const entryId of importerGraphAffectedEntryIds) markEntryDirtyWithCause(entryId, "dependency", "importer-graph");
28690
+ markChangedEntryDirty(sidecarDirtyCause ? "metadata" : isJsonOnlyVueEntryUpdate && !isAutoRoutesStaleAppEntry || isLocalAssetOnlyVueEntryUpdate ? "metadata" : "direct", sidecarDirtyCause ?? (isReactStaticTemplateUpdate ? "react-template" : isJsonOnlyVueEntryUpdate ? isAutoRoutesStaleAppEntry ? "entry-auto-routes" : "entry-json-only" : isAppShellTopologyChanged ? "entry-direct" : isLocalAssetOnlyVueEntryUpdate ? isStyleOnlyVueEntryUpdate ? "entry-style-only" : "entry-local-asset" : "entry-direct"));
28691
+ } else if (!handledSidecarMetadataUpdate && importerGraphAffectedEntryIds.size) for (const entryId of importerGraphAffectedEntryIds) markEntryDirtyWithCause(entryId, "dependency", isReactStaticTemplateUpdate ? "react-template" : "importer-graph");
28692
+ else if (!handledSidecarMetadataUpdate && event === "update" && /\.(?:vue|jsx|tsx)$/.test(normalizedId) && resolvedEntryMap.has(normalizedId)) markChangedEntryDirty("direct", "entry-direct");
28147
28693
  await markAppEntryForTailwindContent();
28148
28694
  const relativeCwd = configService.relativeCwd(normalizedId);
28149
28695
  let handledByIndependentWatcher = false;
@@ -28636,7 +29182,7 @@ let wevuInstallState = "unknown";
28636
29182
  function isExplicitFileRequest$1(id) {
28637
29183
  return id.startsWith(".") || id.startsWith("/") || WINDOWS_ABSOLUTE_PATH_RE$1.test(id);
28638
29184
  }
28639
- function hasWevuDependency(ctx) {
29185
+ function hasWevuDependency$1(ctx) {
28640
29186
  const packageJson = ctx.configService?.packageJson;
28641
29187
  if (!packageJson) return false;
28642
29188
  return Boolean(packageJson.dependencies?.wevu || packageJson.devDependencies?.wevu);
@@ -28645,7 +29191,7 @@ function ensureWevuInstalled(ctx) {
28645
29191
  if (wevuInstallState === "present") return;
28646
29192
  if (wevuInstallState === "missing") return;
28647
29193
  if (warnedMissingWevu) return;
28648
- if (hasWevuDependency(ctx)) {
29194
+ if (hasWevuDependency$1(ctx)) {
28649
29195
  wevuInstallState = "present";
28650
29196
  return;
28651
29197
  }
@@ -28660,7 +29206,7 @@ function ensureWevuInstalled(ctx) {
28660
29206
  logger_default.warn("[vue] 检测到项目中有 .vue 文件,但未安装 wevu,请安装 wevu 后重试。");
28661
29207
  }
28662
29208
  }
28663
- function createVueResolverPlugin(ctx) {
29209
+ function createVueResolverPlugin(ctx, options = {}) {
28664
29210
  const isWeappVueStyleVirtualId = (id) => {
28665
29211
  return id.startsWith("\0weapp-vite:vue-style:") || id.startsWith(LEGACY_WEAPP_VUE_STYLE_VIRTUAL_PREFIX);
28666
29212
  };
@@ -28679,6 +29225,7 @@ function createVueResolverPlugin(ctx) {
28679
29225
  return query ? `${absoluteId}?${query}` : absoluteId;
28680
29226
  }
28681
29227
  if (isVueLikeFile(id)) {
29228
+ if (options.react && /\.(?:jsx|tsx)(?:\?.*)?$/.test(id)) return null;
28682
29229
  ensureWevuInstalled(ctx);
28683
29230
  if (!isExplicitFileRequest$1(id)) return null;
28684
29231
  const absoluteId = toAbsoluteId(id, configService, importer, { base: "srcRoot" });
@@ -29912,6 +30459,9 @@ async function finalizeTransformCompiledResult(options) {
29912
30459
  if (isApp) setAppShell?.(hasAppShellTemplate(result) ? resolveAppShellLayout(configService) : void 0);
29913
30460
  if (!isApp) registerVueTemplateToken(ctx, filename, result.template);
29914
30461
  if (Array.isArray(result.meta?.sfcSrcDeps)) ctx.moduleGraphService.replaceEntryDependencies(filename, "style", result.meta.sfcSrcDeps);
30462
+ const jsxDependencies = result.meta?.jsxDependencies ?? [];
30463
+ addNormalizedWatchFiles(pluginCtx, jsxDependencies);
30464
+ ctx.moduleGraphService.replaceEntryDependencies(filename, "jsx", jsxDependencies);
29915
30465
  await finalizeTransformEntryScript({
29916
30466
  result: transformResult,
29917
30467
  filename,
@@ -30861,6 +31411,9 @@ async function finalizeVueTransform(options) {
30861
31411
  }
30862
31412
  const sfcStyleDependencies = syncVueSfcStyleDependencies(ctx, filename, currentStyleBlocks);
30863
31413
  ctx.moduleGraphService.replaceEntryDependencies(filename, "style", sfcStyleDependencies);
31414
+ const jsxDependencies = result.meta?.jsxDependencies ?? [];
31415
+ addNormalizedWatchFiles(pluginCtx, jsxDependencies);
31416
+ ctx.moduleGraphService.replaceEntryDependencies(filename, "jsx", jsxDependencies);
30864
31417
  registerScopedSlotHostGenerics(ctx, result.scopedSlotComponents, parseUsingComponents(result.config));
30865
31418
  await measureVueHmrStage("finalizeCompiledResult", "vueFinalizeCompiledMs", async () => {
30866
31419
  await finalizeTransformCompiledResult({
@@ -30909,9 +31462,9 @@ async function tryRefreshJsonOnlyVueCompilation(options) {
30909
31462
  //#endregion
30910
31463
  //#region src/plugins/vue/transform/plugin/transformFile/reuse.ts
30911
31464
  async function tryReuseVueCompilation(options) {
30912
- const { ctx, pluginCtx, filename, source, cachedCompilation, previousStyleSignature, autoRoutesSignature, dirtyEntryId, dirtyVueEntryIds, isCssImporterDirty, canAttemptStyleOnlyReuse, sourceMap, isApp, styleBlocksCache, styleRefreshTokens, readAndParseSfc, createReadAndParseSfcOptions, measureStage, measureVueHmrStage, reportTiming } = options;
31465
+ const { ctx, pluginCtx, filename, source, cachedCompilation, previousStyleSignature, autoRoutesSignature, dirtyEntryId, dirtyVueEntryIds, isCssImporterDirty, canAttemptStyleOnlyReuse, isJsxTemplateDependencyDirty, sourceMap, isApp, styleBlocksCache, styleRefreshTokens, readAndParseSfc, createReadAndParseSfcOptions, measureStage, measureVueHmrStage, reportTiming } = options;
30913
31466
  const configService = ctx.configService;
30914
- if (configService.isDev && cachedCompilation && !ctx.runtimeState.scan.isDirty && cachedCompilation.source === source && cachedCompilation.autoRoutesSignature === autoRoutesSignature) {
31467
+ if (configService.isDev && cachedCompilation && !isJsxTemplateDependencyDirty && (filename.endsWith(".vue") || (cachedCompilation.refreshToken ?? 0) === 0) && !ctx.runtimeState.scan.isDirty && cachedCompilation.source === source && cachedCompilation.autoRoutesSignature === autoRoutesSignature) {
30915
31468
  cachedCompilation.refreshToken = 0;
30916
31469
  const cachedResult = normalizeVueTransformResult(cachedCompilation.result);
30917
31470
  let cachedStyleBlocks = cachedResult.meta?.styleBlocks ?? styleBlocksCache.get(filename);
@@ -31053,6 +31606,7 @@ async function transformVueLikeFile(options) {
31053
31606
  }
31054
31607
  const dirtyVueEntryIds = ctx.runtimeState?.build?.hmr?.dirtyVueEntryIds;
31055
31608
  const dirtyEntryId = resolveDirtyVueEntryId(dirtyVueEntryIds, filename);
31609
+ const isJsxTemplateDependencyDirty = Boolean(dirtyEntryId && /\.(?:jsx|tsx)$/.test(ctx.runtimeState?.build?.hmr?.profile?.file ?? ""));
31056
31610
  const isCssImporterDirty = isVueCssImporterDirtyReasonSummary(ctx.runtimeState?.build?.hmr?.profile?.dirtyReasonSummary);
31057
31611
  const canAttemptStyleOnlyReuse = isVueStyleOnlyDirtyReasonSummary(ctx.runtimeState?.build?.hmr?.profile?.dirtyReasonSummary);
31058
31612
  const reuseResult = await tryReuseVueCompilation({
@@ -31067,6 +31621,7 @@ async function transformVueLikeFile(options) {
31067
31621
  dirtyVueEntryIds,
31068
31622
  isCssImporterDirty,
31069
31623
  canAttemptStyleOnlyReuse,
31624
+ isJsxTemplateDependencyDirty,
31070
31625
  sourceMap,
31071
31626
  isApp,
31072
31627
  styleBlocksCache,
@@ -31197,7 +31752,7 @@ function invalidateComponentMetaCache(componentMetaCache, id) {
31197
31752
  componentMetaCache.delete(id);
31198
31753
  componentMetaCache.delete(normalizeFsResolvedId(id));
31199
31754
  }
31200
- function createVueTransformPlugin(ctx) {
31755
+ function createVueTransformPlugin(ctx, options = {}) {
31201
31756
  const compilationCache = /* @__PURE__ */ new Map();
31202
31757
  let appShell;
31203
31758
  let pageMatcher = null;
@@ -31259,6 +31814,7 @@ function createVueTransformPlugin(ctx) {
31259
31814
  });
31260
31815
  },
31261
31816
  async transform(code, id) {
31817
+ if (options.react && /\.(?:jsx|tsx)(?:\?.*)?$/.test(id)) return null;
31262
31818
  if (parseSidecarSourceRequest(id) || !VUE_TRANSFORM_FILTER_RE.test(id) || !isVueLikeId(id)) return null;
31263
31819
  const startedAt = performance.now();
31264
31820
  try {
@@ -31376,8 +31932,8 @@ const VUE_PLUGIN_NAME = "weapp-vite:vue";
31376
31932
  function vuePlugin(ctx, options) {
31377
31933
  if (options?.enable === false) return [];
31378
31934
  return [
31379
- createVueResolverPlugin(ctx),
31380
- createVueTransformPlugin(ctx),
31935
+ createVueResolverPlugin(ctx, options),
31936
+ createVueTransformPlugin(ctx, options),
31381
31937
  createVueWatchPlugin(ctx)
31382
31938
  ];
31383
31939
  }
@@ -31576,17 +32132,26 @@ function flatten(groups) {
31576
32132
  return acc;
31577
32133
  }, []);
31578
32134
  }
32135
+ function hasWevuDependency(ctx) {
32136
+ const packageJson = ctx.configService?.packageJson;
32137
+ return Boolean(packageJson?.dependencies?.wevu || packageJson?.devDependencies?.wevu);
32138
+ }
31579
32139
  function vitePluginWeapp(ctx, subPackageMeta) {
31580
32140
  const libModeEnabled = ctx.configService?.weappLibConfig?.enabled;
31581
32141
  const vueEnabled = ctx.configService?.weappViteConfig?.vue?.enable !== false;
31582
- const runtimeProvider = resolveRuntimeProvider("miniprogram", vueEnabled ? "vue" : "native");
32142
+ const reactEnabled = isReactEnabled(ctx);
32143
+ const runtimeProvider = resolveRuntimeProvider("miniprogram", vueEnabled && (!reactEnabled || hasWevuDependency(ctx)) ? "vue" : "native");
31583
32144
  const groups = [
31584
32145
  [createContextPlugin(ctx), createSelectedRuntimeProviderPlugin(runtimeProvider, ctx.configService.isDev)],
31585
32146
  preflight(ctx),
31586
32147
  uniAppCompatibility(ctx),
31587
- vue(ctx, { enable: vueEnabled })
32148
+ createReactPlugin(ctx),
32149
+ vue(ctx, {
32150
+ enable: vueEnabled,
32151
+ react: reactEnabled
32152
+ })
31588
32153
  ];
31589
- if (vueEnabled && !libModeEnabled) groups.push(wevu(ctx));
32154
+ if (vueEnabled && !libModeEnabled && !reactEnabled) groups.push(wevu(ctx));
31590
32155
  const autoRoutesEnabled = resolveWeappAutoRoutesConfig(ctx.configService?.weappViteConfig?.autoRoutes).enabled;
31591
32156
  if (!subPackageMeta) {
31592
32157
  groups.push(asset(ctx));
@@ -31664,7 +32229,7 @@ function createAbsolutePathPattern(value) {
31664
32229
  function hasTsconfigReference(tsconfig, target) {
31665
32230
  if (!existsSync(tsconfig)) return false;
31666
32231
  try {
31667
- const parsed = parse$1(readFileSync(tsconfig, "utf8"), void 0, true);
32232
+ const parsed = parse$2(readFileSync(tsconfig, "utf8"), void 0, true);
31668
32233
  const references = Array.isArray(parsed.references) ? parsed.references : [];
31669
32234
  const tsconfigDir = path.dirname(tsconfig);
31670
32235
  return references.some((reference) => {
@@ -32612,7 +33177,7 @@ async function loadAppEntry(ctx, scanState) {
32612
33177
  const { path: appEntryPath } = appEntry;
32613
33178
  let configFromVue;
32614
33179
  if (!appConfigFile && vueAppPath) {
32615
- const { extractConfigFromVue } = await import("./file-CV6ZWiTX.mjs");
33180
+ const { extractConfigFromVue } = await import("./file-CQTcjEWz.mjs");
32616
33181
  configFromVue = await extractConfigFromVue(vueAppPath);
32617
33182
  if (configFromVue) appConfigFile = vueAppPath;
32618
33183
  }