weapp-vite 6.18.1 → 6.18.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
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-Dva0fkcv.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-BFzjMcYM.mjs";
4
4
  import { createRequire, isBuiltin } from "node:module";
5
5
  import path, { posix } from "pathe";
6
6
  import path$1, { normalize, relative, win32 } from "node:path";
@@ -14,12 +14,12 @@ import fs$1, { existsSync, readFileSync } from "node:fs";
14
14
  import { compileScript, parse } from "vue/compiler-sfc";
15
15
  import { BABEL_TS_MODULE_PARSER_OPTIONS, generate, getVisitorKeys, parse as parse$2, parseJsLike, traverse } from "@weapp-vite/ast/babel";
16
16
  import pm from "picomatch";
17
- import { VUE_COMPONENT_TAG_RE, WE_VU_INTERNAL_REACTIVITY_MODULE_ID, WE_VU_INTERNAL_RUNTIME_MODULE_ID, WE_VU_INTERNAL_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, pathExists, readAndParseSfc, readFile as readFile$1, resolveClassStyleWxsLocation, stripJsonMacroCallsFromCode } from "wevu/compiler";
17
+ import { VUE_COMPONENT_TAG_RE, WE_VU_INTERNAL_REACTIVITY_MODULE_ID, WE_VU_INTERNAL_RUNTIME_MODULE_ID, WE_VU_INTERNAL_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, pathExists, readAndParseSfc, readFile as readFile$1, refreshVueFileJsonConfig, resolveClassStyleWxsLocation, stripJsonMacroCallsFromCode } from "wevu/compiler";
18
18
  import process from "node:process";
19
19
  import { parse as parse$1, stringify } from "comment-json";
20
20
  import fs$2, { appendFile, copyFile, mkdir, readFile, readdir, rm } from "node:fs/promises";
21
21
  import { build, createLogger, createServer, loadConfigFromFile, preprocessCSS, transformWithOxc } from "vite";
22
- import { createHash } from "node:crypto";
22
+ import { createHash, randomBytes } from "node:crypto";
23
23
  import { fileURLToPath } from "node:url";
24
24
  import semverGte from "semver/functions/gte.js";
25
25
  import semverSatisfies from "semver/functions/satisfies.js";
@@ -33,7 +33,7 @@ import os from "node:os";
33
33
  import { getPackageInfo, getPackageInfoSync, resolveModule } from "local-pkg";
34
34
  import { spawn } from "node:child_process";
35
35
  import PQueue from "p-queue";
36
- 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_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_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_IMPORT_META_ENV_KEY, WEAPP_VITE_INJECTED_API_IDENTIFIER, 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";
36
+ 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_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_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_IMPORT_META_ENV_KEY, WEAPP_VITE_INJECTED_API_IDENTIFIER, 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";
37
37
  import { Buffer } from "node:buffer";
38
38
  import MagicString from "magic-string";
39
39
  import babelPresetEnv from "@babel/preset-env";
@@ -8081,6 +8081,7 @@ function getWeappViteConfig() {
8081
8081
  alipayNpmMode: "node_modules"
8082
8082
  },
8083
8083
  hmr: {
8084
+ runtime: "classic",
8084
8085
  sharedChunks: "auto",
8085
8086
  touchAppWxss: "auto",
8086
8087
  logLevel: "default",
@@ -8355,6 +8356,66 @@ function createRuntimeState() {
8355
8356
  };
8356
8357
  }
8357
8358
  //#endregion
8359
+ //#region src/runtime/resetRuntimeState.ts
8360
+ function resetRuntimeStateForFreshBuild(runtimeState) {
8361
+ const fresh = createRuntimeState();
8362
+ const autoRoutes = runtimeState.autoRoutes;
8363
+ autoRoutes.routes = fresh.autoRoutes.routes;
8364
+ autoRoutes.serialized = fresh.autoRoutes.serialized;
8365
+ autoRoutes.moduleCode = fresh.autoRoutes.moduleCode;
8366
+ autoRoutes.typedDefinition = fresh.autoRoutes.typedDefinition;
8367
+ autoRoutes.watchFiles.clear();
8368
+ autoRoutes.watchDirs.clear();
8369
+ autoRoutes.dirty = fresh.autoRoutes.dirty;
8370
+ autoRoutes.initialized = fresh.autoRoutes.initialized;
8371
+ autoRoutes.candidates.clear();
8372
+ autoRoutes.needsFullRescan = fresh.autoRoutes.needsFullRescan;
8373
+ autoRoutes.loadingAppConfig = fresh.autoRoutes.loadingAppConfig;
8374
+ const autoImport = runtimeState.autoImport;
8375
+ autoImport.registry.clear();
8376
+ autoImport.resolvedResolverComponents.clear();
8377
+ autoImport.matcher = void 0;
8378
+ autoImport.matcherKey = fresh.autoImport.matcherKey;
8379
+ autoImport.version += 1;
8380
+ autoImport.pendingEntriesByImporter.clear();
8381
+ runtimeState.build.hmr = fresh.build.hmr;
8382
+ const json = runtimeState.json;
8383
+ json.cache.cache.clear();
8384
+ json.cache.mtimeMap.clear();
8385
+ json.cache.signatureMap.clear();
8386
+ json.emittedSource.clear();
8387
+ const asset = runtimeState.asset;
8388
+ asset.emittedBuffer.clear();
8389
+ asset.scopedSlotGenerics.clear();
8390
+ const css = runtimeState.css;
8391
+ css.importerToDependencies.clear();
8392
+ css.dependencyToImporters.clear();
8393
+ css.emittedSource.clear();
8394
+ const wxml = runtimeState.wxml;
8395
+ wxml.depsMap.clear();
8396
+ wxml.importerMap.clear();
8397
+ wxml.tokenMap.clear();
8398
+ wxml.componentsMap.clear();
8399
+ wxml.aggregatedComponentsMap.clear();
8400
+ wxml.templatePathMap.clear();
8401
+ wxml.cache.cache.clear();
8402
+ wxml.cache.mtimeMap.clear();
8403
+ wxml.cache.signatureMap.clear();
8404
+ wxml.emittedCode.clear();
8405
+ const scan = runtimeState.scan;
8406
+ scan.subPackageMap.clear();
8407
+ scan.independentSubPackageMap.clear();
8408
+ scan.warnedMessages.clear();
8409
+ scan.appEntry = void 0;
8410
+ scan.pluginJson = void 0;
8411
+ scan.pluginJsonPath = void 0;
8412
+ scan.isDirty = fresh.scan.isDirty;
8413
+ scan.independentDirtyRoots.clear();
8414
+ const lib = runtimeState.lib;
8415
+ lib.enabled = fresh.lib.enabled;
8416
+ lib.entries.clear();
8417
+ }
8418
+ //#endregion
8358
8419
  //#region src/plugins/core/lifecycle/emit/constants.ts
8359
8420
  const PRETTY_NODE_MODULES_RE = /node_modules\/(?:\.pnpm\/[^/]+\/node_modules\/)?(.+)/;
