weapp-vite 6.20.4 → 6.21.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.
- package/README.md +1 -1
- package/dist/auto-import-components/resolvers.mjs +1 -1
- package/dist/auto-routes.mjs +1 -1
- package/dist/cli.mjs +232 -18
- package/dist/{config-C810aRQQ.d.mts → config-Pi3hdn_g.d.mts} +37 -11
- package/dist/config.d.mts +1 -1
- package/dist/{createContext-DoH-W4mj.mjs → createContext-BE57_Xi7.mjs} +863 -180
- package/dist/docs/README.md +1 -1
- package/dist/docs/ai-workflows.md +4 -0
- package/dist/docs/getting-started.md +13 -2
- package/dist/docs/testing.md +15 -0
- package/dist/docs/uni-app-component-libraries.md +4 -4
- package/dist/docs/weapp-config.md +60 -4
- package/dist/{file-DnVj_L9_.mjs → file-Byldwig4.mjs} +1 -1
- package/dist/file-C-jjrMsb.mjs +2 -0
- package/dist/getInstance-yJ2CpeL9.mjs +2 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/json.d.mts +1 -1
- package/dist/mcp.d.mts +1 -1
- package/dist/{resolvers-w4g7O94W.mjs → resolvers-icNxkpcy.mjs} +2 -0
- package/dist/resolvers.mjs +1 -1
- package/dist/test.mjs +1 -1
- package/dist/types.d.mts +2 -2
- package/package.json +17 -17
- package/dist/file-BPMjkByK.mjs +0 -2
- package/dist/getInstance-BPs9XIGi.mjs +0 -2
package/README.md
CHANGED
|
@@ -47,7 +47,7 @@ export default defineConfig({
|
|
|
47
47
|
})
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
未配置 `weapp.hmr.runtime` 时,`wv dev` 会在启动时读取 `project.private.config.json.setting.compileHotReLoad`:开启时使用 `stateful-experimental`,关闭或无法确认时使用 `classic`。启动日志会以 `HMR 模式` 和 `HMR 切换` 两行显示最终模式、选择来源和切换方法。显式设置 `classic` 或 `stateful-experimental`
|
|
50
|
+
未配置 `weapp.hmr.runtime` 时,`wv dev` 会在启动时读取 `project.private.config.json.setting.compileHotReLoad`:开启时使用 `stateful-experimental`,关闭或无法确认时使用 `classic`。启动日志会以 `HMR 模式` 和 `HMR 切换` 两行显示最终模式、选择来源和切换方法。显式设置 `classic` 或 `stateful-experimental` 会覆盖自动选择,但 Skyline 例外:微信开发者工具暂不支持 Skyline 热重载,首次编译检测到任意应用或页面配置使用 `renderer: 'skyline'` 时,会显示兼容性警告、自动将项目私有配置中的 `compileHotReLoad` 设为 `false`,并强制降级到 `classic`。切回 WebView 后可按需手动重新开启热重载。修改 DevTools 设置后请重启 `wv dev`;CSS、资源、配置和不兼容更新会自动回退完整构建与当前路由重载。
|
|
51
51
|
|
|
52
52
|
> 说明:CLI 同时支持完整命令 `weapp-vite` 与简写命令 `wv`,两者等价。下面的示例默认使用 `weapp-vite`,你也可以按个人习惯替换成 `wv`。
|
|
53
53
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as TDesignResolver, i as UviewPlusResolver, n as WeuiResolver, r as VantResolver, t as WotUiResolver } from "../resolvers-
|
|
1
|
+
import { a as TDesignResolver, i as UviewPlusResolver, n as WeuiResolver, r as VantResolver, t as WotUiResolver } from "../resolvers-icNxkpcy.mjs";
|
|
2
2
|
export { TDesignResolver, UviewPlusResolver, VantResolver, WeuiResolver, WotUiResolver };
|
package/dist/auto-routes.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as getCompilerContext, v as getRouteRuntimeGlobalKeys } from "./createContext-
|
|
1
|
+
import { n as getCompilerContext, v as getRouteRuntimeGlobalKeys } from "./createContext-BE57_Xi7.mjs";
|
|
2
2
|
//#region src/auto-routes.ts
|
|
3
3
|
const ROUTE_RUNTIME_OVERRIDE_KEY = Symbol.for("weapp-vite.route-runtime");
|
|
4
4
|
function createGetter(resolver) {
|
package/dist/cli.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { C as
|
|
1
|
+
import { A as shouldPassPlatformArgToIdeOpen, C as findPreloadRuleKey, D as parseCommentJson, E as loadViteConfigFile, O as createCjsConfigLoadError, S as collectPreloadPages, T as suggestPreloadRules, _ as resolveHmrProfileJsonPath, a as formatBytes, b as checkRuntime, d as getBackendForCapability, f as resolveBackendExecution, g as SHARED_CHUNK_VIRTUAL_PREFIX, h as createSharedBuildConfig, j as isPathInside, k as getDefaultIdeProjectRoot, m as syncManagedTsconfigBootstrapFiles, p as syncProjectSupportFiles, t as createCompilerContext, w as resolvePreloadPackageIdentifier, x as getProjectConfigFileName, y as resolveWeappConfigFile } from "./createContext-BE57_Xi7.mjs";
|
|
2
2
|
import { r as logger_default, t as colors } from "./logger-mt4mSTqV.mjs";
|
|
3
|
-
import { h as VERSION } from "./file-
|
|
3
|
+
import { h as VERSION, i as findJsEntry, o as findTemplateEntry, s as findVueEntry } from "./file-Byldwig4.mjs";
|
|
4
4
|
import { c as startWeappViteMcpServer, l as detectAiDevelopmentEnvironment, s as resolveWeappMcpConfig } from "./mcp-BG6TliEg.mjs";
|
|
5
5
|
import { createRequire } from "node:module";
|
|
6
6
|
import fs from "node:fs";
|
|
@@ -8,6 +8,7 @@ import path, { posix } from "pathe";
|
|
|
8
8
|
import path$1 from "node:path";
|
|
9
9
|
import { defu } from "@weapp-core/shared";
|
|
10
10
|
import { fs as fs$1 } from "@weapp-core/shared/fs";
|
|
11
|
+
import { parse } from "vue/compiler-sfc";
|
|
11
12
|
import process from "node:process";
|
|
12
13
|
import fs$2, { mkdir, writeFile } from "node:fs/promises";
|
|
13
14
|
import { build, createServer } from "vite";
|
|
@@ -15,7 +16,7 @@ import os from "node:os";
|
|
|
15
16
|
import { execFile, spawn } from "node:child_process";
|
|
16
17
|
import { Buffer } from "node:buffer";
|
|
17
18
|
import { cac } from "cac";
|
|
18
|
-
import { RETRY_CANCEL_KEYS, RETRY_CONFIRM_KEYS, bootstrapWechatDevtoolsSettings, buildWechatIdeNpm, clearWechatIdeCache, clearWechatIdeCacheByAutomator, closeSharedMiniProgram, closeWechatIdeProject, compileWechatIdeByAutomator, connectOpenedAutomator, createSharedInputSession, createWechatIdeLoginRequiredExitError, defaultCustomConfigFilePath, detectWechatDevtoolsServicePort, dispatchWechatCliCommand, formatAutomatorLoginError, getConfig, getWechatIdeTestAccounts, getWechatIdeTicket, getWechatIdeToolInfo, isAutomatorLoginError, isWeappIdeTopLevelCommand, isWechatIdeEngineBuildEndpointMissingError, isWechatIdeLoggedIn, isWechatIdeLoginRequiredError, isWechatIdeLoginRequiredExitError, launchAutomator, parse, promptRetryKeypress, promptWechatIdeLoginRetry, quitWechatIde, refreshWechatIdeTicket, resetWechatIdeFileUtilsByHttp, resolveCliPath, resolveProjectAutomatorPort, runRetryableCommand, runWechatIdeEngineBuild, runWithSuspendedSharedInput, setWechatIdeTicket, startForwardConsole, takeScreenshot } from "weapp-ide-cli";
|
|
19
|
+
import { RETRY_CANCEL_KEYS, RETRY_CONFIRM_KEYS, bootstrapWechatDevtoolsSettings, buildWechatIdeNpm, clearWechatIdeCache, clearWechatIdeCacheByAutomator, closeSharedMiniProgram, closeWechatIdeProject, compileWechatIdeByAutomator, connectOpenedAutomator, createSharedInputSession, createWechatIdeLoginRequiredExitError, defaultCustomConfigFilePath, detectWechatDevtoolsServicePort, dispatchWechatCliCommand, formatAutomatorLoginError, getConfig, getWechatIdeTestAccounts, getWechatIdeTicket, getWechatIdeToolInfo, isAutomatorLoginError, isWeappIdeTopLevelCommand, isWechatIdeEngineBuildEndpointMissingError, isWechatIdeLoggedIn, isWechatIdeLoginRequiredError, isWechatIdeLoginRequiredExitError, launchAutomator, parse as parse$1, promptRetryKeypress, promptWechatIdeLoginRetry, quitWechatIde, refreshWechatIdeTicket, resetWechatIdeFileUtilsByHttp, resolveCliPath, resolveProjectAutomatorPort, runRetryableCommand, runWechatIdeEngineBuild, runWithSuspendedSharedInput, setWechatIdeTicket, startForwardConsole, takeScreenshot } from "weapp-ide-cli";
|
|
19
20
|
import { promisify } from "node:util";
|
|
20
21
|
import { brotliCompressSync, gzipSync } from "node:zlib";
|
|
21
22
|
import { resolveCommand } from "package-manager-detector/commands";
|
|
@@ -161,7 +162,7 @@ async function executeWechatIdeCliCommand(argv, options = {}) {
|
|
|
161
162
|
createCancelError: (error) => createWechatIdeLoginRequiredExitError(error, "cancelled"),
|
|
162
163
|
execute: async () => {
|
|
163
164
|
try {
|
|
164
|
-
await parse(argv);
|
|
165
|
+
await parse$1(argv);
|
|
165
166
|
return null;
|
|
166
167
|
} catch (error) {
|
|
167
168
|
if (isWechatIdeLoginRequiredExitError(error)) throw error;
|
|
@@ -1069,6 +1070,177 @@ async function analyzeHmrProfile(options) {
|
|
|
1069
1070
|
};
|
|
1070
1071
|
}
|
|
1071
1072
|
//#endregion
|
|
1073
|
+
//#region src/analyze/preload/budget.ts
|
|
1074
|
+
const PRELOAD_LIMIT_BYTES = 2097152;
|
|
1075
|
+
function createPackageSizeMap$1(result) {
|
|
1076
|
+
return new Map((result?.packages ?? []).map((pkg) => [pkg.id, pkg.files.reduce((total, file) => total + (file.size ?? 0), 0)]));
|
|
1077
|
+
}
|
|
1078
|
+
function getConfiguredPackages(rule, appJson) {
|
|
1079
|
+
if (!rule || typeof rule !== "object" || !("packages" in rule)) return [];
|
|
1080
|
+
const packages = rule.packages;
|
|
1081
|
+
if (!Array.isArray(packages)) return [];
|
|
1082
|
+
return packages.flatMap((item) => typeof item === "string" ? [resolvePreloadPackageIdentifier(item, appJson)] : []).filter((item) => Boolean(item));
|
|
1083
|
+
}
|
|
1084
|
+
function createPreloadBudgets(appJson, result, configuredRules, packageAnalysis) {
|
|
1085
|
+
const packageSizes = createPackageSizeMap$1(packageAnalysis);
|
|
1086
|
+
const bySourcePackage = /* @__PURE__ */ new Map();
|
|
1087
|
+
const ensureSourcePackage = (page) => {
|
|
1088
|
+
const sourcePackage = page.packageRoot ?? "__main__";
|
|
1089
|
+
let entry = bySourcePackage.get(sourcePackage);
|
|
1090
|
+
if (!entry) {
|
|
1091
|
+
entry = {
|
|
1092
|
+
sourceType: page.packageRoot ? page.independent ? "independent" : "subpackage" : "main",
|
|
1093
|
+
targets: /* @__PURE__ */ new Map()
|
|
1094
|
+
};
|
|
1095
|
+
bySourcePackage.set(sourcePackage, entry);
|
|
1096
|
+
}
|
|
1097
|
+
return entry;
|
|
1098
|
+
};
|
|
1099
|
+
for (const page of result.pages) {
|
|
1100
|
+
const configuredKey = findPreloadRuleKey(page.route, configuredRules);
|
|
1101
|
+
if (configuredKey === void 0) continue;
|
|
1102
|
+
const entry = ensureSourcePackage(page);
|
|
1103
|
+
for (const packageRoot of getConfiguredPackages(configuredRules[configuredKey], appJson)) {
|
|
1104
|
+
const target = entry.targets.get(packageRoot) ?? {
|
|
1105
|
+
configured: false,
|
|
1106
|
+
suggested: false
|
|
1107
|
+
};
|
|
1108
|
+
target.configured = true;
|
|
1109
|
+
entry.targets.set(packageRoot, target);
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
const pageByRoute = new Map(result.pages.map((page) => [page.route, page]));
|
|
1113
|
+
for (const suggestion of result.suggestions) {
|
|
1114
|
+
const page = pageByRoute.get(suggestion.page);
|
|
1115
|
+
if (!page) continue;
|
|
1116
|
+
const entry = ensureSourcePackage(page);
|
|
1117
|
+
const target = entry.targets.get(suggestion.packageRoot) ?? {
|
|
1118
|
+
configured: false,
|
|
1119
|
+
suggested: false
|
|
1120
|
+
};
|
|
1121
|
+
target.suggested = true;
|
|
1122
|
+
entry.targets.set(suggestion.packageRoot, target);
|
|
1123
|
+
}
|
|
1124
|
+
return [...bySourcePackage.entries()].map(([sourcePackage, entry]) => {
|
|
1125
|
+
const targets = [...entry.targets.entries()].map(([packageRoot, state]) => {
|
|
1126
|
+
const packageId = packageRoot === "__APP__" ? "__main__" : packageRoot;
|
|
1127
|
+
return {
|
|
1128
|
+
packageRoot,
|
|
1129
|
+
bytes: packageSizes.get(packageId),
|
|
1130
|
+
...state
|
|
1131
|
+
};
|
|
1132
|
+
}).sort((left, right) => left.packageRoot.localeCompare(right.packageRoot));
|
|
1133
|
+
const unknownPackages = targets.filter((target) => target.bytes === void 0).map((target) => target.packageRoot);
|
|
1134
|
+
const estimatedBytes = targets.reduce((total, target) => total + (target.bytes ?? 0), 0);
|
|
1135
|
+
const status = estimatedBytes > PRELOAD_LIMIT_BYTES ? "exceeded" : unknownPackages.length > 0 ? "unknown" : "ok";
|
|
1136
|
+
return {
|
|
1137
|
+
sourcePackage,
|
|
1138
|
+
sourceType: entry.sourceType,
|
|
1139
|
+
limitBytes: PRELOAD_LIMIT_BYTES,
|
|
1140
|
+
estimatedBytes,
|
|
1141
|
+
remainingBytes: unknownPackages.length === 0 ? Math.max(0, PRELOAD_LIMIT_BYTES - estimatedBytes) : void 0,
|
|
1142
|
+
status,
|
|
1143
|
+
targets,
|
|
1144
|
+
unknownPackages
|
|
1145
|
+
};
|
|
1146
|
+
}).sort((left, right) => left.sourcePackage.localeCompare(right.sourcePackage));
|
|
1147
|
+
}
|
|
1148
|
+
//#endregion
|
|
1149
|
+
//#region src/analyze/preload/index.ts
|
|
1150
|
+
async function readFileIfExists(filePath) {
|
|
1151
|
+
if (!filePath) return;
|
|
1152
|
+
try {
|
|
1153
|
+
return await fs$1.readFile(filePath, "utf8");
|
|
1154
|
+
} catch {
|
|
1155
|
+
return;
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
function splitVueSource(source, filename) {
|
|
1159
|
+
try {
|
|
1160
|
+
const { descriptor } = parse(source, { filename });
|
|
1161
|
+
return {
|
|
1162
|
+
template: descriptor.template?.content,
|
|
1163
|
+
script: [descriptor.script?.content, descriptor.scriptSetup?.content].filter((content) => Boolean(content)).join("\n")
|
|
1164
|
+
};
|
|
1165
|
+
} catch {
|
|
1166
|
+
return {
|
|
1167
|
+
template: source,
|
|
1168
|
+
script: source
|
|
1169
|
+
};
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
async function collectPageSources(ctx, route) {
|
|
1173
|
+
const base = path.resolve(ctx.configService.absoluteSrcRoot, route);
|
|
1174
|
+
const [templateEntry, scriptEntry, vueEntry] = await Promise.all([
|
|
1175
|
+
findTemplateEntry(base, ctx.configService.platform),
|
|
1176
|
+
findJsEntry(base),
|
|
1177
|
+
findVueEntry(base)
|
|
1178
|
+
]);
|
|
1179
|
+
if (vueEntry) {
|
|
1180
|
+
const source = await readFileIfExists(vueEntry);
|
|
1181
|
+
return source ? splitVueSource(source, vueEntry) : {};
|
|
1182
|
+
}
|
|
1183
|
+
const [template, script] = await Promise.all([readFileIfExists(templateEntry.path), readFileIfExists(scriptEntry.path)]);
|
|
1184
|
+
return {
|
|
1185
|
+
template,
|
|
1186
|
+
script
|
|
1187
|
+
};
|
|
1188
|
+
}
|
|
1189
|
+
function aggregateSuggestions(result, configuredRules, appJson) {
|
|
1190
|
+
const byPage = /* @__PURE__ */ new Map();
|
|
1191
|
+
for (const suggestion of result.suggestions) {
|
|
1192
|
+
const current = byPage.get(suggestion.page) ?? {
|
|
1193
|
+
page: suggestion.page,
|
|
1194
|
+
packages: [],
|
|
1195
|
+
evidence: [],
|
|
1196
|
+
alreadyConfigured: []
|
|
1197
|
+
};
|
|
1198
|
+
if (!current.packages.includes(suggestion.packageRoot)) current.packages.push(suggestion.packageRoot);
|
|
1199
|
+
current.evidence.push({
|
|
1200
|
+
target: suggestion.target,
|
|
1201
|
+
packageRoot: suggestion.packageRoot,
|
|
1202
|
+
source: suggestion.source
|
|
1203
|
+
});
|
|
1204
|
+
const configuredKey = findPreloadRuleKey(suggestion.page, configuredRules);
|
|
1205
|
+
const existingRule = configuredKey === void 0 ? void 0 : configuredRules[configuredKey];
|
|
1206
|
+
const existingPackages = existingRule && typeof existingRule === "object" && "packages" in existingRule ? existingRule.packages : void 0;
|
|
1207
|
+
if ((Array.isArray(existingPackages) ? existingPackages.flatMap((item) => typeof item === "string" ? [resolvePreloadPackageIdentifier(item, appJson)] : []) : []).includes(suggestion.packageRoot)) current.alreadyConfigured.push(suggestion.packageRoot);
|
|
1208
|
+
byPage.set(suggestion.page, current);
|
|
1209
|
+
}
|
|
1210
|
+
return [...byPage.values()].map((suggestion) => ({
|
|
1211
|
+
...suggestion,
|
|
1212
|
+
packages: suggestion.packages.sort(),
|
|
1213
|
+
alreadyConfigured: [...new Set(suggestion.alreadyConfigured)].sort(),
|
|
1214
|
+
evidence: suggestion.evidence.sort((left, right) => left.target.localeCompare(right.target))
|
|
1215
|
+
}));
|
|
1216
|
+
}
|
|
1217
|
+
async function analyzePreloadRules(ctx, options = {}) {
|
|
1218
|
+
const appJson = (await ctx.scanService.loadAppEntry()).json;
|
|
1219
|
+
const pages = collectPreloadPages(appJson);
|
|
1220
|
+
const pageSources = /* @__PURE__ */ new Map();
|
|
1221
|
+
const sourceEntries = await Promise.all(pages.map(async (page) => [page.route, await collectPageSources(ctx, page.route)]));
|
|
1222
|
+
for (const [route, source] of sourceEntries) pageSources.set(route, source);
|
|
1223
|
+
const configuredRules = appJson.preloadRule && typeof appJson.preloadRule === "object" ? appJson.preloadRule : {};
|
|
1224
|
+
const suggestions = suggestPreloadRules(appJson, pageSources);
|
|
1225
|
+
return {
|
|
1226
|
+
runtime: "mini",
|
|
1227
|
+
kind: "preload",
|
|
1228
|
+
generatedAt: (options.now ?? /* @__PURE__ */ new Date()).toISOString(),
|
|
1229
|
+
platform: ctx.configService.platform,
|
|
1230
|
+
pages: pages.map((page) => page.route),
|
|
1231
|
+
configuredRules,
|
|
1232
|
+
suggestions: aggregateSuggestions(suggestions, configuredRules, appJson),
|
|
1233
|
+
budgets: createPreloadBudgets(appJson, suggestions, configuredRules, options.packageAnalysis),
|
|
1234
|
+
uncoveredPages: suggestions.uncovered,
|
|
1235
|
+
limitations: [
|
|
1236
|
+
"仅分析静态路由字面量;动态路由、后端配置和运行时守卫不会被推断。",
|
|
1237
|
+
"建议使用分包 root 作为 packages 值;预算按触发页所属包聚合,未知体积目标仍需人工复核。",
|
|
1238
|
+
"静态跳转只能证明可达性,不能代表真实访问频率,正式启用前仍需结合业务数据确认。",
|
|
1239
|
+
"该命令只提供可审计建议,不会自动修改源码或覆盖手写的 app.json.preloadRule。"
|
|
1240
|
+
]
|
|
1241
|
+
};
|
|
1242
|
+
}
|
|
1243
|
+
//#endregion
|
|
1072
1244
|
//#region src/analyze/components/suggestions.ts
|
|
1073
1245
|
function createComponentSuggestion(usage) {
|
|
1074
1246
|
if (usage.componentPackage !== "__main__" || usage.crossPackageUsageCount === 0) return;
|
|
@@ -2469,6 +2641,23 @@ async function startAnalyzeDashboard(result, options) {
|
|
|
2469
2641
|
await waitPromise;
|
|
2470
2642
|
}
|
|
2471
2643
|
//#endregion
|
|
2644
|
+
//#region src/cli/processCleanup.ts
|
|
2645
|
+
function isSassEmbeddedChild(handle) {
|
|
2646
|
+
if (!handle || typeof handle !== "object") return false;
|
|
2647
|
+
const child = handle;
|
|
2648
|
+
const spawnfile = typeof child.spawnfile === "string" ? child.spawnfile : "";
|
|
2649
|
+
const spawnargs = Array.isArray(child.spawnargs) ? child.spawnargs : [];
|
|
2650
|
+
return Boolean("kill" in handle && "spawnfile" in handle && (spawnfile.includes("sass-embedded") || spawnfile.includes("dart-sass") && spawnargs.includes("--embedded")));
|
|
2651
|
+
}
|
|
2652
|
+
function terminateStaleSassEmbeddedProcess() {
|
|
2653
|
+
const getHandles = process._getActiveHandles;
|
|
2654
|
+
const handles = typeof getHandles === "function" ? getHandles() : void 0;
|
|
2655
|
+
if (!Array.isArray(handles)) return;
|
|
2656
|
+
for (const handle of handles) if (isSassEmbeddedChild(handle)) try {
|
|
2657
|
+
handle.kill();
|
|
2658
|
+
} catch {}
|
|
2659
|
+
}
|
|
2660
|
+
//#endregion
|
|
2472
2661
|
//#region src/cli/commands/analyze.ts
|
|
2473
2662
|
function normalizeDisplayPath(value) {
|
|
2474
2663
|
return value || ".";
|
|
@@ -2583,6 +2772,27 @@ function printWebAnalysisSummary(result) {
|
|
|
2583
2772
|
logger_default.warn(`- 未支持范围:${result.unsupportedScopes.join(";")}`);
|
|
2584
2773
|
for (const limitation of result.limitations) logger_default.warn(`- 限制:${limitation}`);
|
|
2585
2774
|
}
|
|
2775
|
+
function printPreloadAnalysisSummary(result) {
|
|
2776
|
+
logger_default.success("preloadRule 静态分析完成");
|
|
2777
|
+
if (result.suggestions.length === 0) logger_default.info("未检测到可以证明的跨分包静态跳转。");
|
|
2778
|
+
for (const suggestion of result.suggestions) {
|
|
2779
|
+
const packages = suggestion.packages.join("、");
|
|
2780
|
+
const covered = suggestion.alreadyConfigured.length > 0 ? `,已配置:${suggestion.alreadyConfigured.join("、")}` : "";
|
|
2781
|
+
logger_default.info(`- ${suggestion.page} -> ${packages}${covered}`);
|
|
2782
|
+
for (const evidence of suggestion.evidence.slice(0, 5)) logger_default.info(` - ${evidence.source}:${evidence.target}`);
|
|
2783
|
+
}
|
|
2784
|
+
if (result.uncoveredPages.length > 0) logger_default.warn(`- 未找到可扫描源码的页面:${result.uncoveredPages.join("、")}`);
|
|
2785
|
+
if (result.budgets.length > 0) {
|
|
2786
|
+
logger_default.info("预下载额度:");
|
|
2787
|
+
for (const budget of result.budgets) {
|
|
2788
|
+
const size = `${formatAnalyzeBytes(budget.estimatedBytes)} / ${formatAnalyzeBytes(budget.limitBytes)}`;
|
|
2789
|
+
const unknown = budget.unknownPackages.length > 0 ? `,未知:${budget.unknownPackages.join("、")}` : "";
|
|
2790
|
+
const status = budget.status === "exceeded" ? "超限" : budget.status === "unknown" ? "待确认" : "正常";
|
|
2791
|
+
logger_default.info(`- ${budget.sourcePackage}:${size},${status}${unknown}`);
|
|
2792
|
+
}
|
|
2793
|
+
}
|
|
2794
|
+
for (const limitation of result.limitations) logger_default.warn(`- 限制:${limitation}`);
|
|
2795
|
+
}
|
|
2586
2796
|
async function writeAnalyzeResult(result, outputOption, configService, format = "json", previousResult) {
|
|
2587
2797
|
if (!outputOption) return;
|
|
2588
2798
|
const baseDir = configService.cwd;
|
|
@@ -2703,7 +2913,7 @@ function printHmrProfileAnalysisSummary(result, configService) {
|
|
|
2703
2913
|
}
|
|
2704
2914
|
}
|
|
2705
2915
|
function registerAnalyzeCommand(cli) {
|
|
2706
|
-
cli.command("analyze [root]", "analyze 两端包体与源码映射").option("--hmr-profile [file]", `[string | boolean] 分析 HMR JSONL profile,省略值时优先读取配置,否则回退到默认路径`).option("--json", `[boolean] 输出 JSON 结果`).option("--markdown", `[boolean] 输出 Markdown 报告`).option("--report <type>", `[string] 输出指定报告类型(pr)`).option("--budget-check", `[boolean] 检查 analyze 预算,超过预算时返回非 0 退出码`).option("--output <file>", `[string] 将分析结果写入指定文件(JSON 或 Markdown)`).option("-p, --platform <platform>", `[string] target platform (weapp | web)`).option("--project-config <path>", `[string] project config path (miniprogram only)`).action(async (root, options) => {
|
|
2916
|
+
cli.command("analyze [root]", "analyze 两端包体与源码映射").option("--hmr-profile [file]", `[string | boolean] 分析 HMR JSONL profile,省略值时优先读取配置,否则回退到默认路径`).option("--json", `[boolean] 输出 JSON 结果`).option("--markdown", `[boolean] 输出 Markdown 报告`).option("--report <type>", `[string] 输出指定报告类型(pr)`).option("--budget-check", `[boolean] 检查 analyze 预算,超过预算时返回非 0 退出码`).option("--preload", `[boolean] 分析静态页面跳转、实际分包体积和 preloadRule 额度`).option("--output <file>", `[string] 将分析结果写入指定文件(JSON 或 Markdown)`).option("-p, --platform <platform>", `[string] target platform (weapp | web)`).option("--project-config <path>", `[string] project config path (miniprogram only)`).action(async (root, options) => {
|
|
2707
2917
|
filterDuplicateOptions(options);
|
|
2708
2918
|
const configFile = resolveConfigFile(options);
|
|
2709
2919
|
const outputJson = coerceBooleanOption(options.json);
|
|
@@ -2714,8 +2924,9 @@ function registerAnalyzeCommand(cli) {
|
|
|
2714
2924
|
const budgetCheck = coerceBooleanOption(options.budgetCheck);
|
|
2715
2925
|
const targets = resolveRuntimeTargets(options);
|
|
2716
2926
|
const inlineConfig = createInlineConfig(targets);
|
|
2927
|
+
let ctx;
|
|
2717
2928
|
try {
|
|
2718
|
-
|
|
2929
|
+
ctx = await createCompilerContext({
|
|
2719
2930
|
cwd: root,
|
|
2720
2931
|
mode: options.mode ?? "production",
|
|
2721
2932
|
configFile,
|
|
@@ -2743,6 +2954,15 @@ function registerAnalyzeCommand(cli) {
|
|
|
2743
2954
|
} else printHmrProfileAnalysisSummary(hmrProfileResult, ctx.configService);
|
|
2744
2955
|
return;
|
|
2745
2956
|
}
|
|
2957
|
+
if (coerceBooleanOption(options.preload)) {
|
|
2958
|
+
if (targets.kind !== "miniprogram" || ctx.configService.platform !== "weapp") throw new Error("preloadRule 分析目前仅支持微信小程序平台。");
|
|
2959
|
+
const packageAnalysis = await analyzeSubpackages(ctx);
|
|
2960
|
+
const preloadResult = await analyzePreloadRules(ctx, { packageAnalysis });
|
|
2961
|
+
const writtenPath = await writeAnalyzeResult(preloadResult, outputOption, ctx.configService);
|
|
2962
|
+
if (outputJson && !writtenPath) process.stdout.write(`${JSON.stringify(preloadResult, null, 2)}\n`);
|
|
2963
|
+
if (!outputJson && !writtenPath) printPreloadAnalysisSummary(preloadResult);
|
|
2964
|
+
return;
|
|
2965
|
+
}
|
|
2746
2966
|
if (getBackendForCapability(targets, "web", "analyze")) {
|
|
2747
2967
|
const webResult = createWebAnalyzeResult(ctx.configService, { platform: "web" });
|
|
2748
2968
|
const writtenPath = await writeAnalyzeResult(webResult, outputOption, ctx.configService);
|
|
@@ -2780,6 +3000,11 @@ function registerAnalyzeCommand(cli) {
|
|
|
2780
3000
|
} catch (error) {
|
|
2781
3001
|
logger_default.error(error);
|
|
2782
3002
|
process.exitCode = 1;
|
|
3003
|
+
} finally {
|
|
3004
|
+
if (ctx) {
|
|
3005
|
+
for (const backend of [...targets.entries].reverse()) if (backend.descriptor.capabilities.analyze) await backend.driver?.close?.(ctx);
|
|
3006
|
+
}
|
|
3007
|
+
terminateStaleSassEmbeddedProcess();
|
|
2783
3008
|
}
|
|
2784
3009
|
});
|
|
2785
3010
|
}
|
|
@@ -2881,17 +3106,6 @@ function setCommandNodeEnv(nodeEnv) {
|
|
|
2881
3106
|
}
|
|
2882
3107
|
//#endregion
|
|
2883
3108
|
//#region src/cli/commands/build.ts
|
|
2884
|
-
function isSassEmbeddedChild(handle) {
|
|
2885
|
-
return Boolean(handle && typeof handle === "object" && "kill" in handle && "spawnfile" in handle && typeof handle.spawnfile === "string" && handle.spawnfile?.includes("sass-embedded"));
|
|
2886
|
-
}
|
|
2887
|
-
function terminateStaleSassEmbeddedProcess() {
|
|
2888
|
-
const getHandles = process._getActiveHandles;
|
|
2889
|
-
const handles = typeof getHandles === "function" ? getHandles() : void 0;
|
|
2890
|
-
if (!Array.isArray(handles)) return;
|
|
2891
|
-
for (const handle of handles) if (isSassEmbeddedChild(handle)) try {
|
|
2892
|
-
handle.kill();
|
|
2893
|
-
} catch {}
|
|
2894
|
-
}
|
|
2895
3109
|
function emitDashboardEvents$1(handle, events) {
|
|
2896
3110
|
handle?.emitRuntimeEvents(events);
|
|
2897
3111
|
}
|
|
@@ -4731,7 +4945,7 @@ function resolveRunnableHotkeyDefinition(input) {
|
|
|
4731
4945
|
}
|
|
4732
4946
|
//#endregion
|
|
4733
4947
|
//#region package.json
|
|
4734
|
-
var version = "6.
|
|
4948
|
+
var version = "6.21.0";
|
|
4735
4949
|
//#endregion
|
|
4736
4950
|
//#region src/cli/devHotkeys/format.ts
|
|
4737
4951
|
const FULLWIDTH_ASCII_START = 65281;
|
|
@@ -151,29 +151,36 @@ interface SubPackage {
|
|
|
151
151
|
*/
|
|
152
152
|
inlineConfig?: Partial<InlineConfig>;
|
|
153
153
|
}
|
|
154
|
-
type
|
|
155
|
-
interface
|
|
156
|
-
/**
|
|
154
|
+
type StyleScope = 'all' | 'pages' | 'components';
|
|
155
|
+
interface StyleConfigObject {
|
|
156
|
+
/** 样式文件路径,可以是相对当前包 root、相对 `srcRoot` 或绝对路径 */
|
|
157
157
|
source: string;
|
|
158
158
|
/**
|
|
159
159
|
* @description 作用范围快捷配置
|
|
160
160
|
*/
|
|
161
|
-
scope?:
|
|
162
|
-
/** 自定义包含路径,支持传入单个 glob
|
|
161
|
+
scope?: StyleScope;
|
|
162
|
+
/** 自定义包含路径,支持传入单个 glob 或数组,默认覆盖当前包内所有文件 */
|
|
163
163
|
include?: string | string[];
|
|
164
164
|
/** 自定义排除路径,支持传入单个 glob 或数组 */
|
|
165
165
|
exclude?: string | string[];
|
|
166
|
+
/** 是否自动向命中的页面或组件样式注入 `@import`,关闭后只生成独立样式文件 */
|
|
167
|
+
inject?: boolean;
|
|
166
168
|
}
|
|
167
|
-
type
|
|
168
|
-
interface
|
|
169
|
+
type StyleConfigEntry = string | StyleConfigObject;
|
|
170
|
+
interface StyleEntry {
|
|
169
171
|
source: string;
|
|
170
172
|
absolutePath: string;
|
|
171
173
|
outputRelativePath: string;
|
|
172
174
|
inputExtension: string;
|
|
173
|
-
scope:
|
|
175
|
+
scope: StyleScope;
|
|
174
176
|
include: string[];
|
|
175
177
|
exclude: string[];
|
|
178
|
+
inject?: boolean;
|
|
176
179
|
}
|
|
180
|
+
type SubPackageStyleScope = StyleScope;
|
|
181
|
+
type SubPackageStyleConfigObject = StyleConfigObject;
|
|
182
|
+
type SubPackageStyleConfigEntry = StyleConfigEntry;
|
|
183
|
+
type SubPackageStyleEntry = StyleEntry;
|
|
177
184
|
type GenerateExtensionsOptions = Partial<{
|
|
178
185
|
js: 'js' | 'ts' | (string & {});
|
|
179
186
|
json: 'js' | 'ts' | 'json' | (string & {});
|
|
@@ -342,6 +349,10 @@ interface ChunksConfig {
|
|
|
342
349
|
sharedMode?: SharedChunkMode;
|
|
343
350
|
sharedOverrides?: SharedChunkOverride[];
|
|
344
351
|
sharedPathRoot?: string;
|
|
352
|
+
/**
|
|
353
|
+
* @description 按 srcRoot 相对路径保留匹配源码模块的独立输出边界
|
|
354
|
+
*/
|
|
355
|
+
preserveModules?: (string | RegExp)[];
|
|
345
356
|
dynamicImports?: SharedChunkDynamicImports;
|
|
346
357
|
logOptimization?: boolean;
|
|
347
358
|
forceDuplicatePatterns?: (string | RegExp)[];
|
|
@@ -562,7 +573,7 @@ interface WeappSubPackageConfig {
|
|
|
562
573
|
inlineConfig?: Partial<InlineConfig>;
|
|
563
574
|
autoImportComponents?: AutoImportComponentsOption;
|
|
564
575
|
watchSharedStyles?: boolean;
|
|
565
|
-
styles?:
|
|
576
|
+
styles?: StyleConfigEntry | StyleConfigEntry[];
|
|
566
577
|
}
|
|
567
578
|
/**
|
|
568
579
|
* @description HMR 配置
|
|
@@ -656,8 +667,17 @@ interface WeappReactConfig {
|
|
|
656
667
|
renderMode?: 'auto' | 'dynamic' | 'static';
|
|
657
668
|
devWarnings?: boolean;
|
|
658
669
|
}
|
|
670
|
+
type WeappPreloadNetwork = 'all' | 'wifi';
|
|
671
|
+
/**
|
|
672
|
+
* @description 页面进入后的分包预下载规则。
|
|
673
|
+
*/
|
|
674
|
+
interface WeappPreloadRule {
|
|
675
|
+
packages: string[];
|
|
676
|
+
network?: WeappPreloadNetwork;
|
|
677
|
+
}
|
|
659
678
|
interface WeappRouteRule {
|
|
660
679
|
appLayout?: PageLayoutMeta;
|
|
680
|
+
preload?: WeappPreloadRule;
|
|
661
681
|
}
|
|
662
682
|
type WeappRouteRules = Record<string, WeappRouteRule>;
|
|
663
683
|
//#endregion
|
|
@@ -669,7 +689,7 @@ interface SubPackageMetaValue {
|
|
|
669
689
|
entries: string[];
|
|
670
690
|
subPackage: SubPackage;
|
|
671
691
|
autoImportComponents?: AutoImportComponentsOption;
|
|
672
|
-
styleEntries?:
|
|
692
|
+
styleEntries?: StyleEntry[];
|
|
673
693
|
watchSharedStyles?: boolean;
|
|
674
694
|
}
|
|
675
695
|
/**
|
|
@@ -812,6 +832,10 @@ interface WeappViteConfig {
|
|
|
812
832
|
npm?: WeappNpmConfig;
|
|
813
833
|
generate?: GenerateOptions;
|
|
814
834
|
tsconfigPaths?: boolean | PluginOptions;
|
|
835
|
+
/**
|
|
836
|
+
* 主包共享样式入口。生成独立样式文件,并按配置注入主包与普通分包页面或组件。
|
|
837
|
+
*/
|
|
838
|
+
styles?: StyleConfigEntry | StyleConfigEntry[];
|
|
815
839
|
subPackages?: Record<string, WeappSubPackageConfig>;
|
|
816
840
|
copy?: CopyOptions;
|
|
817
841
|
web?: WeappWebConfig;
|
|
@@ -1817,6 +1841,7 @@ interface RuntimeState {
|
|
|
1817
1841
|
emittedCode: Map<string, string>;
|
|
1818
1842
|
};
|
|
1819
1843
|
scan: {
|
|
1844
|
+
mainPackageStyleEntries?: StyleEntry[];
|
|
1820
1845
|
subPackageMap: Map<string, SubPackageMetaValue>;
|
|
1821
1846
|
independentSubPackageMap: Map<string, SubPackageMetaValue>;
|
|
1822
1847
|
warnedMessages: Set<string>;
|
|
@@ -1844,6 +1869,7 @@ interface ScanService {
|
|
|
1844
1869
|
appEntry?: AppEntry;
|
|
1845
1870
|
pluginJson?: Plugin;
|
|
1846
1871
|
pluginJsonPath?: string;
|
|
1872
|
+
readonly mainPackageStyleEntries: StyleEntry[] | undefined;
|
|
1847
1873
|
subPackageMap: Map<string, SubPackageMetaValue>;
|
|
1848
1874
|
independentSubPackageMap: Map<string, SubPackageMetaValue>;
|
|
1849
1875
|
loadAppEntry: () => Promise<AppEntry>;
|
|
@@ -2033,4 +2059,4 @@ declare module 'vite' {
|
|
|
2033
2059
|
*/
|
|
2034
2060
|
declare function defineConfig<T extends UserConfigExport>(config: T): T;
|
|
2035
2061
|
//#endregion
|
|
2036
|
-
export { WeappAnalyzeBudgetConfig as $,
|
|
2062
|
+
export { WeappAnalyzeBudgetConfig as $, isWeappViteHost as $n, GenerateFilenamesOptions as $t, Ref as A, StyleScope as An, WeappReactCompilerConfig as At, BindingErrorLike as B, WeappLibFileName as Bn, WeappWevuConfig as Bt, LoadConfigOptions as C, SharedChunkDynamicImports as Cn, WeappInjectWeapiConfig as Ct, MethodDefinitions$1 as D, StyleConfigEntry as Dn, WeappNpmConfig as Dt, InlineConfig$1 as E, SharedChunkStrategy as En, WeappMcpConfig as Et, RolldownPlugin as F, SubPackageStyleScope as Fn, WeappSubPackageConfig as Ft, EntryJsonFragment as G, WeappManagedServerTsconfigConfig as Gn, BuildNpmPackageMeta as Gt, BaseEntry as H, WeappLibVueTscOptions as Hn, Alias as Ht, RolldownPluginOption as I, WeappLibComponentJson as In, WeappUniAppConfig as It, ScanComponentItem as J, WeappWebConfig as Jn, CopyOptions as Jt, PageEntry as K, WeappManagedSharedTsconfigConfig as Kn, ChunksConfig as Kt, RolldownWatchOptions as L, WeappLibConfig as Ln, WeappVueConfig as Lt, RolldownBuild as M, SubPackageStyleConfigEntry as Mn, WeappRequestRuntimeConfig as Mt, RolldownOptions as N, SubPackageStyleConfigObject as Nn, WeappRouteRule as Nt, Plugin$1 as O, StyleConfigObject as On, WeappPreloadNetwork as Ot, RolldownOutput$1 as P, SubPackageStyleEntry as Pn, WeappRouteRules as Pt, UserConfig$2 as Q, createWeappViteHostMeta as Qn, GenerateFileType as Qt, RolldownWatcher$1 as R, WeappLibDtsOptions as Rn, WeappVueTemplateConfig as Rt, CompilerContext as S, ResolvedAlias as Sn, WeappInjectRequestGlobalsTarget as St, ConfigEnv$1 as T, SharedChunkOverride as Tn, WeappInjectWebRuntimeGlobalsTarget as Tt, ComponentEntry as U, WeappManagedAppTsconfigConfig as Un, AliasOptions as Ut, AppEntry as V, WeappLibInternalDtsOptions as Vn, WeappWorkerConfig as Vt, Entry as W, WeappManagedNodeTsconfigConfig as Wn, AlipayNpmMode as Wt, ProjectConfig as X, WeappViteHostMeta as Xn, GenerateDirsOptions as Xt, WxmlDep as Y, WEAPP_VITE_HOST_NAME as Yn, DeprecatedInlineDynamicImports as Yt, SubPackageMetaValue as Z, applyWeappViteHostMeta as Zn, GenerateExtensionsOptions as Zt, definePageJson as _, NpmDependencyPattern as _n, WeappAutoRoutesIncludePattern as _t, UserConfigFnNoEnvPlain as a, GenerateTemplateFileSource as an, WeappViteRuntime as ar, WeappViteConfig as at, ChangeEvent as b, NpmStrategy as bn, WeappHmrConfig as bt, UserConfigFnPromise as c, GenerateTemplatesConfig as cn, WeappViteTargetKind as cr, EnhanceOptions as ct, Component$1 as d, JsonMergeContext as dn, getSupportedWeappViteTargetDescriptors as dr, MultiPlatformConfig as dt, GenerateOptions as en, resolveWeappViteHostMeta as er, WeappAnalyzeConfig as et, Page$1 as f, JsonMergeFunction as fn, isWebPlatform as fr, ScanWxmlOptions as ft, defineComponentJson as g, NpmBuildOptions as gn, WeappAutoRoutesInclude as gt, defineAppJson as h, MpPlatform$1 as hn, WeappAutoRoutesConfig as ht, UserConfigFnNoEnv as i, GenerateTemplateFactory as in, WeappVitePlatform as ir, WeappForwardConsoleLogLevel as it, ResolvedConfig as j, SubPackage as jn, WeappReactConfig as jt, PluginOption as k, StyleEntry as kn, WeappPreloadRule as kt, defineConfig as l, JsFormat as ln, WebPlatform as lr, EnhanceWxmlOptions as lt, Theme$1 as m, JsonMergeStrategy as mn, WeappAppPreludeMode as mt, UserConfigExport as n, GenerateTemplateContext as nn, ResolvedWeappViteTarget as nr, WeappDebugConfig as nt, UserConfigFnObject as o, GenerateTemplateInlineSource as on, WeappViteTargetDescriptor as or, AutoImportComponents as ot, Sitemap$1 as p, JsonMergeStage as pn, resolveWeappViteTarget as pr, WeappAppPreludeConfig as pt, ComponentsMap as q, WeappManagedTypeScriptConfig as qn, CopyGlobs as qt, UserConfigFn as r, GenerateTemplateEntry as rn, WEB_PLATFORM_ALIASES as rr, WeappForwardConsoleConfig as rt, UserConfigFnObjectPlain as s, GenerateTemplateScope as sn, WeappViteTargetInput as sr, AutoImportComponentsOption as st, UserConfig$1 as t, GenerateTemplate as tn, ResolveWeappViteTargetOptions as tr, WeappAnalyzeHistoryConfig as tt, App$1 as u, JsonConfig as un, getSupportedWeappVitePlatforms as ur, HandleWxmlOptions as ut, defineSitemapJson as v, NpmMainPackageConfig as vn, WeappBuildScopeConfig as vt, ComputedDefinitions$1 as w, SharedChunkMode as wn, WeappInjectWebRuntimeGlobalsConfig as wt, WeappVitePluginApi as x, NpmSubPackageConfig as xn, WeappInjectRequestGlobalsConfig as xt, defineThemeJson as y, NpmPluginPackageConfig as yn, WeappBuildScopeObjectConfig as yt, ViteDevServer$1 as z, WeappLibEntryContext as zn, WeappWebRuntimeConfig as zt };
|
package/dist/config.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { $n as
|
|
1
|
+
import { $n as isWeappViteHost, Qn as createWeappViteHostMeta, Xn as WeappViteHostMeta, Yn as WEAPP_VITE_HOST_NAME, Zn as applyWeappViteHostMeta, _ as definePageJson, a as UserConfigFnNoEnvPlain, ar as WeappViteRuntime, at as WeappViteConfig, c as UserConfigFnPromise, d as Component, er as resolveWeappViteHostMeta, f as Page, g as defineComponentJson, h as defineAppJson, i as UserConfigFnNoEnv, l as defineConfig, m as Theme, n as UserConfigExport, o as UserConfigFnObject, p as Sitemap, r as UserConfigFn, s as UserConfigFnObjectPlain, t as UserConfig, u as App, v as defineSitemapJson, y as defineThemeJson } from "./config-Pi3hdn_g.mjs";
|
|
2
2
|
export { type App, type Component, type Page, type Sitemap, type Theme, UserConfig, UserConfigExport, UserConfigFn, UserConfigFnNoEnv, UserConfigFnNoEnvPlain, UserConfigFnObject, UserConfigFnObjectPlain, UserConfigFnPromise, WEAPP_VITE_HOST_NAME, type WeappViteConfig, WeappViteHostMeta, type WeappViteRuntime, applyWeappViteHostMeta, createWeappViteHostMeta, defineAppJson, defineComponentJson, defineConfig, definePageJson, defineSitemapJson, defineThemeJson, isWeappViteHost, resolveWeappViteHostMeta };
|