weapp-vite 7.4.0 → 7.5.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.
Files changed (92) hide show
  1. package/README.md +51 -1
  2. package/bin/bootstrap.js +14 -1
  3. package/dist/adapters-CcHrsYaj.mjs +1 -0
  4. package/dist/analyze-ZJUvEdaY.mjs +248 -0
  5. package/dist/auto-import-components/resolvers.mjs +1 -2
  6. package/dist/auto-import-presets/wevu-router.mjs +1 -2
  7. package/dist/auto-import-presets/wevu.mjs +1 -2
  8. package/dist/auto-routes.mjs +2 -1
  9. package/dist/budget-BD7VqLCl.d.mts +178 -0
  10. package/dist/chunkStrategy-DRA5WpB-.mjs +1436 -0
  11. package/dist/cli-acceptance.d.mts +1 -0
  12. package/dist/cli-acceptance.mjs +21 -0
  13. package/dist/cli.mjs +1420 -1554
  14. package/dist/compatibility.mjs +1 -2
  15. package/dist/{config-Dbvj5yK7.d.mts → config-V0L-IAJf.d.mts} +87 -30
  16. package/dist/config.d.mts +2 -2
  17. package/dist/config.mjs +1 -1
  18. package/dist/{constants-WOsG3Eqd.mjs → constants-DEZdcsMn.mjs} +1 -1
  19. package/dist/{createContext-UOEgeYnA.mjs → createCompilerContextInstance-DJH_P_nZ.mjs} +31278 -32148
  20. package/dist/createContext-BqYzHhY9.mjs +12 -0
  21. package/dist/dashboard/analyze.d.mts +48 -0
  22. package/dist/dashboard/analyze.mjs +1 -0
  23. package/dist/dashboard/vite.d.mts +1 -1
  24. package/dist/dashboard-DvqF3Key.mjs +1842 -0
  25. package/dist/dashboard.d.mts +3 -2
  26. package/dist/dashboard.mjs +1 -2
  27. package/dist/dashboardViteBridge-Dy3nAD4m.mjs +299 -0
  28. package/dist/dev-fR5GiJRO.mjs +63 -0
  29. package/dist/devProvider-BGBkw28J.mjs +1050 -0
  30. package/dist/docs/README.md +51 -1
  31. package/dist/docs/ai-workflows.md +4 -0
  32. package/dist/docs/doctor.md +38 -0
  33. package/dist/docs/getting-started.md +3 -1
  34. package/dist/docs/index.md +3 -1
  35. package/dist/docs/mcp.md +94 -1
  36. package/dist/docs/testing.md +29 -2
  37. package/dist/docs/troubleshooting.md +8 -0
  38. package/dist/docs/uni-app-component-libraries.md +8 -7
  39. package/dist/docs/upload.md +40 -3
  40. package/dist/docs/vite-plugin.md +171 -0
  41. package/dist/docs/vue-sfc.md +19 -0
  42. package/dist/docs/weapp-config.md +54 -0
  43. package/dist/docs/wevu-authoring.md +10 -0
  44. package/dist/doctor-worker.d.mts +1 -0
  45. package/dist/doctor-worker.mjs +59 -0
  46. package/dist/doctor.d.mts +144 -0
  47. package/dist/doctor.mjs +848 -0
  48. package/dist/eslint.mjs +1 -2
  49. package/dist/file-DRb4eWqw.mjs +1 -0
  50. package/dist/{file-giE9UMZa.mjs → file-sC3jD7Fh.mjs} +15 -9
  51. package/dist/files-BqxFIPRp.mjs +45 -0
  52. package/dist/getInstance-DiGSzBNI.mjs +28 -0
  53. package/dist/getInstance-SiE6WZRh.mjs +1 -0
  54. package/dist/index-C9HjUX5c.d.mts +741 -0
  55. package/dist/index.d.mts +10 -8
  56. package/dist/index.mjs +3 -2
  57. package/dist/json.d.mts +1 -1
  58. package/dist/json.mjs +1 -2
  59. package/dist/lifecycle-BROTlwSL.mjs +320 -0
  60. package/dist/loadConfig-C3BQhz7F.mjs +59 -0
  61. package/dist/loadConfig-VGtBF4qm.mjs +1 -0
  62. package/dist/logger-DGn5iEVN.mjs +1 -0
  63. package/dist/{mcp-BG6TliEg.mjs → mcp-Cj8Maqo6.mjs} +16 -7
  64. package/dist/mcp-D3Yh24Cj.mjs +529 -0
  65. package/dist/mcp.d.mts +6 -3
  66. package/dist/mcp.mjs +1 -2
  67. package/dist/package-7swhyLmf.mjs +91 -0
  68. package/dist/path-doV773b7.mjs +103 -0
  69. package/dist/{platform-DTWs5QRi.mjs → platform-CnkySBKz.mjs} +1 -1
  70. package/dist/processCleanup-B6KA30Zc.mjs +77 -0
  71. package/dist/protocol-vg8HGJ4n.mjs +138 -0
  72. package/dist/{resolvers-icNxkpcy.mjs → resolvers-Dod-euqX.mjs} +4 -1
  73. package/dist/resolvers.mjs +1 -2
  74. package/dist/runtime.mjs +1 -2
  75. package/dist/session-PskhD-nZ.mjs +390 -0
  76. package/dist/test.d.mts +1 -0
  77. package/dist/test.mjs +201 -44
  78. package/dist/types.d.mts +2 -2
  79. package/dist/{upload-D0RcEWrq.mjs → upload-D4msblBf.mjs} +174 -15
  80. package/dist/upload-worker.mjs +136 -3
  81. package/dist/utils-CJSCgEj6.mjs +1094 -0
  82. package/dist/vite.d.mts +9 -0
  83. package/dist/vite.mjs +270 -0
  84. package/dist/volar.d.mts +2 -2
  85. package/dist/web-apis.mjs +1 -2
  86. package/package.json +67 -41
  87. package/dist/adapters-BwnMMIZR.mjs +0 -2
  88. package/dist/dashboard-BzaVesmQ.mjs +0 -558
  89. package/dist/file-D19nbDoN.mjs +0 -2
  90. package/dist/getInstance-CYF1vl5l.mjs +0 -2
  91. package/dist/index-DbqVupg0.d.mts +0 -246
  92. package/dist/logger-mt4mSTqV.mjs +0 -2