8360
8421
  const REQUEST_GLOBAL_EXPORT_RE = /Object\.defineProperty\(exports,\s*(?:`([^`]+)`|'([^']+)'|"([^"]+)"),\s*\{[\s\S]*?get:function\(\)\{return ([A-Za-z_$][\w$]*)\}\}\)/g;
@@ -9820,6 +9881,1092 @@ function createSharedBuildConfig(configService, scanService) {
9820
9881
  return { build: { rolldownOptions: { output: createSharedBuildOutput(configService, () => scanService.subPackageMap.keys()) } } };
9821
9882
  }
9822
9883
  //#endregion
9884
+ //#region src/runtime/statefulHmr/outputWriter.ts
9885
+ /**
9886
+ * @description 通过独立的 Vite write 阶段持久化 DevEngine 已生成的文件,不重新解析业务源码。
9887
+ */
9888
+ async function writeStatefulHmrOutput(outDir, output) {
9889
+ const virtualEntry = "\0weapp-vite-stateful-hmr-output";
9890
+ await build({
9891
+ configFile: false,
9892
+ logLevel: "silent",
9893
+ build: {
9894
+ emptyOutDir: false,
9895
+ minify: false,
9896
+ outDir,
9897
+ rolldownOptions: { input: virtualEntry },
9898
+ write: true
9899
+ },
9900
+ plugins: [{
9901
+ name: "weapp-vite:stateful-hmr-output-writer",
9902
+ resolveId(id) {
9903
+ return id === virtualEntry ? virtualEntry : void 0;
9904
+ },
9905
+ load(id) {
9906
+ return id === virtualEntry ? "export {}" : void 0;
9907
+ },
9908
+ buildStart() {
9909
+ for (const item of output) this.emitFile({
9910
+ type: "asset",
9911
+ fileName: item.fileName.replaceAll("\\", "/"),
9912
+ source: item.type === "chunk" ? item.code : item.source
9913
+ });
9914
+ },
9915
+ generateBundle(_options, bundle) {
9916
+ for (const [fileName, item] of Object.entries(bundle)) if (item.type === "chunk" && item.facadeModuleId === virtualEntry) delete bundle[fileName];
9917
+ }
9918
+ }],
9919
+ root: path$1.dirname(outDir)
9920
+ });
9921
+ }
9922
+ //#endregion
9923
+ //#region src/runtime/statefulHmr/runtimeSource.ts
9924
+ const statefulHmrRolldownRuntimeSource = `
9925
+ var BaseDevRuntime = DevRuntime;
9926
+ class WeappViteHotContext {
9927
+ callbacks = [];
9928
+ data = {};
9929
+ _internal = { updateStyle() {}, removeStyle() {} };
9930
+ constructor(moduleId) { this.moduleId = moduleId; }
9931
+ accept(...args) {
9932
+ if (args.length === 0) this.callbacks.push({ deps: this.moduleId, callback: undefined });
9933
+ else if (args.length === 1 && typeof args[0] === 'function') this.callbacks.push({ deps: this.moduleId, callback: args[0] });
9934
+ else if (args.length === 1) this.callbacks.push({ deps: args[0], callback: undefined });
9935
+ else this.callbacks.push({ deps: args[0], callback: args[1] });
9936
+ }
9937
+ acceptExports(_exports, callback) { this.accept(callback); }
9938
+ dispose() {}
9939
+ prune() {}
9940
+ invalidate() {}
9941
+ on() {}
9942
+ off() {}
9943
+ send() {}
9944
+ }
9945
+ class WeappViteDevRuntime extends BaseDevRuntime {
9946
+ contexts = new Map();
9947
+ patchedModules = new Set();
9948
+ applyingPatch = false;
9949
+ currentModuleId = '';
9950
+ registrationModuleId = '';
9951
+ createEsmInitializer = (id, initialize, _deduplicate, result) => () => {
9952
+ if (!initialize) return result;
9953
+ if (!this.applyingPatch && this.patchedModules.has(id)) return result;
9954
+ const callback = initialize;
9955
+ initialize = undefined;
9956
+ const previousId = this.currentModuleId;
9957
+ this.currentModuleId = id;
9958
+ try { result = callback(id); }
9959
+ finally { this.currentModuleId = previousId; }
9960
+ if (this.applyingPatch) this.patchedModules.add(id);
9961
+ return result;
9962
+ };
9963
+ createCjsInitializer = (id, initialize, _deduplicate, module) => () => {
9964
+ if (module) return module.exports;
9965
+ if (!this.applyingPatch && this.patchedModules.has(id)) return this.loadExports(id);
9966
+ module = { exports: {} };
9967
+ const previousId = this.currentModuleId;
9968
+ this.currentModuleId = id;
9969
+ try { initialize(module.exports, module, id); }
9970
+ finally { this.currentModuleId = previousId; }
9971
+ if (this.applyingPatch) this.patchedModules.add(id);
9972
+ return module.exports;
9973
+ };
9974
+ createModuleHotContext(moduleId) {
9975
+ const previous = this.contexts.get(moduleId);
9976
+ const context = new WeappViteHotContext(moduleId);
9977
+ if (previous) {
9978
+ context.callbacks = previous.callbacks;
9979
+ context.data = previous.data;
9980
+ }
9981
+ this.contexts.set(moduleId, context);
9982
+ return context;
9983
+ }
9984
+ registerModule(id, exportsHolder) {
9985
+ this.registrationModuleId = id;
9986
+ return super.registerModule(id, exportsHolder);
9987
+ }
9988
+ beginPatch() { this.applyingPatch = true; }
9989
+ endPatch() { this.applyingPatch = false; }
9990
+ applyUpdates(boundaries) {
9991
+ for (const [boundary, acceptedVia] of boundaries) {
9992
+ const context = this.contexts.get(boundary);
9993
+ if (!context) continue;
9994
+ const callbacks = [...context.callbacks];
9995
+ if (boundary === acceptedVia) context.callbacks = [];
9996
+ for (const { deps, callback } of callbacks) {
9997
+ if (!callback) continue;
9998
+ if (Array.isArray(deps)) {
9999
+ if (deps.includes(acceptedVia)) callback(deps.map((id) => this.loadExports(id)));
10000
+ } else if (deps === acceptedVia) callback(this.loadExports(acceptedVia));
10001
+ }
10002
+ }
10003
+ }
10004
+ }
10005
+ const runtime = new WeappViteDevRuntime(undefined, 'weapp-vite-stateful');
10006
+ globalThis.__rolldown_runtime__ = runtime;
10007
+ const bridgeKey = ${JSON.stringify(WEAPP_VITE_STATEFUL_HMR_BRIDGE_KEY)};
10008
+ const definitions = new Map();
10009
+ const registered = new Set();
10010
+ const instances = new Map();
10011
+ const pendingNativeDefinitions = new Map();
10012
+ const wevuRefreshes = new Map();
10013
+ const wevuRefreshGenerations = new Map();
10014
+ const wevuInstanceGenerations = new WeakMap();
10015
+ let suppressLifecycles = false;
10016
+ const nativeRegistrations = {};
10017
+ function getInstances(moduleId) {
10018
+ let values = instances.get(moduleId);
10019
+ if (!values) instances.set(moduleId, values = new Set());
10020
+ return values;
10021
+ }
10022
+ function refreshWevuInstance(instance, moduleId) {
10023
+ if (!instance || (typeof instance !== 'object' && typeof instance !== 'function')) return;
10024
+ const generation = wevuRefreshGenerations.get(moduleId) || 0;
10025
+ if (generation === 0) return;
10026
+ let generations = wevuInstanceGenerations.get(instance);
10027
+ if (generations?.get(moduleId) === generation) return;
10028
+ const refresh = wevuRefreshes.get(moduleId);
10029
+ if (typeof refresh !== 'function') return;
10030
+ refresh(instance);
10031
+ if (!generations) wevuInstanceGenerations.set(instance, generations = new Map());
10032
+ generations.set(moduleId, generation);
10033
+ }
10034
+ function proxyFunction(moduleId, path, fallback) {
10035
+ return function (...args) {
10036
+ if (suppressLifecycles && /(?:created|attached|ready|detached|onLoad|onShow|onHide|onUnload)$/.test(path)) return;
10037
+ const definition = definitions.get(moduleId);
10038
+ const segments = path.split('.');
10039
+ let value = definition;
10040
+ for (const segment of segments) value = value && value[segment];
10041
+ return (typeof value === 'function' ? value : fallback)?.apply(this, args);
10042
+ };
10043
+ }
10044
+ function decorateObject(value, moduleId, prefix = '') {
10045
+ if (!value || typeof value !== 'object' || Array.isArray(value)) return value;
10046
+ const result = { ...value };
10047
+ for (const [key, child] of Object.entries(value)) {
10048
+ const path = prefix ? prefix + '.' + key : key;
10049
+ if (typeof child === 'function') result[key] = proxyFunction(moduleId, path, child);
10050
+ else if (child && typeof child === 'object' && ['lifetimes', 'methods', 'pageLifetimes'].includes(key)) {
10051
+ result[key] = decorateObject(child, moduleId, path);
10052
+ }
10053
+ }
10054
+ if (!prefix && typeof value.onLoad === 'function') {
10055
+ const onLoad = result.onLoad;
10056
+ result.onLoad = function (...args) {
10057
+ getInstances(moduleId).add(this);
10058
+ return onLoad.apply(this, args);
10059
+ };
10060
+ }
10061
+ if (!prefix && result.lifetimes && typeof result.lifetimes === 'object') {
10062
+ const attached = result.lifetimes.attached;
10063
+ const detached = result.lifetimes.detached;
10064
+ result.lifetimes = { ...result.lifetimes };
10065
+ if (typeof attached === 'function') {
10066
+ result.lifetimes.attached = function (...args) {
10067
+ getInstances(moduleId).add(this);
10068
+ return attached.apply(this, args);
10069
+ };
10070
+ }
10071
+ if (typeof detached === 'function') {
10072
+ result.lifetimes.detached = function (...args) {
10073
+ getInstances(moduleId).delete(this);
10074
+ return detached.apply(this, args);
10075
+ };
10076
+ }
10077
+ }
10078
+ return result;
10079
+ }
10080
+ function decorateWevuComponent(definition, moduleId) {
10081
+ const result = { ...definition };
10082
+ const methods = { ...(definition.methods || {}) };
10083
+ for (const [name, method] of Object.entries(methods)) {
10084
+ if (typeof method !== 'function') continue;
10085
+ methods[name] = function (...args) {
10086
+ getInstances(moduleId).add(this);
10087
+ refreshWevuInstance(this, moduleId);
10088
+ return method.apply(this, args);
10089
+ };
10090
+ }
10091
+ result.methods = methods;
10092
+ const onLoad = definition.onLoad;
10093
+ const onUnload = definition.onUnload;
10094
+ if (typeof onLoad === 'function') {
10095
+ result.onLoad = function (...args) {
10096
+ getInstances(moduleId).add(this);
10097
+ return onLoad.apply(this, args);
10098
+ };
10099
+ }
10100
+ if (typeof onUnload === 'function') {
10101
+ result.onUnload = function (...args) {
10102
+ getInstances(moduleId).delete(this);
10103
+ return onUnload.apply(this, args);
10104
+ };
10105
+ }
10106
+ const lifetimes = { ...(definition.lifetimes || {}) };
10107
+ const attached = lifetimes.attached;
10108
+ const detached = lifetimes.detached;
10109
+ lifetimes.attached = function (...args) {
10110
+ getInstances(moduleId).add(this);
10111
+ return attached?.apply(this, args);
10112
+ };
10113
+ lifetimes.detached = function (...args) {
10114
+ getInstances(moduleId).delete(this);
10115
+ return detached?.apply(this, args);
10116
+ };
10117
+ return { ...result, lifetimes };
10118
+ }
10119
+ function registerDefinition(name, definition, nativeRegistration) {
10120
+ const moduleId = runtime.currentModuleId || runtime.registrationModuleId || name;
10121
+ if (!runtime.applyingPatch && runtime.patchedModules.has(moduleId)) return;
10122
+ definitions.set(moduleId, definition);
10123
+ if (registered.has(moduleId)) {
10124
+ return;
10125
+ }
10126
+ if (name === 'Component') {
10127
+ let pending = pendingNativeDefinitions.get(name);
10128
+ if (!pending) pendingNativeDefinitions.set(name, pending = []);
10129
+ pending.push(decorateObject(definition, moduleId));
10130
+ registered.add(moduleId);
10131
+ return;
10132
+ }
10133
+ const original = nativeRegistration || nativeRegistrations[name];
10134
+ if (typeof original !== 'function') throw new Error(name + ' registration API is unavailable');
10135
+ registered.add(moduleId);
10136
+ return original.call(globalThis, decorateObject(definition, moduleId));
10137
+ }
10138
+ globalThis[bridgeKey] = {
10139
+ App(definition) { return registerDefinition('App', definition); },
10140
+ Page(definition) { return registerDefinition('Page', definition); },
10141
+ Component(definition, nativeRegistration) { return registerDefinition('Component', definition, nativeRegistration); },
10142
+ installNative(name, registration) {
10143
+ if (typeof registration === 'function') nativeRegistrations[name] = registration;
10144
+ },
10145
+ takeNativeDefinitions(name) {
10146
+ const pending = pendingNativeDefinitions.get(name) || [];
10147
+ pendingNativeDefinitions.delete(name);
10148
+ return pending;
10149
+ },
10150
+ isApplying() { return runtime.applyingPatch; },
10151
+ trackWevuComponent(definition, refresh) {
10152
+ const moduleId = runtime.registrationModuleId || runtime.currentModuleId || 'Component';
10153
+ if (!runtime.applyingPatch && runtime.patchedModules.has(moduleId)) return definition;
10154
+ definitions.set(moduleId, definition);
10155
+ if (typeof refresh === 'function') wevuRefreshes.set(moduleId, refresh);
10156
+ if (runtime.applyingPatch) {
10157
+ wevuRefreshGenerations.set(moduleId, (wevuRefreshGenerations.get(moduleId) || 0) + 1);
10158
+ const currentRefresh = wevuRefreshes.get(moduleId);
10159
+ if (typeof currentRefresh === 'function') {
10160
+ for (const instance of [...getInstances(moduleId)]) currentRefresh(instance);
10161
+ }
10162
+ return definition;
10163
+ }
10164
+ return decorateWevuComponent(definition, moduleId);
10165
+ },
10166
+ ready: true,
10167
+ beginUpdate() {
10168
+ suppressLifecycles = true;
10169
+ runtime.beginPatch();
10170
+ },
10171
+ endUpdate() {
10172
+ runtime.endPatch();
10173
+ setTimeout(() => { suppressLifecycles = false; });
10174
+ }
10175
+ };
10176
+ `;
10177
+ function createStatefulHmrControlSource(control) {
10178
+ return `
10179
+ globalThis[${JSON.stringify(WEAPP_VITE_STATEFUL_HMR_CONTROL_KEY)}] = ${JSON.stringify(control)};
10180
+ (() => {
10181
+ const control = globalThis[${JSON.stringify(WEAPP_VITE_STATEFUL_HMR_CONTROL_KEY)}];
10182
+ if (globalThis[${JSON.stringify(WEAPP_VITE_STATEFUL_HMR_CLIENT_KEY)}]) return;
10183
+ let version = 0;
10184
+ let phase = 'registering';
10185
+ let pendingBatch;
10186
+ let requestGeneration = 0;
10187
+ let activeRequest;
10188
+ let timer;
10189
+ const sessionId = Date.now().toString(36) + '-' + Math.random().toString(36).slice(2);
10190
+ const schedule = (delay) => {
10191
+ if (timer) clearTimeout(timer);
10192
+ const expectedPhase = phase;
10193
+ const expectedVersion = version;
10194
+ timer = setTimeout(() => {
10195
+ timer = undefined;
10196
+ if (phase !== expectedPhase || version !== expectedVersion) return;
10197
+ send(phase === 'registering' ? 'register' : 'poll');
10198
+ }, delay);
10199
+ };
10200
+ const send = (action) => {
10201
+ activeRequest?.abort?.();
10202
+ const generation = ++requestGeneration;
10203
+ activeRequest = wx.request({
10204
+ url: control.url,
10205
+ method: 'POST',
10206
+ data: { token: control.token, action, buildId: control.buildId, sessionId, version },
10207
+ timeout: 30000,
10208
+ success(result) {
10209
+ if (generation !== requestGeneration) return;
10210
+ activeRequest = undefined;
10211
+ const type = result?.data?.type;
10212
+ if (action === 'register' && type === 'registered') {
10213
+ phase = 'polling';
10214
+ if (pendingBatch) globalThis[${JSON.stringify(WEAPP_VITE_STATEFUL_HMR_CLIENT_KEY)}].receiveBatch(pendingBatch.meta, pendingBatch.apply);
10215
+ else send('poll');
10216
+ } else if (type === 'idle' || type === 'changed') send('poll');
10217
+ else if (type === 'batch-published') schedule(2000);
10218
+ else if (type === 'rebuilding') schedule(1000);
10219
+ else schedule(500);
10220
+ },
10221
+ fail() {
10222
+ if (generation !== requestGeneration) return;
10223
+ activeRequest = undefined;
10224
+ schedule(500);
10225
+ }
10226
+ });
10227
+ };
10228
+ const relaunch = () => {
10229
+ const pages = typeof getCurrentPages === 'function' ? getCurrentPages() : [];
10230
+ const page = pages[pages.length - 1];
10231
+ const route = page?.route || page?.__route__;
10232
+ if (!route) return send('poll');
10233
+ const query = Object.entries(page?.options || {})
10234
+ .filter(([, value]) => value !== undefined)
10235
+ .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(String(value)))
10236
+ .join('&');
10237
+ wx.reLaunch({ url: '/' + route + (query ? '?' + query : ''), complete: () => send('poll') });
10238
+ };
10239
+ globalThis[${JSON.stringify(WEAPP_VITE_STATEFUL_HMR_CLIENT_KEY)}] = {
10240
+ getVersion() { return version; },
10241
+ receiveBatch(meta, apply) {
10242
+ if (phase === 'registering') {
10243
+ pendingBatch = { meta, apply };
10244
+ return;
10245
+ }
10246
+ pendingBatch = undefined;
10247
+ if (phase !== 'polling' || meta.buildId !== control.buildId || meta.fromVersion !== version) return send('poll');
10248
+ phase = 'applying';
10249
+ const bridge = globalThis[${JSON.stringify(WEAPP_VITE_STATEFUL_HMR_BRIDGE_KEY)}];
10250
+ if (!bridge?.ready) {
10251
+ phase = 'polling';
10252
+ return send('rebuild');
10253
+ }
10254
+ bridge.beginUpdate?.();
10255
+ try {
10256
+ apply();
10257
+ version = meta.targetVersion;
10258
+ phase = meta.compatible === false ? 'relaunching' : 'polling';
10259
+ } catch (error) {
10260
+ console.error('[weapp-vite] stateful HMR patch failed', error);
10261
+ phase = 'polling';
10262
+ return send('rebuild');
10263
+ } finally {
10264
+ bridge.endUpdate?.();
10265
+ }
10266
+ if (phase === 'relaunching') relaunch();
10267
+ else send('poll');
10268
+ }
10269
+ };
10270
+ send('register');
10271
+ })();
10272
+ `;
10273
+ }
10274
+ //#endregion
10275
+ //#region src/runtime/statefulHmr/serverState.ts
10276
+ function createStatefulHmrServerState(buildId) {
10277
+ return {
10278
+ buildId,
10279
+ deltas: [],
10280
+ hostVersion: 0,
10281
+ retainedDeltaBytes: 0,
10282
+ retiredSessionIds: []
10283
+ };
10284
+ }
10285
+ function transitionStatefulHmrServer(state, event) {
10286
+ switch (event.type) {
10287
+ case "delta-added": {
10288
+ const version = state.hostVersion + 1;
10289
+ return unchanged({
10290
+ ...state,
10291
+ deltas: [...state.deltas, {
10292
+ code: event.code,
10293
+ version
10294
+ }],
10295
+ hostVersion: version,
10296
+ retainedDeltaBytes: state.retainedDeltaBytes + event.bytes
10297
+ });
10298
+ }
10299
+ case "client-registered": return registerClient(state, event);
10300
+ case "client-reported": return reportClient(state, event);
10301
+ case "batch-publish-failed":
10302
+ if (state.inFlight?.sessionId !== event.sessionId || state.inFlight.targetVersion !== event.targetVersion) return unchanged(state);
10303
+ return unchanged({
10304
+ ...state,
10305
+ inFlight: void 0
10306
+ });
10307
+ case "full-build-committed": return unchanged(createStatefulHmrServerState(event.buildId));
10308
+ }
10309
+ }
10310
+ function registerClient(state, client) {
10311
+ const rejected = rejectClient(state, client);
10312
+ if (rejected) return rejected;
10313
+ if (state.retiredSessionIds.includes(client.sessionId)) return withCommand(state, {
10314
+ type: "ignore-client",
10315
+ reason: "retired-session"
10316
+ });
10317
+ if (state.activeSessionId === client.sessionId) return unchanged(state);
10318
+ const retiredSessionIds = state.activeSessionId ? [.../* @__PURE__ */ new Set([...state.retiredSessionIds, state.activeSessionId])] : state.retiredSessionIds;
10319
+ return unchanged({
10320
+ ...state,
10321
+ activeSessionId: client.sessionId,
10322
+ inFlight: void 0,
10323
+ retiredSessionIds
10324
+ });
10325
+ }
10326
+ function reportClient(state, client) {
10327
+ const rejected = rejectClient(state, client);
10328
+ if (rejected) return rejected;
10329
+ if (state.retiredSessionIds.includes(client.sessionId)) return withCommand(state, {
10330
+ type: "ignore-client",
10331
+ reason: "retired-session"
10332
+ });
10333
+ if (client.sessionId !== state.activeSessionId) return withCommand(state, {
10334
+ type: "ignore-client",
10335
+ reason: "unknown-session"
10336
+ });
10337
+ return synchronizeClient(state, client.version);
10338
+ }
10339
+ function rejectClient(state, client) {
10340
+ if (client.buildId !== state.buildId) return withCommand(state, {
10341
+ type: "ignore-client",
10342
+ reason: "stale-build"
10343
+ });
10344
+ if (!Number.isInteger(client.version) || client.version < 0) return withCommand(state, {
10345
+ type: "request-full-build",
10346
+ reason: "invalid-client-version"
10347
+ });
10348
+ if (client.version > state.hostVersion) return withCommand(state, {
10349
+ type: "request-full-build",
10350
+ reason: "client-version-ahead"
10351
+ });
10352
+ }
10353
+ function synchronizeClient(state, clientVersion) {
10354
+ let synchronized = state;
10355
+ if (state.inFlight) {
10356
+ if (clientVersion === state.inFlight.fromVersion) return publishMissingRange(state, clientVersion, state.inFlight.targetVersion);
10357
+ if (clientVersion !== state.inFlight.targetVersion) return withCommand(state, {
10358
+ type: "request-full-build",
10359
+ reason: "invalid-client-version"
10360
+ });
10361
+ synchronized = {
10362
+ ...state,
10363
+ inFlight: void 0
10364
+ };
10365
+ }
10366
+ if (clientVersion >= synchronized.hostVersion) return unchanged(synchronized);
10367
+ return publishMissingRange(synchronized, clientVersion, synchronized.hostVersion, true);
10368
+ }
10369
+ function publishMissingRange(state, fromVersion, targetVersion, trackInFlight = false) {
10370
+ const deltas = state.deltas.filter((delta) => delta.version > fromVersion && delta.version <= targetVersion);
10371
+ if (deltas.length !== targetVersion - fromVersion) return withCommand(state, {
10372
+ type: "request-full-build",
10373
+ reason: "missing-delta-history"
10374
+ });
10375
+ const batch = {
10376
+ buildId: state.buildId,
10377
+ deltas,
10378
+ fromVersion,
10379
+ sessionId: state.activeSessionId,
10380
+ targetVersion
10381
+ };
10382
+ return withCommand(trackInFlight ? {
10383
+ ...state,
10384
+ inFlight: {
10385
+ fromVersion,
10386
+ sessionId: batch.sessionId,
10387
+ targetVersion
10388
+ }
10389
+ } : state, {
10390
+ type: "publish-batch",
10391
+ batch
10392
+ });
10393
+ }
10394
+ function unchanged(state) {
10395
+ return {
10396
+ commands: [],
10397
+ state
10398
+ };
10399
+ }
10400
+ function withCommand(state, command) {
10401
+ return {
10402
+ commands: [command],
10403
+ state
10404
+ };
10405
+ }
10406
+ //#endregion
10407
+ //#region src/runtime/statefulHmr/transport.ts
10408
+ const endpointPath = "/__weapp_vite_stateful_hmr__";
10409
+ const pollTimeout = 25e3;
10410
+ var StatefulHmrTransport = class {
10411
+ server;
10412
+ publishUpdate;
10413
+ requestFullBuild;
10414
+ state = createStatefulHmrServerState(createId());
10415
+ token = createId();
10416
+ pendingPolls = /* @__PURE__ */ new Map();
10417
+ closed = false;
10418
+ constructor(server, publishUpdate, requestFullBuild) {
10419
+ this.server = server;
10420
+ this.publishUpdate = publishUpdate;
10421
+ this.requestFullBuild = requestFullBuild;
10422
+ }
10423
+ get retainedDeltaBytes() {
10424
+ return this.state.retainedDeltaBytes;
10425
+ }
10426
+ get retainedDeltaCount() {
10427
+ return this.state.hostVersion;
10428
+ }
10429
+ install() {
10430
+ this.server.middlewares.use(endpointPath, this.handleRequest);
10431
+ }
10432
+ close() {
10433
+ this.closed = true;
10434
+ this.respondToAll({ type: "rebuilding" });
10435
+ }
10436
+ addDelta(code) {
10437
+ this.apply({
10438
+ type: "delta-added",
10439
+ bytes: Buffer.byteLength(code),
10440
+ code
10441
+ });
10442
+ this.respondToAll({ type: "changed" });
10443
+ }
10444
+ createBuildId() {
10445
+ return createId();
10446
+ }
10447
+ commitFullBuild(buildId) {
10448
+ this.apply({
10449
+ type: "full-build-committed",
10450
+ buildId
10451
+ });
10452
+ this.respondToAll({ type: "rebuilding" });
10453
+ }
10454
+ isCurrentBuild(buildId) {
10455
+ return this.state.buildId === buildId;
10456
+ }
10457
+ createControl() {
10458
+ const address = this.server.httpServer?.address();
10459
+ const port = address && typeof address !== "string" ? address.port : this.server.config.server.port;
10460
+ return {
10461
+ buildId: this.state.buildId,
10462
+ token: this.token,
10463
+ url: `http://127.0.0.1:${port}${endpointPath}`
10464
+ };
10465
+ }
10466
+ handleRequest = async (request, response) => {
10467
+ if (this.closed || request.method !== "POST") {
10468
+ respond(response, 404, { type: "not-found" });
10469
+ return;
10470
+ }
10471
+ let body;
10472
+ try {
10473
+ body = JSON.parse(await readBody(request));
10474
+ } catch {
10475
+ respond(response, 400, { type: "invalid-request" });
10476
+ return;
10477
+ }
10478
+ if (!isClientReport(body) || body.token !== this.token) {
10479
+ respond(response, 403, { type: "forbidden" });
10480
+ return;
10481
+ }
10482
+ if (body.action === "rebuild") {
10483
+ this.requestFullBuild();
10484
+ respond(response, 202, { type: "rebuilding" });
10485
+ return;
10486
+ }
10487
+ if (body.action === "register") {
10488
+ if (this.apply({
10489
+ type: "client-registered",
10490
+ buildId: body.buildId,
10491
+ sessionId: body.sessionId,
10492
+ version: body.version
10493
+ }).some((command) => command.type === "request-full-build")) this.requestFullBuild();
10494
+ respond(response, 200, { type: "registered" });
10495
+ return;
10496
+ }
10497
+ const commands = this.apply({
10498
+ type: "client-reported",
10499
+ buildId: body.buildId,
10500
+ sessionId: body.sessionId,
10501
+ version: body.version
10502
+ });
10503
+ const publish = commands.find((command) => command.type === "publish-batch");
10504
+ if (publish?.type === "publish-batch") {
10505
+ try {
10506
+ await this.publishUpdate(publish.batch.buildId, renderBatch(publish.batch, createId()));
10507
+ respond(response, 200, {
10508
+ type: "batch-published",
10509
+ targetVersion: publish.batch.targetVersion
10510
+ });
10511
+ } catch {
10512
+ this.apply({
10513
+ type: "batch-publish-failed",
10514
+ sessionId: publish.batch.sessionId,
10515
+ targetVersion: publish.batch.targetVersion
10516
+ });
10517
+ respond(response, 500, { type: "publish-failed" });
10518
+ }
10519
+ return;
10520
+ }
10521
+ if (commands.some((command) => command.type === "request-full-build")) {
10522
+ this.requestFullBuild();
10523
+ respond(response, 202, { type: "rebuilding" });
10524
+ return;
10525
+ }
10526
+ if (commands.some((command) => command.type === "ignore-client")) {
10527
+ respond(response, 409, { type: "rebuilding" });
10528
+ return;
10529
+ }
10530
+ this.holdPoll(body.sessionId, response);
10531
+ };
10532
+ apply(event) {
10533
+ const transition = transitionStatefulHmrServer(this.state, event);
10534
+ this.state = transition.state;
10535
+ return transition.commands;
10536
+ }
10537
+ holdPoll(sessionId, response) {
10538
+ const previous = this.pendingPolls.get(sessionId);
10539
+ if (previous) this.finishPoll(sessionId, previous, { type: "changed" });
10540
+ const pending = {
10541
+ response,
10542
+ timeout: setTimeout(() => this.finishPoll(sessionId, pending, { type: "idle" }), pollTimeout)
10543
+ };
10544
+ this.pendingPolls.set(sessionId, pending);
10545
+ response.on("close", () => this.finishPoll(sessionId, pending));
10546
+ }
10547
+ finishPoll(sessionId, pending, value) {
10548
+ if (this.pendingPolls.get(sessionId) !== pending) return;
10549
+ clearTimeout(pending.timeout);
10550
+ this.pendingPolls.delete(sessionId);
10551
+ if (value) respond(pending.response, 200, value);
10552
+ }
10553
+ respondToAll(value) {
10554
+ for (const [sessionId, pending] of this.pendingPolls) this.finishPoll(sessionId, pending, value);
10555
+ }
10556
+ };
10557
+ function renderBatch(batch, nonce) {
10558
+ const metadata = {
10559
+ buildId: batch.buildId,
10560
+ compatible: true,
10561
+ fromVersion: batch.fromVersion,
10562
+ targetVersion: batch.targetVersion
10563
+ };
10564
+ const code = batch.deltas.map((delta) => delta.code).join("\n");
10565
+ return `// ${nonce}\nglobalThis.__WEAPP_VITE_STATEFUL_HMR_CLIENT__.receiveBatch(${JSON.stringify(metadata)}, () => {\n${indent(code, 2)}\n});\n`;
10566
+ }
10567
+ function indent(value, spaces) {
10568
+ const prefix = " ".repeat(spaces);
10569
+ return value.split("\n").map((line) => `${prefix}${line}`).join("\n");
10570
+ }
10571
+ function isClientReport(value) {
10572
+ if (!value || typeof value !== "object") return false;
10573
+ const candidate = value;
10574
+ return (candidate.action === "poll" || candidate.action === "rebuild" || candidate.action === "register") && typeof candidate.buildId === "string" && typeof candidate.sessionId === "string" && typeof candidate.token === "string" && typeof candidate.version === "number";
10575
+ }
10576
+ async function readBody(request) {
10577
+ const chunks = [];
10578
+ let size = 0;
10579
+ for await (const chunk of request) {
10580
+ const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
10581
+ size += buffer.length;
10582
+ if (size > 64 * 1024) throw new Error("stateful HMR request body is too large");
10583
+ chunks.push(buffer);
10584
+ }
10585
+ return Buffer.concat(chunks).toString("utf8");
10586
+ }
10587
+ function respond(response, status, body) {
10588
+ if (response.writableEnded) return;
10589
+ response.statusCode = status;
10590
+ response.setHeader("content-type", "application/json");
10591
+ response.end(JSON.stringify(body));
10592
+ }
10593
+ function createId() {
10594
+ return randomBytes(16).toString("hex");
10595
+ }
10596
+ //#endregion
10597
+ //#region src/runtime/statefulHmr/viteAdapter.ts
10598
+ const clientId = "weapp-vite-stateful-hmr";
10599
+ var StatefulHmrViteAdapter = class {
10600
+ config;
10601
+ server;
10602
+ callbacks;
10603
+ bundledDev;
10604
+ constructor(config, server, callbacks) {
10605
+ this.config = config;
10606
+ this.server = server;
10607
+ this.callbacks = callbacks;
10608
+ }
10609
+ install() {
10610
+ const bundledDev = this.server.environments.client.bundledDev;
10611
+ if (!bundledDev) throw new Error("stateful-experimental HMR 需要 Vite experimental.bundledDev。");
10612
+ if (typeof bundledDev.getRolldownOptions !== "function" || typeof bundledDev.storeOutputFiles !== "function") throw new TypeError("当前 Vite bundled-development 私有 API 与 weapp-vite 不兼容。");
10613
+ this.bundledDev = bundledDev;
10614
+ this.installOptions(bundledDev);
10615
+ this.installOutput(bundledDev);
10616
+ this.installPatches(bundledDev);
10617
+ this.installListener(bundledDev);
10618
+ }
10619
+ async rebuild() {
10620
+ const engine = this.bundledDev?._devEngine;
10621
+ if (!engine) return;
10622
+ engine.triggerFullBuild();
10623
+ await engine.ensureLatestBuildOutput();
10624
+ }
10625
+ registerBundleModules(output) {
10626
+ const moduleIds = /* @__PURE__ */ new Set();
10627
+ for (const item of output) {
10628
+ if (item.type !== "chunk") continue;
10629
+ for (const match of item.code.matchAll(/registerModule\("([^"]+)"/g)) moduleIds.add(match[1]);
10630
+ for (const id of Object.keys(item.modules ?? {})) {
10631
+ const normalized = toStableModuleId(id, this.config.root);
10632
+ if (!moduleIds.has(normalized)) moduleIds.add(normalized);
10633
+ }
10634
+ }
10635
+ this.registerModules([...moduleIds]);
10636
+ return moduleIds.size;
10637
+ }
10638
+ registerPatchModules(code) {
10639
+ const moduleIds = /* @__PURE__ */ new Set();
10640
+ for (const match of code.matchAll(/create(?:Esm|Cjs)Initializer\("([^"]+)"/g)) moduleIds.add(match[1]);
10641
+ this.registerModules([...moduleIds]);
10642
+ }
10643
+ registerModules(moduleIds) {
10644
+ if (moduleIds.length) this.bundledDev?._devEngine?.registerModules(clientId, moduleIds);
10645
+ }
10646
+ installOptions(bundledDev) {
10647
+ const original = bundledDev.getRolldownOptions.bind(bundledDev);
10648
+ bundledDev.getRolldownOptions = async () => {
10649
+ const options = await original();
10650
+ const output = Array.isArray(options.output) ? options.output[0] ??= {} : options.output ??= {};
10651
+ const configuredOutput = this.config.build.rolldownOptions.output;
10652
+ const desiredOutput = Array.isArray(configuredOutput) ? configuredOutput[0] : configuredOutput;
10653
+ Object.assign(output, desiredOutput);
10654
+ const userBanner = output.banner;
10655
+ const userFooter = output.footer;
10656
+ output.format = "cjs";
10657
+ output.minify = false;
10658
+ output.sourcemap = false;
10659
+ output.banner = async (chunk) => {
10660
+ const existing = typeof userBanner === "function" ? await userBanner(chunk) : userBanner ?? "";
10661
+ return `${existing}${existing ? "\n" : ""}${createStatefulHmrBanner(chunk)}`;
10662
+ };
10663
+ output.footer = async (chunk) => {
10664
+ const statefulFooter = createStatefulHmrFooter(chunk);
10665
+ const existing = typeof userFooter === "function" ? await userFooter(chunk) : userFooter ?? "";
10666
+ return `${statefulFooter}${statefulFooter && existing ? "\n" : ""}${existing}`;
10667
+ };
10668
+ options.experimental ??= {};
10669
+ options.experimental.devMode = {
10670
+ ...typeof options.experimental.devMode === "object" ? options.experimental.devMode : {},
10671
+ implement: statefulHmrRolldownRuntimeSource,
10672
+ lazy: false
10673
+ };
10674
+ return options;
10675
+ };
10676
+ }
10677
+ installOutput(bundledDev) {
10678
+ const original = bundledDev.storeOutputFiles.bind(bundledDev);
10679
+ bundledDev.storeOutputFiles = (output) => {
10680
+ original(output);
10681
+ this.callbacks.onOutput(output);
10682
+ };
10683
+ }
10684
+ installPatches(bundledDev) {
10685
+ const original = bundledDev.handleHmrOutput.bind(bundledDev);
10686
+ bundledDev.handleHmrOutput = (client, files, output, info) => {
10687
+ if (output.type === "Noop") return;
10688
+ if (this.callbacks.onPatch(files, output)) original(client, files, output, info);
10689
+ };
10690
+ }
10691
+ installListener(bundledDev) {
10692
+ const original = bundledDev.listen.bind(bundledDev);
10693
+ bundledDev.listen = async () => {
10694
+ await original();
10695
+ bundledDev.clients.setupIfNeeded({ send: (payload) => this.handlePayload(payload) }, clientId);
10696
+ const engine = bundledDev._devEngine;
10697
+ if (!engine) throw new Error("Vite 未初始化微信状态保持 HMR 所需的 DevEngine。");
10698
+ await engine.ensureCurrentBuildFinish();
10699
+ if ((await engine.getBundleState()).lastBuildErrored) throw new Error("微信状态保持 HMR 初次构建失败。");
10700
+ await this.callbacks.waitForInitialBundle();
10701
+ };
10702
+ }
10703
+ handlePayload(payload) {
10704
+ if (!payload || typeof payload !== "object") return;
10705
+ const candidate = payload;
10706
+ if (candidate.type === "error" && typeof candidate.err?.message === "string") this.callbacks.onError(candidate.err.message);
10707
+ }
10708
+ };
10709
+ function createStatefulHmrBanner(chunk) {
10710
+ if (chunk.fileName === "app.js") return [
10711
+ `require(${JSON.stringify(`./${WEAPP_VITE_STATEFUL_HMR_CONTROL_FILE}`)});`,
10712
+ "require(\"./rolldown-runtime.js\");",
10713
+ `globalThis[${JSON.stringify(WEAPP_VITE_STATEFUL_HMR_BRIDGE_KEY)}].installNative('App', definition => App(definition));`
10714
+ ].join("");
10715
+ if (!chunk.isEntry || !chunk.fileName.endsWith(".js")) return "";
10716
+ const prefix = "../".repeat(chunk.fileName.split("/").length - 1);
10717
+ return [
10718
+ `require(${JSON.stringify(`${prefix}rolldown-runtime.js`)});`,
10719
+ `globalThis[${JSON.stringify(WEAPP_VITE_STATEFUL_HMR_BRIDGE_KEY)}].installNative('Page', definition => Page(definition));`,
10720
+ `require(${JSON.stringify(`${prefix}${WEAPP_VITE_STATEFUL_HMR_PRELOAD_FILE}`)});`,
10721
+ `require(${JSON.stringify(`${prefix}${WEAPP_VITE_STATEFUL_HMR_UPDATE_FILE}`)});`
10722
+ ].join("");
10723
+ }
10724
+ function createStatefulHmrFooter(chunk) {
10725
+ if (!chunk.isEntry || chunk.fileName === "app.js" || !chunk.fileName.endsWith(".js")) return "";
10726
+ return `for (const definition of globalThis[${JSON.stringify(WEAPP_VITE_STATEFUL_HMR_BRIDGE_KEY)}].takeNativeDefinitions('Component')) Component(definition);`;
10727
+ }
10728
+ function toStableModuleId(id, root) {
10729
+ const normalizedId = id.replaceAll("\\", "/");
10730
+ const absolute = path$1.posix.isAbsolute(normalizedId) || /^[A-Z]:\//i.test(normalizedId);
10731
+ if (normalizedId.startsWith("\0") || !absolute) return normalizedId;
10732
+ return path$1.posix.relative(root.replaceAll("\\", "/"), normalizedId);
10733
+ }
10734
+ //#endregion
10735
+ //#region src/runtime/statefulHmr/session.ts
10736
+ const maxRetainedDeltaCount = 1e3;
10737
+ const maxRetainedDeltaBytes = 16 * 1024 * 1024;
10738
+ async function runStatefulHmrDev(ctx, buildOptions, restart) {
10739
+ const configService = ctx.configService;
10740
+ if (configService.platform !== "weapp") throw new Error("weapp.hmr.runtime=\"stateful-experimental\" 目前仅支持微信小程序平台。");
10741
+ let session;
10742
+ const installPlugin = {
10743
+ name: "weapp-vite:stateful-hmr-session",
10744
+ enforce: "post",
10745
+ configureServer(server) {
10746
+ const currentSession = new StatefulHmrSession(ctx, server, restart);
10747
+ session = currentSession;
10748
+ currentSession.install();
10749
+ },
10750
+ transform(code, id) {
10751
+ if (!isStatefulHmrBoundary(id, configService.absoluteSrcRoot) || code.includes("import.meta.hot.accept")) return;
10752
+ return `${id.endsWith(".vue") ? code : redirectNativeComponentRegistration(code)}\nif (import.meta.hot) import.meta.hot.accept();\n`;
10753
+ }
10754
+ };
10755
+ const server = await createServer({
10756
+ ...buildOptions,
10757
+ appType: "custom",
10758
+ configFile: false,
10759
+ define: {
10760
+ ...buildOptions.define ?? {},
10761
+ App: `globalThis[${JSON.stringify(WEAPP_VITE_STATEFUL_HMR_BRIDGE_KEY)}].App`,
10762
+ Page: `globalThis[${JSON.stringify(WEAPP_VITE_STATEFUL_HMR_BRIDGE_KEY)}].Page`
10763
+ },
10764
+ experimental: {
10765
+ ...buildOptions.experimental ?? {},
10766
+ bundledDev: true
10767
+ },
10768
+ plugins: [installPlugin, ...buildOptions.plugins ?? []],
10769
+ server: {
10770
+ ...buildOptions.server ?? {},
10771
+ host: "127.0.0.1",
10772
+ port: 0
10773
+ },
10774
+ build: {
10775
+ ...buildOptions.build ?? {},
10776
+ watch: void 0,
10777
+ write: false
10778
+ }
10779
+ });
10780
+ await server.listen();
10781
+ if (!session) {
10782
+ await server.close();
10783
+ throw new Error("微信状态保持 HMR session 未完成初始化。");
10784
+ }
10785
+ await session.refreshControl();
10786
+ return createWatcherAdapter(server, session);
10787
+ }
10788
+ var StatefulHmrSession = class {
10789
+ ctx;
10790
+ server;
10791
+ restart;
10792
+ adapter;
10793
+ initialBundle = Promise.withResolvers();
10794
+ transport;
10795
+ outputChain = Promise.resolve();
10796
+ rebuildTimer;
10797
+ restartTimer;
10798
+ constructor(ctx, server, restart) {
10799
+ this.ctx = ctx;
10800
+ this.server = server;
10801
+ this.restart = restart;
10802
+ this.transport = new StatefulHmrTransport(server, async (buildId, source) => {
10803
+ await this.enqueueOutput(async () => {
10804
+ if (!this.transport.isCurrentBuild(buildId)) return;
10805
+ await writeStatefulHmrOutput(this.ctx.configService.outDir, [{
10806
+ type: "asset",
10807
+ fileName: WEAPP_VITE_STATEFUL_HMR_UPDATE_FILE,
10808
+ source
10809
+ }]);
10810
+ });
10811
+ }, () => this.requestFullBuild());
10812
+ this.adapter = new StatefulHmrViteAdapter(server.config, server, {
10813
+ onError: (message) => server.config.logger.error(`[weapp-vite] stateful HMR: ${message}`),
10814
+ onOutput: (output) => this.handleOutput(output),
10815
+ onPatch: (files, output) => this.handlePatch(files, output),
10816
+ waitForInitialBundle: () => this.waitForInitialBundle()
10817
+ });
10818
+ }
10819
+ install() {
10820
+ this.transport.install();
10821
+ this.adapter.install();
10822
+ }
10823
+ async close() {
10824
+ if (this.rebuildTimer) clearTimeout(this.rebuildTimer);
10825
+ if (this.restartTimer) clearTimeout(this.restartTimer);
10826
+ this.transport.close();
10827
+ await this.outputChain;
10828
+ }
10829
+ async refreshControl() {
10830
+ await this.enqueueOutput(async () => {
10831
+ await writeStatefulHmrOutput(this.ctx.configService.outDir, [{
10832
+ type: "asset",
10833
+ fileName: WEAPP_VITE_STATEFUL_HMR_CONTROL_FILE,
10834
+ source: createStatefulHmrControlSource(this.transport.createControl())
10835
+ }]);
10836
+ });
10837
+ }
10838
+ handleOutput(output) {
10839
+ this.enqueueOutput(async () => {
10840
+ const compatibleOutput = await transformOutput(output);
10841
+ const fullBuild = compatibleOutput.some((item) => item.fileName === "app.js");
10842
+ if (fullBuild) {
10843
+ const buildId = this.transport.createBuildId();
10844
+ this.transport.commitFullBuild(buildId);
10845
+ setAsset(compatibleOutput, WEAPP_VITE_STATEFUL_HMR_CONTROL_FILE, createStatefulHmrControlSource({
10846
+ ...this.transport.createControl(),
10847
+ buildId
10848
+ }));
10849
+ setAsset(compatibleOutput, WEAPP_VITE_STATEFUL_HMR_PRELOAD_FILE, "void 0;\n");
10850
+ setAsset(compatibleOutput, WEAPP_VITE_STATEFUL_HMR_UPDATE_FILE, "void 0;\n");
10851
+ }
10852
+ await writeStatefulHmrOutput(this.ctx.configService.outDir, compatibleOutput);
10853
+ if (fullBuild) {
10854
+ const moduleCount = this.adapter.registerBundleModules(compatibleOutput);
10855
+ this.server.config.logger.info(`[weapp-vite] 微信状态保持 HMR 已就绪(${moduleCount} modules)`);
10856
+ this.initialBundle.resolve();
10857
+ }
10858
+ });
10859
+ }
10860
+ handlePatch(files, output) {
10861
+ if (!isSafeJavaScriptPatch(files, output, this.ctx.runtimeState.build.hmr.profile.dirtyReasonSummary)) {
10862
+ this.requestServerRestart();
10863
+ return false;
10864
+ }
10865
+ this.adapter.registerPatchModules(output.code);
10866
+ transformJavaScript(output.code, output.filename).then((code) => {
10867
+ if (shouldResetStatefulHmrRetention(this.transport.retainedDeltaCount, this.transport.retainedDeltaBytes, Buffer.byteLength(code))) {
10868
+ this.requestFullBuild();
10869
+ return;
10870
+ }
10871
+ this.transport.addDelta(code);
10872
+ }).catch((error) => {
10873
+ this.server.config.logger.error("[weapp-vite] stateful HMR patch transform failed", { error });
10874
+ this.requestFullBuild();
10875
+ });
10876
+ return true;
10877
+ }
10878
+ requestFullBuild() {
10879
+ if (this.rebuildTimer) return;
10880
+ this.rebuildTimer = setTimeout(() => {
10881
+ this.rebuildTimer = void 0;
10882
+ this.adapter.rebuild().catch((error) => {
10883
+ this.server.config.logger.error("[weapp-vite] stateful HMR full rebuild failed", { error });
10884
+ });
10885
+ }, 100);
10886
+ }
10887
+ requestServerRestart() {
10888
+ if (this.restartTimer) return;
10889
+ this.restartTimer = setTimeout(() => {
10890
+ this.restartTimer = void 0;
10891
+ this.restart().catch((error) => {
10892
+ this.server.config.logger.error("[weapp-vite] stateful HMR server restart failed", { error });
10893
+ });
10894
+ }, 100);
10895
+ }
10896
+ enqueueOutput(task) {
10897
+ this.outputChain = this.outputChain.then(task, task).catch((error) => {
10898
+ this.server.config.logger.error("[weapp-vite] stateful HMR output failed", { error });
10899
+ });
10900
+ return this.outputChain;
10901
+ }
10902
+ async waitForInitialBundle() {
10903
+ await this.initialBundle.promise;
10904
+ await this.outputChain;
10905
+ }
10906
+ };
10907
+ function createWatcherAdapter(server, session) {
10908
+ return {
10909
+ close: async () => {
10910
+ await session.close();
10911
+ await server.close();
10912
+ },
10913
+ on() {
10914
+ return this;
10915
+ }
10916
+ };
10917
+ }
10918
+ function isStatefulHmrBoundary(id, srcRoot) {
10919
+ if (id.includes("?")) return false;
10920
+ const cleanId = id.split("?", 1)[0];
10921
+ return cleanId.startsWith(srcRoot.replaceAll("\\", "/")) && /\.(?:[cm]?[jt]sx?|vue)$/.test(cleanId);
10922
+ }
10923
+ function redirectNativeComponentRegistration(code) {
10924
+ if (!code.includes("Component")) return code;
10925
+ const ast = parseJsLike(code);
10926
+ const magicString = new MagicString(code);
10927
+ let changed = false;
10928
+ traverse(ast, { CallExpression(path) {
10929
+ const callee = path.node.callee;
10930
+ if (callee.type !== "Identifier" || callee.name !== "Component" || path.scope.hasBinding("Component") || callee.start == null || callee.end == null) return;
10931
+ magicString.overwrite(callee.start, callee.end, `globalThis[${JSON.stringify(WEAPP_VITE_STATEFUL_HMR_BRIDGE_KEY)}].Component`);
10932
+ changed = true;
10933
+ } });
10934
+ return changed ? magicString.toString() : code;
10935
+ }
10936
+ function isSafeJavaScriptPatch(files, output, dirtyReasonSummary = []) {
10937
+ return output.type === "Patch" && output.hmrBoundaries.length > 0 && files.every((file) => /\.(?:[cm]?[jt]sx?|vue)$/.test(file)) && !dirtyReasonSummary.some((reason) => /^(?:entry-json-only|entry-local-asset|entry-style-only):/.test(reason));
10938
+ }
10939
+ function shouldResetStatefulHmrRetention(retainedDeltaCount, retainedDeltaBytes, nextDeltaBytes) {
10940
+ return retainedDeltaCount >= maxRetainedDeltaCount || retainedDeltaBytes + nextDeltaBytes >= maxRetainedDeltaBytes;
10941
+ }
10942
+ async function transformOutput(output) {
10943
+ return await Promise.all(output.map(async (item) => {
10944
+ if (item.type !== "chunk") return item;
10945
+ return {
10946
+ ...item,
10947
+ code: await transformJavaScript(item.code, item.fileName)
10948
+ };
10949
+ }));
10950
+ }
10951
+ async function transformJavaScript(code, filename) {
10952
+ return (await transformWithOxc(code, filename, {
10953
+ assumptions: { setPublicClassFields: true },
10954
+ lang: "js",
10955
+ sourcemap: false,
10956
+ target: "es2018"
10957
+ })).code;
10958
+ }
10959
+ function setAsset(output, fileName, source) {
10960
+ const index = output.findIndex((item) => item.fileName === fileName);
10961
+ const asset = {
10962
+ type: "asset",
10963
+ fileName,
10964
+ source
10965
+ };
10966
+ if (index >= 0) output[index] = asset;
10967
+ else output.push(asset);
10968
+ }
10969
+ //#endregion
9823
10970
  //#region src/runtime/watch/options.ts
9824
10971
  function resolvePollingWatchConfig(configService) {
9825
10972
  const buildWatch = configService.inlineConfig?.build?.watch;
@@ -12632,73 +13779,47 @@ function createBuildService(ctx) {
12632
13779
  if (!configService.isDev) return false;
12633
13780
  return requestedConfigRestartBuilds.delete(target);
12634
13781
  }
12635
- function resetRuntimeStateForConfigRestart() {
12636
- const fresh = createRuntimeState();
12637
- const autoRoutes = ctx.runtimeState.autoRoutes;
12638
- autoRoutes.routes = fresh.autoRoutes.routes;
12639
- autoRoutes.serialized = fresh.autoRoutes.serialized;
12640
- autoRoutes.moduleCode = fresh.autoRoutes.moduleCode;
12641
- autoRoutes.typedDefinition = fresh.autoRoutes.typedDefinition;
12642
- autoRoutes.watchFiles.clear();
12643
- autoRoutes.watchDirs.clear();
12644
- autoRoutes.dirty = fresh.autoRoutes.dirty;
12645
- autoRoutes.initialized = fresh.autoRoutes.initialized;
12646
- autoRoutes.candidates.clear();
12647
- autoRoutes.needsFullRescan = fresh.autoRoutes.needsFullRescan;
12648
- autoRoutes.loadingAppConfig = fresh.autoRoutes.loadingAppConfig;
12649
- const autoImport = ctx.runtimeState.autoImport;
12650
- autoImport.registry.clear();
12651
- autoImport.resolvedResolverComponents.clear();
12652
- autoImport.matcher = void 0;
12653
- autoImport.matcherKey = fresh.autoImport.matcherKey;
12654
- autoImport.version += 1;
12655
- autoImport.pendingEntriesByImporter.clear();
12656
- ctx.runtimeState.build.hmr = fresh.build.hmr;
12657
- const json = ctx.runtimeState.json;
12658
- json.cache.cache.clear();
12659
- json.cache.mtimeMap.clear();
12660
- json.cache.signatureMap.clear();
12661
- json.emittedSource.clear();
12662
- const asset = ctx.runtimeState.asset;
12663
- asset.emittedBuffer.clear();
12664
- asset.scopedSlotGenerics.clear();
12665
- const css = ctx.runtimeState.css;
12666
- css.importerToDependencies.clear();
12667
- css.dependencyToImporters.clear();
12668
- css.emittedSource.clear();
12669
- const wxml = ctx.runtimeState.wxml;
12670
- wxml.depsMap.clear();
12671
- wxml.importerMap.clear();
12672
- wxml.tokenMap.clear();
12673
- wxml.componentsMap.clear();
12674
- wxml.aggregatedComponentsMap.clear();
12675
- wxml.templatePathMap.clear();
12676
- wxml.cache.cache.clear();
12677
- wxml.cache.mtimeMap.clear();
12678
- wxml.cache.signatureMap.clear();
12679
- wxml.emittedCode.clear();
12680
- const scan = ctx.runtimeState.scan;
12681
- scan.subPackageMap.clear();
12682
- scan.independentSubPackageMap.clear();
12683
- scan.warnedMessages.clear();
12684
- scan.appEntry = void 0;
12685
- scan.pluginJson = void 0;
12686
- scan.pluginJsonPath = void 0;
12687
- scan.isDirty = fresh.scan.isDirty;
12688
- scan.independentDirtyRoots.clear();
12689
- const lib = ctx.runtimeState.lib;
12690
- lib.enabled = fresh.lib.enabled;
12691
- lib.entries.clear();
12692
- }
12693
13782
  async function runDev(target) {
12694
13783
  if (process.env.NODE_ENV === void 0) process.env.NODE_ENV = "development";
12695
13784
  debug$2?.(`[${target}] dev build watcher start`);
12696
13785
  const { hasWorkersDir, workersDir } = checkWorkersOptions(target, configService, scanService);
12697
- const buildOptions = appendHmrMetricsPlugin(applyTargetBuildOverride(configService.merge(void 0, createSharedBuildConfig(configService, scanService), resolveTargetBuildOverride(target)), target));
13786
+ const createDevBuildOptions = () => appendHmrMetricsPlugin(applyTargetBuildOverride(configService.merge(void 0, createSharedBuildConfig(configService, scanService), resolveTargetBuildOverride(target)), target));
13787
+ let buildOptions = createDevBuildOptions();
12698
13788
  buildOptions.build = {
12699
13789
  ...buildOptions.build ?? {},
12700
13790
  write: true
12701
13791
  };
13792
+ if (target === "app" && configService.weappViteConfig.hmr?.runtime === "stateful-experimental") {
13793
+ await build({
13794
+ ...buildOptions,
13795
+ build: {
13796
+ ...buildOptions.build ?? {},
13797
+ watch: void 0
13798
+ }
13799
+ });
13800
+ resetRuntimeStateForFreshBuild(ctx.runtimeState);
13801
+ await scanService.loadAppEntry();
13802
+ scanService.loadSubPackages();
13803
+ buildOptions = createDevBuildOptions();
13804
+ buildOptions.build = {
13805
+ ...buildOptions.build ?? {},
13806
+ write: true
13807
+ };
13808
+ const workerPromise = hasWorkersDir && workersDir ? devWorkers(configService, watcherService, workersDir) : Promise.resolve();
13809
+ let statefulWatcher;
13810
+ const [watcher] = await Promise.all([runStatefulHmrDev(ctx, buildOptions, async () => {
13811
+ await statefulWatcher?.close();
13812
+ logger_default.info("检测到非兼容更新,正在重启微信状态保持 HMR 构建...");
13813
+ resetRuntimeStateForFreshBuild(ctx.runtimeState);
13814
+ await scanService.loadAppEntry();
13815
+ scanService.loadSubPackages();
13816
+ await runDev(target);
13817
+ logger_default.success("微信状态保持 HMR 构建已完成完整重载。");
13818
+ }), workerPromise]);
13819
+ statefulWatcher = watcher;
13820
+ watcherService.setRollupWatcher(watcher, "/");
13821
+ return watcher;
13822
+ }
12702
13823
  const snapshotBuildOptions = {
12703
13824
  ...buildOptions,
12704
13825
  build: { ...buildOptions.build ?? {} }
@@ -12848,7 +13969,7 @@ function createBuildService(ctx) {
12848
13969
  if (shouldRestartDevBuild(target)) {
12849
13970
  await watcher.close();
12850
13971
  logger_default.info("检测到 Vite 配置变更,正在重启小程序开发构建...");
12851
- resetRuntimeStateForConfigRestart();
13972
+ resetRuntimeStateForFreshBuild(ctx.runtimeState);
12852
13973
  await configService.load(configService.loadOptions);
12853
13974
  try {
12854
13975
  const supportFiles = await syncProjectSupportFiles(ctx);
@@ -18008,6 +19129,32 @@ async function collectAppEntries(options) {
18008
19129
  };
18009
19130
  }
18010
19131
  //#endregion
19132
+ //#region src/plugins/outputFinalizer/pageLayout.ts
19133
+ const nativePageLayoutOutputs = /* @__PURE__ */ new WeakMap();
19134
+ function registerNativePageLayoutOutput(options) {
19135
+ const { configService, runtimeState, pageId, templatePath, plan } = options;
19136
+ const { templateExtension } = resolveCompilerOutputExtensions(configService.outputExtensions);
19137
+ const fileName = resolveRelativeOutputFileNameWithExtension(configService, templatePath, templateExtension);
19138
+ const outputs = nativePageLayoutOutputs.get(runtimeState) ?? /* @__PURE__ */ new Map();
19139
+ if (plan) {
19140
+ outputs.set(fileName, {
19141
+ pageId,
19142
+ plan
19143
+ });
19144
+ nativePageLayoutOutputs.set(runtimeState, outputs);
19145
+ } else outputs.delete(fileName);
19146
+ }
19147
+ function restoreNativePageLayoutOutputs(ctx, bundle) {
19148
+ const outputs = nativePageLayoutOutputs.get(ctx.runtimeState);
19149
+ if (!outputs?.size) return;
19150
+ for (const [fileName, { pageId, plan }] of outputs) {
19151
+ const output = bundle[fileName];
19152
+ if (output?.type !== "asset") continue;
19153
+ const transformed = applyPageLayoutPlanToNativePage({ template: typeof output.source === "string" ? output.source : Buffer.from(output.source).toString("utf8") }, pageId, plan, { platform: ctx.configService.platform });
19154
+ if (transformed.template) output.source = transformed.template;
19155
+ }
19156
+ }
19157
+ //#endregion
18011
19158
  //#region src/plugins/utils/invalidateEntry/cssGraph.ts
18012
19159
  const importProtocols = /^(?:https?:|data:|blob:|\/)/i;
18013
19160
  const cssImportRE = /@(?:import|wv-keep-import|use|forward)\s+(?:url\()?['"]?([^'")\s]+)['"]?\)?/gi;
@@ -18741,6 +19888,13 @@ async function emitEntryOutput(options) {
18741
19888
  try {
18742
19889
  replaceLayoutDependencies(id, []);
18743
19890
  const layoutPlan = resolvedPageLayoutPlan === void 0 ? await resolvePageLayoutPlan(code, id, configService) : resolvedPageLayoutPlan ?? void 0;
19891
+ registerNativePageLayoutOutput({
19892
+ configService,
19893
+ runtimeState,
19894
+ pageId: id,
19895
+ templatePath,
19896
+ plan: layoutPlan
19897
+ });
18744
19898
  if (layoutPlan) {
18745
19899
  const layoutDependencies = /* @__PURE__ */ new Set();
18746
19900
  for (const file of await expandResolvedPageLayoutFiles(layoutPlan.layouts)) {
@@ -22310,14 +23464,18 @@ function createOutputFinalizerPlugin(ctx) {
22310
23464
  return {
22311
23465
  name: "weapp-vite:output-finalizer",
22312
23466
  enforce: "post",
22313
- generateBundle(_options, bundle) {
22314
- const outputBundle = bundle;
22315
- rewriteWevuInternalRuntimeImports(bundle, wevuRuntimeRewriteOptions);
22316
- stabilizeWevuRuntimeChunkAccess(bundle);
22317
- const assetEntries = collectOutputFinalizerAssetEntries(outputBundle);
22318
- normalizePreprocessorStyleAssetEntries(outputBundle, assetEntries.preprocessorStyleAssets, ctx.configService.outputExtensions?.wxss, (asset) => this.emitFile(asset));
22319
- normalizeTemplateAssetEntries(ctx, assetEntries.templateAssets);
22320
- pruneUnchangedDevHmrOutputs(ctx, outputBundle, wevuRuntimeRewriteOptions, { runtimeRewriteDone: true });
23467
+ generateBundle: {
23468
+ order: "post",
23469
+ handler(_options, bundle) {
23470
+ const outputBundle = bundle;
23471
+ rewriteWevuInternalRuntimeImports(bundle, wevuRuntimeRewriteOptions);
23472
+ stabilizeWevuRuntimeChunkAccess(bundle);
23473
+ restoreNativePageLayoutOutputs(ctx, outputBundle);
23474
+ const assetEntries = collectOutputFinalizerAssetEntries(outputBundle);
23475
+ normalizePreprocessorStyleAssetEntries(outputBundle, assetEntries.preprocessorStyleAssets, ctx.configService.outputExtensions?.wxss, (asset) => this.emitFile(asset));
23476
+ normalizeTemplateAssetEntries(ctx, assetEntries.templateAssets);
23477
+ pruneUnchangedDevHmrOutputs(ctx, outputBundle, wevuRuntimeRewriteOptions, { runtimeRewriteDone: true });
23478
+ }
22321
23479
  }
22322
23480
  };
22323
23481
  }
@@ -27637,6 +28795,168 @@ function parseUsingComponents(config) {
27637
28795
  }
27638
28796
  }
27639
28797
  //#endregion
28798
+ //#region src/plugins/vue/transform/plugin/transformFile/finalize.ts
28799
+ async function finalizeVueTransform(options) {
28800
+ const { ctx, pluginCtx, filename, source, autoRoutesSignature, result, compilationCache, currentStyleIndependentSignature, previousStyleSignature, dirtyEntryId, dirtyVueEntryIds, isCssImporterDirty, isPage, isApp, sourceMap, styleBlocksCache, styleRefreshTokens, scopedSlotModules, emittedScopedSlotChunks, setAppShell, readAndParseSfc, createReadAndParseSfcOptions, measureStage, measureVueHmrStage, reportTiming } = options;
28801
+ const configService = ctx.configService;
28802
+ let currentStyleBlocks = Array.isArray(result.meta?.styleBlocks) ? result.meta.styleBlocks : styleBlocksCache.get(filename);
28803
+ if (!currentStyleBlocks) currentStyleBlocks = await measureStage("preloadSfcStyles", async () => await loadStyleBlocksForStyleOnlyRefresh({
28804
+ filename,
28805
+ source,
28806
+ styleBlocksCache,
28807
+ readAndParseSfc,
28808
+ createReadAndParseSfcOptions,
28809
+ pluginCtx,
28810
+ configService
28811
+ }));
28812
+ if (currentStyleBlocks) styleBlocksCache.set(filename, currentStyleBlocks);
28813
+ if (configService.isDev && dirtyEntryId) {
28814
+ const currentStyleSignature = createSfcStyleBlocksSignature(currentStyleBlocks);
28815
+ const hmrEventId = ctx.runtimeState.build?.hmr?.profile?.eventId;
28816
+ if (hmrEventId != null && (isCssImporterDirty || currentStyleSignature && currentStyleSignature !== previousStyleSignature)) styleRefreshTokens.set(filename, hmrEventId);
28817
+ else styleRefreshTokens.delete(filename);
28818
+ dirtyVueEntryIds?.delete(dirtyEntryId);
28819
+ }
28820
+ const sfcStyleDependencies = syncVueSfcStyleDependencies(ctx, filename, currentStyleBlocks);
28821
+ for (const dependency of sfcStyleDependencies) addNormalizedWatchFile(pluginCtx, dependency);
28822
+ registerScopedSlotHostGenerics(ctx, result.scopedSlotComponents, parseUsingComponents(result.config));
28823
+ await measureVueHmrStage("finalizeCompiledResult", "vueFinalizeCompiledMs", async () => {
28824
+ await finalizeTransformCompiledResult({
28825
+ ctx,
28826
+ pluginCtx,
28827
+ filename,
28828
+ source,
28829
+ autoRoutesSignature,
28830
+ result,
28831
+ compilationCache,
28832
+ styleIndependentSignature: filename.endsWith(".vue") ? currentStyleIndependentSignature ?? resolveVueSfcStyleIndependentSignature(source, filename) : void 0,
28833
+ setAppShell,
28834
+ configService,
28835
+ isPage,
28836
+ isApp,
28837
+ sourceMap,
28838
+ scopedSlotModules,
28839
+ emittedScopedSlotChunks,
28840
+ addWatchFile: addNormalizedWatchFile,
28841
+ emitScopedSlotChunks
28842
+ });
28843
+ });
28844
+ const returnedCode = await measureVueHmrStage("finalizeCode", "vueFinalizeCodeMs", async () => finalizeTransformEntryCode({
28845
+ result,
28846
+ filename,
28847
+ styleBlocks: result.meta?.styleBlocks ?? styleBlocksCache.get(filename),
28848
+ isPage,
28849
+ isApp,
28850
+ isDev: configService.isDev,
28851
+ sourceMap,
28852
+ hmrStyleToken: configService.isDev ? styleRefreshTokens.get(filename) : void 0
28853
+ }));
28854
+ reportTiming(filename, isPage);
28855
+ return returnedCode;
28856
+ }
28857
+ //#endregion
28858
+ //#region src/plugins/vue/transform/plugin/transformFile/jsonOnly.ts
28859
+ function isVueJsonOnlyDirtyReasonSummary(dirtyReasonSummary) {
28860
+ return Boolean(dirtyReasonSummary?.length && dirtyReasonSummary.every((item) => item.startsWith("entry-json-only:")));
28861
+ }
28862
+ async function tryRefreshJsonOnlyVueCompilation(options) {
28863
+ const { cachedResult, compileOptions, dirtyEntryId, dirtyReasonSummary, filename, isDev, scanDirty, source, autoRoutesSignature, cachedAutoRoutesSignature } = options;
28864
+ if (!isDev || scanDirty || !dirtyEntryId || !cachedResult || !filename.endsWith(".vue") || cachedAutoRoutesSignature !== autoRoutesSignature || !isVueJsonOnlyDirtyReasonSummary(dirtyReasonSummary)) return;
28865
+ const refreshed = await refreshVueFileJsonConfig(source, filename, cachedResult, compileOptions);
28866
+ return refreshed ? normalizeVueTransformResult(refreshed) : void 0;
28867
+ }
28868
+ //#endregion
28869
+ //#region src/plugins/vue/transform/plugin/transformFile/reuse.ts
28870
+ async function tryReuseVueCompilation(options) {
28871
+ const { ctx, pluginCtx, filename, source, cachedCompilation, previousStyleSignature, autoRoutesSignature, dirtyEntryId, dirtyVueEntryIds, isCssImporterDirty, canAttemptStyleOnlyReuse, sourceMap, isApp, styleBlocksCache, styleRefreshTokens, readAndParseSfc, createReadAndParseSfcOptions, measureStage, measureVueHmrStage, reportTiming } = options;
28872
+ const configService = ctx.configService;
28873
+ if (configService.isDev && cachedCompilation && !ctx.runtimeState.scan.isDirty && cachedCompilation.source === source && cachedCompilation.autoRoutesSignature === autoRoutesSignature) {
28874
+ cachedCompilation.refreshToken = 0;
28875
+ const cachedResult = normalizeVueTransformResult(cachedCompilation.result);
28876
+ let cachedStyleBlocks = cachedResult.meta?.styleBlocks ?? styleBlocksCache.get(filename);
28877
+ let canReturnCachedCompilation = true;
28878
+ if (dirtyEntryId && canAttemptStyleOnlyReuse && filename.endsWith(".vue")) {
28879
+ const refreshedStyleBlocks = await measureStage("loadStyleOnlySfcStyles", async () => await loadStyleBlocksForStyleOnlyRefresh({
28880
+ filename,
28881
+ source,
28882
+ styleBlocksCache,
28883
+ force: true,
28884
+ readAndParseSfc,
28885
+ createReadAndParseSfcOptions,
28886
+ pluginCtx,
28887
+ configService
28888
+ }));
28889
+ if (!refreshStyleOnlyVueTransformResult(cachedResult, filename, refreshedStyleBlocks)) {
28890
+ cachedCompilation.styleIndependentSignature = void 0;
28891
+ canReturnCachedCompilation = false;
28892
+ } else {
28893
+ cachedStyleBlocks = refreshedStyleBlocks;
28894
+ cachedCompilation.result = cachedResult;
28895
+ const currentStyleSignature = createSfcStyleBlocksSignature(cachedStyleBlocks);
28896
+ const hmrEventId = ctx.runtimeState.build?.hmr?.profile?.eventId;
28897
+ if (hmrEventId != null && (isCssImporterDirty || currentStyleSignature && currentStyleSignature !== previousStyleSignature)) styleRefreshTokens.set(filename, hmrEventId);
28898
+ else styleRefreshTokens.delete(filename);
28899
+ }
28900
+ }
28901
+ if (!canReturnCachedCompilation) cachedCompilation.refreshToken = 1;
28902
+ else {
28903
+ const returnedCode = await measureVueHmrStage("finalizeCode", "vueFinalizeCodeMs", async () => finalizeTransformEntryCode({
28904
+ result: cachedResult,
28905
+ filename,
28906
+ styleBlocks: cachedStyleBlocks,
28907
+ isPage: cachedCompilation.isPage,
28908
+ isApp,
28909
+ isDev: configService.isDev,
28910
+ sourceMap,
28911
+ hmrStyleToken: styleRefreshTokens.get(filename)
28912
+ }));
28913
+ if (dirtyEntryId) dirtyVueEntryIds?.delete(dirtyEntryId);
28914
+ reportTiming(filename, cachedCompilation.isPage);
28915
+ return { returnedCode };
28916
+ }
28917
+ }
28918
+ const currentStyleIndependentSignature = configService.isDev && dirtyEntryId && canAttemptStyleOnlyReuse && filename.endsWith(".vue") ? resolveVueSfcStyleIndependentSignature(source, filename) : void 0;
28919
+ if (Boolean(configService.isDev && cachedCompilation && dirtyEntryId && canAttemptStyleOnlyReuse && filename.endsWith(".vue") && !ctx.runtimeState.scan.isDirty && cachedCompilation.autoRoutesSignature === autoRoutesSignature && cachedCompilation.styleIndependentSignature && currentStyleIndependentSignature && cachedCompilation.styleIndependentSignature === currentStyleIndependentSignature && cachedCompilation.source !== source) && cachedCompilation) {
28920
+ const cachedResult = normalizeVueTransformResult(cachedCompilation.result);
28921
+ const styleBlocks = await measureStage("loadStyleOnlySfcStyles", async () => await loadStyleBlocksForStyleOnlyRefresh({
28922
+ filename,
28923
+ source,
28924
+ styleBlocksCache,
28925
+ force: true,
28926
+ readAndParseSfc,
28927
+ createReadAndParseSfcOptions,
28928
+ pluginCtx,
28929
+ configService
28930
+ }));
28931
+ if (!refreshStyleOnlyVueTransformResult(cachedResult, filename, styleBlocks)) cachedCompilation.styleIndependentSignature = void 0;
28932
+ else {
28933
+ cachedCompilation.source = source;
28934
+ cachedCompilation.result = cachedResult;
28935
+ cachedCompilation.styleIndependentSignature = currentStyleIndependentSignature;
28936
+ cachedCompilation.refreshToken = 0;
28937
+ const hmrEventId = ctx.runtimeState.build?.hmr?.profile?.eventId;
28938
+ if (hmrEventId != null && (isCssImporterDirty || styleBlocks?.length)) styleRefreshTokens.set(filename, hmrEventId);
28939
+ const returnedCode = await measureVueHmrStage("finalizeCode", "vueFinalizeCodeMs", async () => finalizeTransformEntryCode({
28940
+ result: cachedResult,
28941
+ filename,
28942
+ styleBlocks,
28943
+ isPage: cachedCompilation.isPage,
28944
+ isApp,
28945
+ isDev: configService.isDev,
28946
+ sourceMap,
28947
+ hmrStyleToken: styleRefreshTokens.get(filename)
28948
+ }));
28949
+ if (dirtyEntryId) dirtyVueEntryIds?.delete(dirtyEntryId);
28950
+ reportTiming(filename, cachedCompilation.isPage);
28951
+ return {
28952
+ currentStyleIndependentSignature,
28953
+ returnedCode
28954
+ };
28955
+ }
28956
+ }
28957
+ return { currentStyleIndependentSignature };
28958
+ }
28959
+ //#endregion
27640
28960
  //#region src/plugins/vue/transform/plugin/transformFile.ts
27641
28961
  async function transformVueLikeFile(options) {
27642
28962
  const { ctx, pluginCtx, code, id, compilationCache, setAppShell, pageMatcher, setPageMatcher, scanDirtySynced, setScanDirtySynced, reExportResolutionCache, compileOptionsCache, componentMetaCache, styleBlocksCache, styleRefreshTokens, scopedSlotModules, emittedScopedSlotChunks, classStyleRuntimeWarned, readAndParseSfc, createReadAndParseSfcOptions } = options;
@@ -27695,159 +29015,120 @@ async function transformVueLikeFile(options) {
27695
29015
  const dirtyEntryId = resolveDirtyVueEntryId(dirtyVueEntryIds, filename);
27696
29016
  const isCssImporterDirty = isVueCssImporterDirtyReasonSummary(ctx.runtimeState?.build?.hmr?.profile?.dirtyReasonSummary);
27697
29017
  const canAttemptStyleOnlyReuse = isVueStyleOnlyDirtyReasonSummary(ctx.runtimeState?.build?.hmr?.profile?.dirtyReasonSummary);
27698
- if (configService.isDev && cachedCompilation && !ctx.runtimeState.scan.isDirty && cachedCompilation.source === transformedSource && cachedCompilation.autoRoutesSignature === autoRoutesSignature) {
27699
- cachedCompilation.refreshToken = 0;
27700
- const cachedResult = normalizeVueTransformResult(cachedCompilation.result);
27701
- let cachedStyleBlocks = cachedResult.meta?.styleBlocks ?? styleBlocksCache.get(filename);
27702
- let canReturnCachedCompilation = true;
27703
- if (dirtyEntryId && canAttemptStyleOnlyReuse && filename.endsWith(".vue")) {
27704
- const refreshedStyleBlocks = await measureStage("loadStyleOnlySfcStyles", async () => await loadStyleBlocksForStyleOnlyRefresh({
27705
- filename,
27706
- source: transformedSource,
27707
- styleBlocksCache,
27708
- force: true,
27709
- readAndParseSfc,
27710
- createReadAndParseSfcOptions,
27711
- pluginCtx,
27712
- configService
27713
- }));
27714
- if (!refreshStyleOnlyVueTransformResult(cachedResult, filename, refreshedStyleBlocks)) {
27715
- cachedCompilation.styleIndependentSignature = void 0;
27716
- canReturnCachedCompilation = false;
27717
- } else {
27718
- cachedStyleBlocks = refreshedStyleBlocks;
27719
- cachedCompilation.result = cachedResult;
27720
- const currentStyleSignature = createSfcStyleBlocksSignature(cachedStyleBlocks);
27721
- const hmrEventId = ctx.runtimeState.build?.hmr?.profile?.eventId;
27722
- if (hmrEventId != null && (isCssImporterDirty || currentStyleSignature && currentStyleSignature !== previousStyleSignature)) styleRefreshTokens.set(filename, hmrEventId);
27723
- else styleRefreshTokens.delete(filename);
27724
- }
27725
- }
27726
- if (!canReturnCachedCompilation) cachedCompilation.refreshToken = 1;
27727
- else {
27728
- const returnedCode = await measureVueHmrStage("finalizeCode", "vueFinalizeCodeMs", async () => finalizeTransformEntryCode({
27729
- result: cachedResult,
27730
- filename,
27731
- styleBlocks: cachedStyleBlocks,
27732
- isPage: cachedCompilation.isPage,
27733
- isApp,
27734
- isDev: configService.isDev,
27735
- sourceMap,
27736
- hmrStyleToken: styleRefreshTokens.get(filename)
27737
- }));
27738
- if (dirtyEntryId) dirtyVueEntryIds?.delete(dirtyEntryId);
27739
- reportTiming(filename, cachedCompilation.isPage);
27740
- return {
27741
- code: returnedCode.code,
27742
- map: returnedCode.map
27743
- };
27744
- }
27745
- }
27746
- const currentStyleIndependentSignature = configService.isDev && dirtyEntryId && canAttemptStyleOnlyReuse && filename.endsWith(".vue") ? resolveVueSfcStyleIndependentSignature(transformedSource, filename) : void 0;
27747
- if (Boolean(configService.isDev && cachedCompilation && dirtyEntryId && canAttemptStyleOnlyReuse && filename.endsWith(".vue") && !ctx.runtimeState.scan.isDirty && cachedCompilation.autoRoutesSignature === autoRoutesSignature && cachedCompilation.styleIndependentSignature && currentStyleIndependentSignature && cachedCompilation.styleIndependentSignature === currentStyleIndependentSignature && cachedCompilation.source !== transformedSource) && cachedCompilation) {
27748
- const cachedResult = normalizeVueTransformResult(cachedCompilation.result);
27749
- const styleBlocks = await measureStage("loadStyleOnlySfcStyles", async () => await loadStyleBlocksForStyleOnlyRefresh({
27750
- filename,
27751
- source: transformedSource,
27752
- styleBlocksCache,
27753
- force: true,
27754
- readAndParseSfc,
27755
- createReadAndParseSfcOptions,
27756
- pluginCtx,
27757
- configService
27758
- }));
27759
- if (!refreshStyleOnlyVueTransformResult(cachedResult, filename, styleBlocks)) cachedCompilation.styleIndependentSignature = void 0;
27760
- else {
27761
- cachedCompilation.source = transformedSource;
27762
- cachedCompilation.result = cachedResult;
27763
- cachedCompilation.styleIndependentSignature = currentStyleIndependentSignature;
27764
- cachedCompilation.refreshToken = 0;
27765
- const hmrEventId = ctx.runtimeState.build?.hmr?.profile?.eventId;
27766
- if (hmrEventId != null && (isCssImporterDirty || styleBlocks?.length)) styleRefreshTokens.set(filename, hmrEventId);
27767
- const returnedCode = await measureVueHmrStage("finalizeCode", "vueFinalizeCodeMs", async () => finalizeTransformEntryCode({
27768
- result: cachedResult,
27769
- filename,
27770
- styleBlocks,
27771
- isPage: cachedCompilation.isPage,
27772
- isApp,
27773
- isDev: configService.isDev,
27774
- sourceMap,
27775
- hmrStyleToken: styleRefreshTokens.get(filename)
27776
- }));
27777
- if (dirtyEntryId) dirtyVueEntryIds?.delete(dirtyEntryId);
27778
- reportTiming(filename, cachedCompilation.isPage);
27779
- return {
27780
- code: returnedCode.code,
27781
- map: returnedCode.map
27782
- };
27783
- }
27784
- }
29018
+ const reuseResult = await tryReuseVueCompilation({
29019
+ ctx,
29020
+ pluginCtx,
29021
+ filename,
29022
+ source: transformedSource,
29023
+ cachedCompilation,
29024
+ previousStyleSignature,
29025
+ autoRoutesSignature,
29026
+ dirtyEntryId,
29027
+ dirtyVueEntryIds,
29028
+ isCssImporterDirty,
29029
+ canAttemptStyleOnlyReuse,
29030
+ sourceMap,
29031
+ isApp,
29032
+ styleBlocksCache,
29033
+ styleRefreshTokens,
29034
+ readAndParseSfc,
29035
+ createReadAndParseSfcOptions,
29036
+ measureStage,
29037
+ measureVueHmrStage,
29038
+ reportTiming
29039
+ });
29040
+ if (reuseResult.returnedCode) return {
29041
+ code: reuseResult.returnedCode.code,
29042
+ map: reuseResult.returnedCode.map
29043
+ };
29044
+ const { currentStyleIndependentSignature } = reuseResult;
27785
29045
  const compileOptions = createCompileVueFileOptions(ctx, pluginCtx, filename, isPage, isApp, configService, {
27786
29046
  reExportResolutionCache,
27787
29047
  classStyleRuntimeWarned,
27788
29048
  compileOptionsCache,
27789
29049
  componentMetaCache
27790
29050
  });
27791
- const result = normalizeVueTransformResult(await measureVueHmrStage("compile", "vueCompileMs", async () => await compileTransformEntryResult({
27792
- transformedSource,
27793
- filename,
27794
- compileOptions,
27795
- compileVueFile,
27796
- compileJsxFile
27797
- })));
27798
- let currentStyleBlocks = Array.isArray(result.meta?.styleBlocks) ? result.meta.styleBlocks : styleBlocksCache.get(filename);
27799
- if (!currentStyleBlocks) currentStyleBlocks = await measureStage("preloadSfcStyles", async () => await loadStyleBlocksForStyleOnlyRefresh({
27800
- filename,
27801
- source: transformedSource,
27802
- styleBlocksCache,
27803
- readAndParseSfc,
27804
- createReadAndParseSfcOptions,
27805
- pluginCtx,
27806
- configService
27807
- }));
27808
- if (currentStyleBlocks) styleBlocksCache.set(filename, currentStyleBlocks);
27809
- if (configService.isDev && dirtyEntryId) {
27810
- const currentStyleSignature = createSfcStyleBlocksSignature(currentStyleBlocks);
27811
- const hmrEventId = ctx.runtimeState.build?.hmr?.profile?.eventId;
27812
- if (hmrEventId != null && (isCssImporterDirty || currentStyleSignature && currentStyleSignature !== previousStyleSignature)) styleRefreshTokens.set(filename, hmrEventId);
27813
- else styleRefreshTokens.delete(filename);
27814
- dirtyVueEntryIds?.delete(dirtyEntryId);
27815
- }
27816
- const sfcStyleDependencies = syncVueSfcStyleDependencies(ctx, filename, currentStyleBlocks);
27817
- for (const dependency of sfcStyleDependencies) addNormalizedWatchFile(pluginCtx, dependency);
27818
- registerScopedSlotHostGenerics(ctx, result.scopedSlotComponents, parseUsingComponents(result.config));
27819
- await measureVueHmrStage("finalizeCompiledResult", "vueFinalizeCompiledMs", async () => {
27820
- await finalizeTransformCompiledResult({
29051
+ const jsonOnlyResult = await measureVueHmrStage("refreshJsonConfig", "vueCompileMs", async () => {
29052
+ return await tryRefreshJsonOnlyVueCompilation({
29053
+ cachedResult: cachedCompilation?.result,
29054
+ compileOptions,
29055
+ dirtyEntryId,
29056
+ dirtyReasonSummary: ctx.runtimeState?.build?.hmr?.profile?.dirtyReasonSummary,
29057
+ filename,
29058
+ isDev: configService.isDev,
29059
+ scanDirty: ctx.runtimeState.scan.isDirty,
29060
+ source: transformedSource,
29061
+ autoRoutesSignature,
29062
+ cachedAutoRoutesSignature: cachedCompilation?.autoRoutesSignature
29063
+ });
29064
+ });
29065
+ if (jsonOnlyResult) {
29066
+ const returnedCode = await finalizeVueTransform({
27821
29067
  ctx,
27822
29068
  pluginCtx,
27823
29069
  filename,
27824
29070
  source: transformedSource,
27825
29071
  autoRoutesSignature,
27826
- result,
29072
+ result: jsonOnlyResult,
27827
29073
  compilationCache,
27828
- styleIndependentSignature: filename.endsWith(".vue") ? currentStyleIndependentSignature ?? resolveVueSfcStyleIndependentSignature(transformedSource, filename) : void 0,
27829
- setAppShell,
27830
- configService,
29074
+ currentStyleIndependentSignature: cachedCompilation?.styleIndependentSignature,
29075
+ previousStyleSignature,
29076
+ dirtyEntryId,
29077
+ dirtyVueEntryIds,
29078
+ isCssImporterDirty,
27831
29079
  isPage,
27832
29080
  isApp,
27833
29081
  sourceMap,
29082
+ styleBlocksCache,
29083
+ styleRefreshTokens,
27834
29084
  scopedSlotModules,
27835
29085
  emittedScopedSlotChunks,
27836
- addWatchFile: addNormalizedWatchFile,
27837
- emitScopedSlotChunks
29086
+ setAppShell,
29087
+ readAndParseSfc,
29088
+ createReadAndParseSfcOptions,
29089
+ measureStage,
29090
+ measureVueHmrStage,
29091
+ reportTiming
27838
29092
  });
27839
- });
27840
- const returnedCode = await measureVueHmrStage("finalizeCode", "vueFinalizeCodeMs", async () => finalizeTransformEntryCode({
27841
- result,
29093
+ return {
29094
+ code: returnedCode.code,
29095
+ map: returnedCode.map
29096
+ };
29097
+ }
29098
+ const result = normalizeVueTransformResult(await measureVueHmrStage("compile", "vueCompileMs", async () => await compileTransformEntryResult({
29099
+ transformedSource,
29100
+ filename,
29101
+ compileOptions,
29102
+ compileVueFile,
29103
+ compileJsxFile
29104
+ })));
29105
+ const returnedCode = await finalizeVueTransform({
29106
+ ctx,
29107
+ pluginCtx,
27842
29108
  filename,
27843
- styleBlocks: result.meta?.styleBlocks ?? styleBlocksCache.get(filename),
29109
+ source: transformedSource,
29110
+ autoRoutesSignature,
29111
+ result,
29112
+ compilationCache,
29113
+ currentStyleIndependentSignature,
29114
+ previousStyleSignature,
29115
+ dirtyEntryId,
29116
+ dirtyVueEntryIds,
29117
+ isCssImporterDirty,
27844
29118
  isPage,
27845
29119
  isApp,
27846
- isDev: configService.isDev,
27847
29120
  sourceMap,
27848
- hmrStyleToken: configService.isDev ? styleRefreshTokens.get(filename) : void 0
27849
- }));
27850
- reportTiming(filename, isPage);
29121
+ styleBlocksCache,
29122
+ styleRefreshTokens,
29123
+ scopedSlotModules,
29124
+ emittedScopedSlotChunks,
29125
+ setAppShell,
29126
+ readAndParseSfc,
29127
+ createReadAndParseSfcOptions,
29128
+ measureStage,
29129
+ measureVueHmrStage,
29130
+ reportTiming
29131
+ });
27851
29132
  return {
27852
29133
  code: returnedCode.code,
27853
29134
  map: returnedCode.map
@@ -29282,7 +30563,7 @@ async function loadAppEntry(ctx, scanState) {
29282
30563
  const { path: appEntryPath } = appEntry;
29283
30564
  let configFromVue;
29284
30565
  if (!appConfigFile && vueAppPath) {
29285
- const { extractConfigFromVue } = await import("./file-DhBNEU2N.mjs");
30566
+ const { extractConfigFromVue } = await import("./file-DYC-Rc4v.mjs");
29286
30567
  configFromVue = await extractConfigFromVue(vueAppPath);
29287
30568
  if (configFromVue) appConfigFile = vueAppPath;
29288
30569
  }