package/README.md CHANGED
@@ -14,6 +14,20 @@
14
14
 
15
15
  <p>&nbsp;</p>
16
16
 
17
+ ## Node.js 支持范围
18
+
19
+ 框架及编译依赖链要求 `^22.18.0 || ^24.11.0 || >=26.0.0`:Node 22 至少 22.18.0、Node 24 至少 24.11.0,或 Node 26 及以上版本;不支持 Node 20、23、25。这是 Babel 8 与必需构建依赖支持范围的交集,不能通过关闭 engines 校验恢复旧版本支持。
20
+
21
+ 升级已有项目时先升级 Node.js,再重新安装依赖。CLI 会在加载编译依赖前检查实际 Node 版本;`prepare` 也会明确拒绝不支持的环境。直接通过 Vite 或程序 API 消费时同样需要遵守包的 `engines.node`。
22
+
23
+ `create-weapp-vite` 自身依赖要求更高:Node 22 至少 22.22.2、Node 24 至少 24.15.0,或 Node 26 及以上版本。新建项目按脚手架要求选择 Node,不要将框架最低版本误认为脚手架最低版本。
24
+
25
+ 发布候选在构建环境中打包,再在独立临时消费者中以严格 engines/peer 校验安装;CI 覆盖 Linux、Windows、macOS 的 Node 22.18.0、24.11.0、26.0.0 及 22/24 当前补丁版本,验证原生和 SFC 构建、prepare 与公开类型。
26
+
27
+ ## 普通 Vite 与 Vite+
28
+
29
+ 独立项目继续使用 `wv dev/build`,不需要注册插件或安装 Vite+。采用普通 Vite / Vite+ 时,在顶层 `weapp` 配置旁注册 `weapp-vite/vite` 的 `weapp()`,使用原生 `vite dev/build` / `vp dev/build`。当前插件开放微信 TS/Vue/React 生产构建、原生 `build --watch` 与实验性 classic/stateful 开发;通过 `weapp.hmr.runtime` 选择模式,已支持普通分包、独立分包与 worker,其他高级目标仍在分阶段对齐。Vite+ 需要配套 core alias 与依赖覆盖,详见[标准插件指南](https://vite.weapp.dev/guide/vite-plugin.html)。
30
+
17
31
  ## 使用文档地址: [vite.weapp.dev](https://vite.weapp.dev)
18
32
 
19
33
  ## Features
@@ -64,6 +78,22 @@ wv build -p web
64
78
 
65
79
  `web` 是浏览器 runtime 的规范平台名,`h5` 仅作为向后兼容别名保留;未选择 Web 平台时不改变现有小程序构建。完整配置和兼容边界见 [Web 运行时配置](https://vite.weapp.dev/config/web) 与 [`@weapp-vite/web`](https://vite.weapp.dev/packages/web)。
66
80
 
81
+ ### 可选 Hub 工作台
82
+
83
+ `wv dev --ui` / `wv build --ui` 保持独立 Dashboard。安装可选面板包 `@weapp-vite/dashboard` 后,可显式启用 DevFrame 1.2 的官方 Hub,无需安装 Vite DevTools:
84
+
85
+ ```bash
86
+ wv dev --ui-host hub
87
+ wv build --ui-host hub
88
+ wv analyze --ui-host hub
89
+ ```
90
+
91
+ `--ui-host` 只接受 `standalone` 和 `hub`,并隐式启用 UI;不传 UI 参数时,`dev` / `build` 不新增服务。Hub 入口为 `/__devframes/`,Dashboard 面板仍为 `/__weapp-vite/`,共用 loopback 服务、OTP 认证、报告控制器和原生连接。Hub 提供停靠面板与内建设置,不安装终端或其他默认工具;语言设置不自动翻译自定义 Dashboard。
92
+
93
+ Dashboard dock 与 Hub 品牌使用与官网相同图案的包内 SVG 字符串,以 data URL 提供。源码入口和发布产物均无需 SVG loader、官网目录或外部图标服务。
94
+
95
+ Hub 的 `/__devframes/__mcp` 聚合端点保持关闭,但与独立模式一样发布 Dashboard scoped MCP 实例,地址为 `/__weapp-vite/__mcp`,不继承其他插件的工具或 Resources。`analyze --json`、`--markdown`、`--report` 等输出选项优先级保持不变;Hub 不是离线报告导出。完整参数见 [CLI 指南](https://vite.weapp.dev/guide/cli#可选-hub-工作台)。
96
+
67
97
  ### Dashboard 嵌入 Vite DevTools
68
98
 
69
99
  `weapp-vite/dashboard` 是 Node 端共享核心;CLI 独立工作台与 Vite DevTools 复用同一个 `DevframeDefinition` 和 `@weapp-vite/dashboard` 面板。可选适配器位于 `weapp-vite/dashboard/vite`,使用官方 `createPluginFromDevframe`,不会由普通包入口或 CLI 自动加载。
@@ -109,6 +139,15 @@ DevTools `0.7.6` 自身存在程序化重启边界:重复使用同一个 `DevT
109
139
 
110
140
  仓库内可通过 `apps/dashboard-ui-lab` 的 `dev:inspector` 与 `dev:inspector:host` 验证两种宿主,详见其 [实验说明](../../apps/dashboard-ui-lab/README.md)。
111
141
 
142
+ ### Dashboard MCP
143
+
144
+ CLI 的 standalone 与 Hub 模式均向 AI 提供摘要/预算、包与产物/模块检索、重复分析、构建比较、最近事件与受限文件片段,并提供调查列表、详情和领取/提案/开始/回报四个元数据动作。页面与工具共享报告、产物及 `weapp-vite/dashboard/analyze` 纯计算,缺失基线或测量不会假造增减。实际监听后可通过 `devframe connect` 发现 scoped 实例;MCP 校验 loopback 对端与 Origin,浏览器使用 OTP。本机模式不区分本机用户,请勿通过代理、隧道或端口转发对外发布。
145
+
146
+ 「对象检查」以真实包 → 产物 → 模块关系浏览完整报告,选择与显式筛选分离,证据/内容/变化/调查共用一个上下文区。浏览器提交绑定报告的调查,外部 Agent 回传提案后需用户明确授权;执行仍在外部,回执不能代替更新报告上的人工复验。创建、取消、授权和复验不暴露为 Agent 工具,也不提供通用 shared-state、任意文件写入或命令执行。
147
+
148
+ 旧 revision 请求与旧提案授权会被拒绝。嵌入 Vite DevTools 时仍由宿主决定是否开放 MCP;现有 `wv mcp`、REST 与微信 IDE 自动化入口保持不变。客户端配置、任务版本和领取令牌用法见 [随包 MCP 指南](docs/mcp.md#dashboard-证据查询与对象调查devframe)。
149
+
150
+
112
151
  ### Vue 项目
113
152
 
114
153
  ```typescript
@@ -377,6 +416,7 @@ wv build --upload -p weapp
377
416
  # 独立 upload 命令仍支持多个小程序目标;all 在此表示六端
378
417
  wv upload --platform jd,swan
379
418
  wv upload --platform all --dry-run
419
+ wv upload --platform xhs,tt --json --timeout 180
380
420
 
381
421
  # 内置本地自动版本演练,不修改版本或锁文件
382
422
  wv upload -p xhs,tt --mode test --bump patch --git-desc --dry-run
@@ -388,6 +428,8 @@ wv upload -p xhs,tt --mode test --bump patch --git-desc --dry-run
388
428
 
389
429
  `build -p all --upload` 保持“小程序 + Web”语义,等两个后端都构建成功后只上传小程序;独立 `wv upload -p all` 才是六端逐一构建上传,首次失败停止。`--dry-run` 只构建并校验产物,不校验凭据、不调用 SDK。
390
430
 
431
+ 独立 `upload --json` 将单个结构化报告写入 stdout,构建日志与官方进度进入 stderr;失败保留前序成功、当前错误和后续 `not-run` 条目,并以非零状态退出。`--timeout <秒>` 只限制各平台 SDK worker,不包含构建。SDK 开始后超时或中断标记远端结果未确认;终止本地进程不能取消远端任务,不自动重试。六端可选结果与进度差异见[结果、进度与本地超时](https://vite.weapp.dev/guide/upload.html#report)。这两个选项不适用于 `build --upload`、`preview` 或 IDE 上传。
432
+
391
433
  多个平台可用一份 `weapp.multiPlatform.projectConfigs` 映射集中配置 AppID,公共字段用对象展开复用,不必手工维护六份原生 JSON。构建器在代码输出目录内生成对应项目配置;原生文件方式仍可使用。完整配置见[一份配置与批量上传](https://vite.weapp.dev/guide/upload.html#batch)。
392
434
 
393
435
  官方工具按目标安装,凭据只使用环境变量,不在 `weapp.upload` 中配置。完整的项目配置、AppID、凭据获取与环境文件、上传、预览、批量操作、CI 与排障见[小程序上传与预览指南](https://vite.weapp.dev/guide/upload.html):[小红书](https://vite.weapp.dev/guide/upload/xhs.html)、[抖音](https://vite.weapp.dev/guide/upload/tt.html)、[微信](https://vite.weapp.dev/guide/upload/weapp.html)、[支付宝与淘宝边界](https://vite.weapp.dev/guide/upload/alipay.html)、[京东](https://vite.weapp.dev/guide/upload/jd.html)、[百度](https://vite.weapp.dev/guide/upload/swan.html)。本地速查见 `dist/docs/upload.md`;淘宝暂不支持,不要用 `-p alipay` 替代。
@@ -443,7 +485,7 @@ wv upload -p ./dist -v 1.2.3 -d "release"
443
485
 
444
486
  每次旧顶层调用只警告一次未来移除,不要求立即改写脚本;若只想保留 IDE 行为,改为 `wv ide upload -p ./dist -v 1.2.3 -d "release"`,该显式入口不警告。若迁移到 SDK,先在**源码项目根**安装 `miniprogram-ci`、配置 AppID、代码上传私钥与 IP 白名单,再执行 `wv build --upload -p weapp --uv 1.2.3 --desc "release"`。SDK 会重新构建、使用新凭据,不复用 IDE 登录;不要把旧 `--project` 的产物目录直接作为 `[root]`。
445
487
 
446
- `-p` 有 `--version/-v`、`--project`、`--appid`、`--ext-appid` 或 `--info-output/-i` 等旧标记时才表示 IDE 项目目录,否则表示平台,不猜测路径。旧标记与 SDK 的 `--platform`、`--uv`、`--bump`、`--git-desc`、`--dry-run`(含其 `--no-*` 形式)混用,在 IDE、编译或版本修改前报错;SDK dry-run/自动版本不适用于 IDE。`--desc` 共用,`-d` 只在旧调用中是说明,原生命令中仍是 debug。
488
+ `-p` 有 `--version/-v`、`--project`、`--appid`、`--ext-appid` 或 `--info-output/-i` 等旧标记时才表示 IDE 项目目录,否则表示平台,不猜测路径。旧标记与 SDK 的 `--platform`、`--uv`、`--bump`、`--git-desc`、`--dry-run`、`--json`、`--timeout`(含其 `--no-*` 形式)混用,在 IDE、编译或版本修改前报错;SDK 专属选项不适用于 IDE。`--desc` 共用,`-d` 只在旧调用中是说明,原生命令中仍是 debug。
447
489
 
448
490
  `wv upload --help` 查看 SDK 帮助;`wv help upload` 保留旧 IDE 帮助并提示未来弃用;`wv ide help upload` 不弃用、不警告。等号写法、选项值与 `--` 边界等完整规则见[旧上传兼容与迁移](https://vite.weapp.dev/guide/cli.html#legacy-upload)。
449
491
 
@@ -540,3 +582,11 @@ const artifact = await buildTestArtifact({ cwd: process.cwd() })
540
582
  [MIT](./LICENSE)
541
583
 
542
584
  <!-- "//------":""esbuild": "^0.21.3",", -->
585
+
586
+ ## 实验性标准 Vite 插件
587
+
588
+ `weapp-vite/vite` 导出 `weapp()`,通过 `plugins: [weapp()]` 和顶层 `weapp` 配置接入原生 `vite build` / `vp build`。当前开放微信 TS/Vue/React 生产构建、原生 build watch 与实验性 classic/stateful 开发;已支持普通分包、独立分包与 worker,其他高级目标继续分阶段对齐。配置、Vite+ alias 与未开放能力见 [标准插件指南](https://vite.weapp.dev/guide/vite-plugin)。离线说明随包发布在 `dist/docs/vite-plugin.md`。
589
+
590
+ ## AI 改动验收
591
+
592
+ 通过 `wv accept --inspect --json` 检查环境;审阅配置后运行 `wv accept --trust --json`。现有 MCP 同时提供验收启动、状态、取消和报告工具,无需模型 Key。[接入指南](https://vite.weapp.dev/guide/acceptance)。独立 `weapp-agent` CLI 同仓维护并保留原命令。
package/bin/bootstrap.js CHANGED
@@ -1,3 +1,9 @@
1
+ import { readFileSync } from 'node:fs'
2
+ // eslint-disable-next-line e18e/ban-dependencies -- 启动检查使用与发布 engines 完全相同的 npm semver 语义。
3
+ import satisfies from 'semver/functions/satisfies.js'
4
+
5
+ const { engines } = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'))
6
+
1
7
  export function isPrepareCommand(argv) {
2
8
  return Array.isArray(argv) && argv[0] === 'prepare'
3
9
  }
@@ -105,9 +111,16 @@ export function guardPrepareProcessExit(argv) {
105
111
  export async function runWeappViteCLI(options = {}) {
106
112
  const {
107
113
  argv = getGlobalProcess().argv.slice(2),
108
- importer = () => import('../dist/cli.mjs'),
114
+ nodeVersion = getGlobalProcess().versions.node,
115
+ importer = () => ['accept', 'mcp'].includes(argv[0])
116
+ ? import('../dist/cli-acceptance.mjs')
117
+ : import('../dist/cli.mjs'),
109
118
  write = message => getGlobalProcess().stderr.write(`\n WARN ${message}\n\n`),
110
119
  } = options
120
+ // 在加载 Babel 等依赖前校验同一份发布声明;prepare 的容错不能吞掉不受支持的运行时。
121
+ if (!satisfies(nodeVersion, engines.node)) {
122
+ throw new Error(`weapp-vite requires Node.js ${engines.node}; current version is ${nodeVersion}. Please upgrade Node.js before running this command.`)
123
+ }
111
124
  const restorePrepareGuard = guardPrepareProcessExit(argv)
112
125
  const restoreKnownNoiseGuard = guardKnownLocalPkgResolveNoise()
113
126
 
@@ -0,0 +1 @@
1
+ export { MINI_PROGRAM_PLATFORM_DESCRIPTORS as t } from "@weapp-core/shared";
@@ -0,0 +1,248 @@
1
+ //#region src/analyze/subpackages/artifacts/category.ts
2
+ function isRuntimeCategory(category) {
3
+ return category === "runtime" || category === "reactivity" || category === "host" || category === "helper";
4
+ }
5
+ //#endregion
6
+ //#region src/analyze/subpackages/budget.ts
7
+ const defaultBudgets = {
8
+ totalBytes: 20971520,
9
+ mainBytes: 2097152,
10
+ subPackageBytes: 2097152,
11
+ independentBytes: 2097152,
12
+ warningRatio: .85,
13
+ source: "default"
14
+ };
15
+ function createAnalyzeBudgetCheck(result) {
16
+ const budgets = result.metadata?.budgets ?? defaultBudgets;
17
+ const createItem = (options, unknown = false) => {
18
+ const ratio = options.limitBytes > 0 ? options.currentBytes / options.limitBytes : options.currentBytes > 0 ? 1 : 0;
19
+ return {
20
+ ...options,
21
+ ratio,
22
+ status: unknown ? "unknown" : ratio >= 1 ? "exceeded" : ratio >= budgets.warningRatio ? "warning" : "ok"
23
+ };
24
+ };
25
+ const files = result.packages.flatMap((pkg) => pkg.files);
26
+ const unique = new Map(files.map((file) => [file.file, file]));
27
+ const sizeUnknown = (items) => items.some((file) => typeof file.size !== "number" || !Number.isFinite(file.size) || file.size < 0);
28
+ const items = [createItem({
29
+ id: "__total__",
30
+ label: "总包",
31
+ scope: "total",
32
+ currentBytes: [...unique.values()].reduce((sum, file) => sum + (file.size ?? 0), 0),
33
+ limitBytes: budgets.totalBytes,
34
+ measurement: "file-bytes",
35
+ files: [...unique.keys()].sort()
36
+ }, sizeUnknown(files))];
37
+ for (const pkg of result.packages) {
38
+ const limitBytes = budgets.packageBytes?.[pkg.id] ?? (pkg.type === "main" ? budgets.mainBytes : pkg.type === "subPackage" ? budgets.subPackageBytes : pkg.type === "independent" ? budgets.independentBytes : void 0);
39
+ if (limitBytes === void 0) continue;
40
+ items.push(createItem({
41
+ id: pkg.id,
42
+ label: pkg.label,
43
+ scope: pkg.type,
44
+ currentBytes: pkg.files.reduce((sum, file) => sum + (file.size ?? 0), 0),
45
+ limitBytes,
46
+ measurement: "file-bytes",
47
+ files: pkg.files.map((file) => file.file).sort()
48
+ }, sizeUnknown(pkg.files)));
49
+ }
50
+ if (budgets.runtimeBytes !== void 0) {
51
+ const artifacts = result.artifacts;
52
+ items.push(createItem({
53
+ id: "__runtime__",
54
+ label: "Runtime(含混合 chunk 的文件上界)",
55
+ scope: "runtime",
56
+ currentBytes: artifacts?.runtime.upperBoundBytes ?? 0,
57
+ limitBytes: budgets.runtimeBytes,
58
+ measurement: artifacts ? "upper-bound" : "unavailable",
59
+ files: artifacts?.files.filter((file) => artifacts.runtime.unknownFiles.includes(file.file) || file.modules.some((module) => isRuntimeCategory(module.category))).map((file) => file.file) ?? files.filter((file) => file.type === "chunk" || /\.[cm]?js$/i.test(file.file)).map((file) => file.file)
60
+ }, !artifacts || artifacts.runtime.unknownFiles.length > 0));
61
+ }
62
+ return items.sort((a, b) => b.ratio - a.ratio || a.label.localeCompare(b.label));
63
+ }
64
+ //#endregion
65
+ //#region src/dashboard/analyze/comparison.ts
66
+ function createModuleComparisonKey(source, sourceType) {
67
+ const origin = sourceType === "node_modules" || sourceType === "workspace" ? "dependency" : sourceType;
68
+ const queryIndex = source.indexOf("?");
69
+ let canonicalSource = (queryIndex === -1 ? source : source.slice(0, queryIndex)).replaceAll("\\", "/").replace(/^\0/, "");
70
+ if (origin === "dependency") {
71
+ const nodeModulesIndex = canonicalSource.lastIndexOf("/node_modules/");
72
+ if (nodeModulesIndex >= 0) canonicalSource = canonicalSource.slice(nodeModulesIndex + 14);
73
+ else if (canonicalSource.startsWith("node_modules/")) canonicalSource = canonicalSource.slice(13);
74
+ else if (sourceType === "workspace") canonicalSource = (canonicalSource.match(/(?:^|\/)packages-runtime\/(wevu\/.*)$/) ?? canonicalSource.match(/(?:^|\/)(@[^/]+\/[^/]+\/dist\/.*)$/))?.[1] ?? canonicalSource;
75
+ }
76
+ return `${origin}\0${canonicalSource}`;
77
+ }
78
+ function classifyIncrementCategory(source, sourceType) {
79
+ if (source.includes("wevu") || source.includes("@weapp-vite/dashboard")) return "WeVu / runtime";
80
+ if (sourceType === "node_modules" || source.includes("node_modules")) return "第三方依赖";
81
+ if (sourceType === "workspace") return "工作区包";
82
+ if (sourceType === "plugin") return "插件生成";
83
+ if (source.endsWith(".wxss") || source.endsWith(".css") || source.endsWith(".scss")) return "样式资源";
84
+ if (source.endsWith(".wxml") || source.endsWith(".json")) return "页面结构";
85
+ return "业务源码";
86
+ }
87
+ function createChangeAdvice(category, change) {
88
+ if (change === "unmeasured") return "缺少体积测量,不能判断增长或缩小。";
89
+ if (change === "removed" || change === "decreased") return "确认体积减少符合预期,检查受影响页面与依赖边界。";
90
+ if (category === "第三方依赖") return "检查依赖边界或公共入口。";
91
+ if (category === "WeVu / runtime") return "排查组件和 API 引用边界。";
92
+ if (category === "样式资源") return "检查样式复用和生成范围。";
93
+ return change === "added" ? "确认分包归属和懒加载边界。" : "对比新增引用和共享模块。";
94
+ }
95
+ function createSizeMaps(result) {
96
+ const packages = /* @__PURE__ */ new Map();
97
+ const files = /* @__PURE__ */ new Map();
98
+ const moduleIds = /* @__PURE__ */ new Map();
99
+ let totalBytes = 0;
100
+ let unmeasuredFiles = 0;
101
+ for (const pkg of result.packages) {
102
+ let packageBytes = 0;
103
+ let packageUnmeasuredFiles = 0;
104
+ for (const file of pkg.files) {
105
+ const bytes = file.size ?? null;
106
+ if (bytes === null) packageUnmeasuredFiles += 1;
107
+ else packageBytes += bytes;
108
+ const fileKey = `file:${pkg.id}\0${file.file}`;
109
+ files.set(fileKey, {
110
+ key: fileKey,
111
+ label: file.file,
112
+ bytes,
113
+ packageId: pkg.id,
114
+ packageLabel: pkg.label,
115
+ file: file.file,
116
+ category: classifyIncrementCategory(file.source ?? file.file)
117
+ });
118
+ for (const mod of file.modules ?? []) {
119
+ const moduleBytes = mod.bytes ?? mod.originalBytes ?? null;
120
+ const existing = moduleIds.get(mod.id);
121
+ if (existing) {
122
+ existing.bytes = existing.bytes === null || moduleBytes === null ? null : Math.max(existing.bytes, moduleBytes);
123
+ continue;
124
+ }
125
+ const queryIndex = mod.source.indexOf("?");
126
+ moduleIds.set(mod.id, {
127
+ key: `module:${createModuleComparisonKey(mod.source, mod.sourceType)}`,
128
+ label: mod.source,
129
+ bytes: moduleBytes,
130
+ moduleId: mod.id,
131
+ sourceType: mod.sourceType,
132
+ packageId: pkg.id,
133
+ packageLabel: pkg.label,
134
+ file: file.file,
135
+ category: classifyIncrementCategory(queryIndex === -1 ? mod.source : mod.source.slice(0, queryIndex), mod.sourceType)
136
+ });
137
+ }
138
+ }
139
+ totalBytes += packageBytes;
140
+ unmeasuredFiles += packageUnmeasuredFiles;
141
+ const key = `package:${pkg.id}`;
142
+ packages.set(key, {
143
+ key,
144
+ label: pkg.label,
145
+ bytes: packageUnmeasuredFiles > 0 ? null : packageBytes,
146
+ packageId: pkg.id,
147
+ packageLabel: pkg.label
148
+ });
149
+ }
150
+ const modules = /* @__PURE__ */ new Map();
151
+ for (const mod of moduleIds.values()) {
152
+ const existing = modules.get(mod.key);
153
+ if (!existing) modules.set(mod.key, mod);
154
+ else if (existing.bytes === null || mod.bytes === null) existing.bytes = null;
155
+ else if (existing.bytes < mod.bytes) modules.set(mod.key, mod);
156
+ }
157
+ return {
158
+ packages,
159
+ files,
160
+ modules,
161
+ totalBytes: unmeasuredFiles > 0 ? null : totalBytes,
162
+ unmeasuredFiles
163
+ };
164
+ }
165
+ function compareSizeMaps(current, previous) {
166
+ const changes = [];
167
+ const append = (entry, currentBytes, previousBytes, change) => {
168
+ changes.push({
169
+ key: entry.key,
170
+ label: entry.label,
171
+ packageId: entry.packageId,
172
+ packageLabel: entry.packageLabel,
173
+ file: entry.file,
174
+ moduleId: entry.moduleId,
175
+ sourceType: entry.sourceType,
176
+ category: entry.category,
177
+ change,
178
+ currentBytes,
179
+ previousBytes,
180
+ deltaBytes: currentBytes === null || previousBytes === null ? null : currentBytes - previousBytes,
181
+ advice: entry.category ? createChangeAdvice(entry.category, change) : void 0
182
+ });
183
+ };
184
+ for (const [key, entry] of current) {
185
+ const old = previous.get(key);
186
+ if (!old) append(entry, entry.bytes, 0, "added");
187
+ else if (entry.bytes === null || old.bytes === null) append(entry, entry.bytes, old.bytes, "unmeasured");
188
+ else if (entry.bytes !== old.bytes) append(entry, entry.bytes, old.bytes, entry.bytes > old.bytes ? "increased" : "decreased");
189
+ }
190
+ for (const [key, entry] of previous) if (!current.has(key)) append(entry, 0, entry.bytes, "removed");
191
+ return changes.sort((a, b) => (b.deltaBytes ?? -Infinity) - (a.deltaBytes ?? -Infinity) || a.key.localeCompare(b.key));
192
+ }
193
+ /** 比较两个真实快照;模块仅按已记录的 chunk 贡献归并,缺失测量不视为零。 */
194
+ function createAnalyzeComparison(current, previous) {
195
+ const currentMaps = createSizeMaps(current);
196
+ const previousMaps = createSizeMaps(previous);
197
+ return {
198
+ currentBytes: currentMaps.totalBytes,
199
+ previousBytes: previousMaps.totalBytes,
200
+ deltaBytes: currentMaps.totalBytes === null || previousMaps.totalBytes === null ? null : currentMaps.totalBytes - previousMaps.totalBytes,
201
+ currentUnmeasuredFiles: currentMaps.unmeasuredFiles,
202
+ previousUnmeasuredFiles: previousMaps.unmeasuredFiles,
203
+ packages: compareSizeMaps(currentMaps.packages, previousMaps.packages),
204
+ files: compareSizeMaps(currentMaps.files, previousMaps.files),
205
+ modules: compareSizeMaps(currentMaps.modules, previousMaps.modules)
206
+ };
207
+ }
208
+ //#endregion
209
+ //#region src/dashboard/analyze/moduleBytes.ts
210
+ /** 取每个原始模块 ID 的最大已知贡献,缺少产物贡献时使用原始体积。 */
211
+ function createModuleByteMap(result) {
212
+ const bytes = /* @__PURE__ */ new Map();
213
+ for (const pkg of result.packages) for (const file of pkg.files) for (const mod of file.modules ?? []) bytes.set(mod.id, Math.max(bytes.get(mod.id) ?? 0, mod.bytes ?? mod.originalBytes ?? 0));
214
+ return bytes;
215
+ }
216
+ //#endregion
217
+ //#region src/dashboard/analyze/duplicates.ts
218
+ function createDuplicateAdvice(sourceType, hasIndependentPackage, estimatedSavingBytes) {
219
+ if (hasIndependentPackage) return estimatedSavingBytes > 0 ? "含独立分包,先确认隔离要求,再评估是否抽公共入口。" : "含独立分包,重复可能来自隔离边界。";
220
+ if (sourceType === "node_modules") return "依赖被多个包带入,检查引用边界或考虑主包公共入口。";
221
+ if (sourceType === "src" || sourceType === "workspace") return "共享源码跨包重复,优先抽公共模块或调整分包归属。";
222
+ if (sourceType === "plugin") return "插件生成内容跨包重复,检查插件产物输出策略。";
223
+ return "检查该模块是否需要在多个包内重复存在。";
224
+ }
225
+ /** 按原始模块 ID 统计跨包重复,节省量是估算值,不代表可安全移除的字节。 */
226
+ function createDuplicateModuleInsights(result) {
227
+ const moduleBytes = createModuleByteMap(result);
228
+ const packageTypes = new Map(result.packages.map((pkg) => [pkg.id, pkg.type]));
229
+ return result.modules.filter((module) => module.packages.length > 1).map((module) => {
230
+ const bytes = moduleBytes.get(module.id) ?? 0;
231
+ const packages = module.packages.map((pkg) => pkg.packageId);
232
+ const estimatedSavingBytes = bytes * (packages.length - 1);
233
+ const hasIndependentPackage = packages.some((id) => packageTypes.get(id) === "independent");
234
+ return {
235
+ id: module.id,
236
+ source: module.source,
237
+ sourceType: module.sourceType,
238
+ packageCount: packages.length,
239
+ bytes,
240
+ estimatedSavingBytes,
241
+ packages,
242
+ hasIndependentPackage,
243
+ advice: createDuplicateAdvice(module.sourceType, hasIndependentPackage, estimatedSavingBytes)
244
+ };
245
+ }).sort((a, b) => b.estimatedSavingBytes - a.estimatedSavingBytes || b.packageCount - a.packageCount || b.bytes - a.bytes || a.source.localeCompare(b.source) || a.id.localeCompare(b.id));
246
+ }
247
+ //#endregion
248
+ export { isRuntimeCategory as a, createAnalyzeBudgetCheck as i, createModuleByteMap as n, createAnalyzeComparison as r, createDuplicateModuleInsights as t };
@@ -1,2 +1 @@
1
- import { a as TDesignResolver, i as UviewPlusResolver, n as WeuiResolver, r as VantResolver, t as WotUiResolver } from "../resolvers-icNxkpcy.mjs";
2
- export { TDesignResolver, UviewPlusResolver, VantResolver, WeuiResolver, WotUiResolver };
1
+ export { a as TDesignResolver, i as UviewPlusResolver, r as VantResolver, n as WeuiResolver, t as WotUiResolver } from "../resolvers-Dod-euqX.mjs";
@@ -1,2 +1 @@
1
- import { t as wevuRouter } from "../wevu-router-Dg1LnBlg.mjs";
2
- export { wevuRouter as default };
1
+ export { t as default } from "../wevu-router-Dg1LnBlg.mjs";
@@ -1,2 +1 @@
1
- import { t as wevu } from "../wevu-BQWUU7br.mjs";
2
- export { wevu as default };
1
+ export { t as default } from "../wevu-BQWUU7br.mjs";
@@ -1,4 +1,5 @@
1
- import { n as getCompilerContext, y as getRouteRuntimeGlobalKeys } from "./createContext-UOEgeYnA.mjs";
1
+ import { O as getRouteRuntimeGlobalKeys } from "./createCompilerContextInstance-DJH_P_nZ.mjs";
2
+ import { t as getCompilerContext } from "./getInstance-DiGSzBNI.mjs";
2
3
  //#region src/auto-routes.ts
3
4
  const ROUTE_RUNTIME_OVERRIDE_KEY = Symbol.for("weapp-vite.route-runtime");
4
5
  function createGetter(resolver) {
@@ -0,0 +1,178 @@
1
+ import { C as GlassEaselAnalyzeResult } from "./config-V0L-IAJf.mjs";
2
+ import { RolldownOutput } from "rolldown";
3
+ //#region src/analyze/components/types.d.ts
4
+ type AnalyzeComponentSuggestionKind = 'move-to-subpackage' | 'split-or-async' | 'shared-subpackage-or-placeholder';
5
+ interface AnalyzeComponentSuggestion {
6
+ kind: AnalyzeComponentSuggestionKind;
7
+ message: string;
8
+ component: string;
9
+ componentPackage: string;
10
+ targetPackage?: string;
11
+ pagePackages: string[];
12
+ }
13
+ interface AnalyzeComponentPageUsage {
14
+ page: string;
15
+ packageId: string;
16
+ usageCount: number;
17
+ }
18
+ interface AnalyzeComponentUsage {
19
+ component: string;
20
+ componentPackage: string;
21
+ totalUsageCount: number;
22
+ pageUsageCount: number;
23
+ pages: AnalyzeComponentPageUsage[];
24
+ suggestions: AnalyzeComponentSuggestion[];
25
+ }
26
+ //#endregion
27
+ //#region src/analyze/subpackages/artifacts/types.d.ts
28
+ interface AnalyzeModuleOwner {
29
+ name: string;
30
+ version?: string;
31
+ }
32
+ type AnalyzeModuleCategory = 'runtime' | 'reactivity' | 'host' | 'helper' | 'application' | 'dependency' | 'unknown';
33
+ interface AnalyzeArtifactModule {
34
+ source: string;
35
+ package?: AnalyzeModuleOwner;
36
+ category: AnalyzeModuleCategory;
37
+ /** 打包器提供的模块长度,不保证等于最终 UTF-8 字节。 */
38
+ renderedLength?: number;
39
+ /** 按模块长度占比分摊的最终字节估算,不是独立压缩结果。 */
40
+ estimatedBytes: number;
41
+ }
42
+ interface AnalyzeArtifact {
43
+ file: string;
44
+ packageId: string;
45
+ origin: 'main' | 'independent';
46
+ type: 'chunk' | 'asset';
47
+ bytes: number;
48
+ sha256?: string;
49
+ role: 'runtime' | 'application' | 'dependency' | 'mixed' | 'unknown' | 'asset';
50
+ classification: 'module-ownership' | 'asset' | 'unavailable';
51
+ estimation: 'rendered-length-proportional';
52
+ modules: AnalyzeArtifactModule[];
53
+ runtimeEstimatedBytes: number;
54
+ unattributedBytes: number;
55
+ }
56
+ interface AnalyzeArtifactAnalysis {
57
+ files: AnalyzeArtifact[];
58
+ /** 各物理文件只计一次;不能再加上 runtime 或重复模块估算。 */
59
+ totalBytes: number;
60
+ /** 同一模块在多个物理文件中的估算总量减去最大单份,不是可保证节省量。 */
61
+ duplicateEstimatedBytes: number;
62
+ runtime: {
63
+ estimatedBytes: number;
64
+ /** 包含 runtime 模块的所有文件实际字节,包括混合 chunk 中的业务代码。 */
65
+ upperBoundBytes: number;
66
+ unknownFiles: string[];
67
+ };
68
+ }
69
+ //#endregion
70
+ //#region src/analyze/subpackages/types.d.ts
71
+ type PackageType = 'main' | 'subPackage' | 'independent' | 'virtual';
72
+ type ModuleSourceType = 'src' | 'plugin' | 'node_modules' | 'workspace';
73
+ type BuildOrigin = 'main' | 'independent';
74
+ interface AnalyzeBudgetConfig {
75
+ totalBytes: number;
76
+ mainBytes: number;
77
+ subPackageBytes: number;
78
+ independentBytes: number;
79
+ runtimeBytes?: number;
80
+ packageBytes?: Record<string, number>;
81
+ warningRatio: number;
82
+ source: 'config' | 'default';
83
+ }
84
+ interface AnalyzeHistoryMetadata {
85
+ enabled: boolean;
86
+ dir: string;
87
+ limit: number;
88
+ latestSnapshot?: string;
89
+ }
90
+ interface AnalyzeSubpackagesMetadata {
91
+ projectName?: string;
92
+ generatedAt: string;
93
+ budgets: AnalyzeBudgetConfig;
94
+ history: AnalyzeHistoryMetadata;
95
+ }
96
+ interface ModuleInFile {
97
+ id: string;
98
+ source: string;
99
+ sourceType: ModuleSourceType;
100
+ bytes?: number;
101
+ originalBytes?: number;
102
+ }
103
+ interface PackageFileEntry {
104
+ file: string;
105
+ type: 'chunk' | 'asset';
106
+ from: BuildOrigin;
107
+ size?: number;
108
+ sha256?: string;
109
+ /** 包含虚拟模块在内的打包器长度总和,用于保留无法归因的份额。 */
110
+ moduleRenderedLength?: number;
111
+ gzipSize?: number;
112
+ brotliSize?: number;
113
+ isEntry?: boolean;
114
+ imports?: string[];
115
+ dynamicImports?: string[];
116
+ modules?: ModuleInFile[];
117
+ source?: string;
118
+ sourceType?: ModuleSourceType;
119
+ }
120
+ interface PackageReport {
121
+ id: string;
122
+ label: string;
123
+ type: PackageType;
124
+ files: PackageFileEntry[];
125
+ }
126
+ interface ModuleUsage {
127
+ id: string;
128
+ source: string;
129
+ sourceType: ModuleSourceType;
130
+ packages: Array<{
131
+ packageId: string;
132
+ files: string[];
133
+ }>;
134
+ }
135
+ interface SubPackageDescriptor {
136
+ root: string;
137
+ independent: boolean;
138
+ name?: string;
139
+ }
140
+ interface AnalyzeSubpackagesResult {
141
+ schemaVersion?: 2;
142
+ build?: {
143
+ id: string;
144
+ platform: string;
145
+ mode: string;
146
+ };
147
+ artifacts?: AnalyzeArtifactAnalysis;
148
+ budgetChecks?: AnalyzeBudgetCheckItem[];
149
+ metadata?: AnalyzeSubpackagesMetadata;
150
+ packages: PackageReport[];
151
+ modules: ModuleUsage[];
152
+ subPackages: SubPackageDescriptor[];
153
+ components?: AnalyzeComponentUsage[];
154
+ glassEasel: GlassEaselAnalyzeResult;
155
+ }
156
+ //#endregion
157
+ //#region src/analyze/subpackages/budget.d.ts
158
+ interface AnalyzeBudgetCheckItem {
159
+ id: string;
160
+ label: string;
161
+ scope: 'total' | 'runtime' | PackageType;
162
+ currentBytes: number;
163
+ limitBytes: number;
164
+ ratio: number;
165
+ status: 'ok' | 'warning' | 'exceeded' | 'unknown';
166
+ measurement: 'file-bytes' | 'upper-bound' | 'unavailable';
167
+ files: string[];
168
+ }
169
+ interface AnalyzeBudgetCheckInput {
170
+ packages: AnalyzeSubpackagesResult['packages'];
171
+ artifacts?: AnalyzeSubpackagesResult['artifacts'];
172
+ metadata?: Partial<AnalyzeSubpackagesMetadata> & {
173
+ budgets: AnalyzeBudgetConfig;
174
+ };
175
+ }
176
+ declare function createAnalyzeBudgetCheck(result: AnalyzeBudgetCheckInput): AnalyzeBudgetCheckItem[];
177
+ //#endregion
178
+ export { AnalyzeSubpackagesResult as a, AnalyzeBudgetConfig as i, AnalyzeBudgetCheckItem as n, ModuleSourceType as o, createAnalyzeBudgetCheck as r, AnalyzeBudgetCheckInput as t };