weapp-vite 7.3.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 (91) hide show
  1. package/README.md +154 -6
  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 +1918 -2089
  14. package/dist/compatibility.mjs +1 -2
  15. package/dist/{config-1J4rToMR.d.mts → config-V0L-IAJf.d.mts} +419 -39
  16. package/dist/config.d.mts +2 -2
  17. package/dist/config.mjs +1 -1
  18. package/dist/constants-DEZdcsMn.mjs +85 -0
  19. package/dist/{createContext-cqr9Y4EV.mjs → createCompilerContextInstance-DJH_P_nZ.mjs} +17602 -15886
  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 +9 -0
  24. package/dist/dashboard/vite.mjs +44 -0
  25. package/dist/dashboard-DvqF3Key.mjs +1842 -0
  26. package/dist/dashboard.d.mts +3 -0
  27. package/dist/dashboard.mjs +1 -0
  28. package/dist/dashboardViteBridge-Dy3nAD4m.mjs +299 -0
  29. package/dist/dev-fR5GiJRO.mjs +63 -0
  30. package/dist/devProvider-BGBkw28J.mjs +1050 -0
  31. package/dist/docs/README.md +154 -6
  32. package/dist/docs/ai-workflows.md +4 -0
  33. package/dist/docs/doctor.md +38 -0
  34. package/dist/docs/getting-started.md +52 -1
  35. package/dist/docs/index.md +6 -2
  36. package/dist/docs/mcp.md +94 -1
  37. package/dist/docs/testing.md +29 -2
  38. package/dist/docs/troubleshooting.md +8 -0
  39. package/dist/docs/uni-app-component-libraries.md +8 -7
  40. package/dist/docs/upload.md +226 -0
  41. package/dist/docs/vite-plugin.md +171 -0
  42. package/dist/docs/vue-sfc.md +19 -0
  43. package/dist/docs/weapp-config.md +374 -2
  44. package/dist/docs/wevu-authoring.md +10 -0
  45. package/dist/doctor-worker.d.mts +1 -0
  46. package/dist/doctor-worker.mjs +59 -0
  47. package/dist/doctor.d.mts +144 -0
  48. package/dist/doctor.mjs +848 -0
  49. package/dist/eslint.mjs +1 -2
  50. package/dist/file-DRb4eWqw.mjs +1 -0
  51. package/dist/{file-CKB0Tn8Z.mjs → file-sC3jD7Fh.mjs} +16 -93
  52. package/dist/files-BqxFIPRp.mjs +45 -0
  53. package/dist/getInstance-DiGSzBNI.mjs +28 -0
  54. package/dist/getInstance-SiE6WZRh.mjs +1 -0
  55. package/dist/index-C9HjUX5c.d.mts +741 -0
  56. package/dist/index.d.mts +10 -8
  57. package/dist/index.mjs +3 -2
  58. package/dist/json.d.mts +1 -1
  59. package/dist/json.mjs +1 -2
  60. package/dist/lifecycle-BROTlwSL.mjs +320 -0
  61. package/dist/loadConfig-C3BQhz7F.mjs +59 -0
  62. package/dist/loadConfig-VGtBF4qm.mjs +1 -0
  63. package/dist/logger-DGn5iEVN.mjs +1 -0
  64. package/dist/{mcp-BG6TliEg.mjs → mcp-Cj8Maqo6.mjs} +16 -7
  65. package/dist/mcp-D3Yh24Cj.mjs +529 -0
  66. package/dist/mcp.d.mts +6 -3
  67. package/dist/mcp.mjs +1 -2
  68. package/dist/package-7swhyLmf.mjs +91 -0
  69. package/dist/path-doV773b7.mjs +103 -0
  70. package/dist/platform-CnkySBKz.mjs +175 -0
  71. package/dist/processCleanup-B6KA30Zc.mjs +77 -0
  72. package/dist/protocol-vg8HGJ4n.mjs +138 -0
  73. package/dist/{resolvers-icNxkpcy.mjs → resolvers-Dod-euqX.mjs} +4 -1
  74. package/dist/resolvers.mjs +1 -2
  75. package/dist/runtime.mjs +1 -2
  76. package/dist/session-PskhD-nZ.mjs +390 -0
  77. package/dist/test.d.mts +1 -0
  78. package/dist/test.mjs +201 -44
  79. package/dist/types.d.mts +2 -2
  80. package/dist/upload-D4msblBf.mjs +562 -0
  81. package/dist/upload-worker.d.mts +1 -0
  82. package/dist/upload-worker.mjs +161 -0
  83. package/dist/utils-CJSCgEj6.mjs +1094 -0
  84. package/dist/vite.d.mts +9 -0
  85. package/dist/vite.mjs +270 -0
  86. package/dist/volar.d.mts +2 -2
  87. package/dist/web-apis.mjs +1 -2
  88. package/package.json +85 -37
  89. package/dist/file-CvgkbGIx.mjs +0 -2
  90. package/dist/getInstance-CZ1s63zd.mjs +0 -2
  91. 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
@@ -31,7 +45,7 @@
31
45
  - 🌐 **实验性 Web Runtime**:同一份原生 WXML/WXSS/TS 或 wevu Vue SFC 源码可通过 `-p web` 启动和构建浏览器版本
32
46
  - 🎨 **内置 Tailwind CSS**:通过 `weapp.tailwindcss` 配置 `weapp-tailwindcss` 的 core 与 generator 集成;Tailwind CSS v4 项目引入 `tailwindcss` 后可自动启用
33
47
  - 🧩 **实验性 uni-app 组件库兼容**:通过显式依赖白名单与 `WotUiResolver()` 在微信小程序和 Web 中使用 Wot UI Vue SFC
34
- - 🧰 **IDE 命令增强**:可直接透传 `weapp-ide-cli` 全量命令(`preview/upload/config/automator` 等)
48
+ - 🧰 **IDE 命令增强**:通过 `wv ide <command>` 调用 `weapp-ide-cli`;保留旧顶层上传参数并提示未来弃用,SDK 与 IDE 边界见下文
35
49
  - 🧪 **真实产物单测**:`weapp-vite/test` 提供不启动 CLI 的程序化测试构建入口,可配合 `@mpcore/test` 测试页面和组件
36
50
  - 🌍 **内置 i18n**:构建期编译 locale JSON,通过 WXS 翻译模板,并在逻辑层安全切换已构建语言
37
51
 
@@ -64,6 +78,76 @@ 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
+
97
+ ### Dashboard 嵌入 Vite DevTools
98
+
99
+ `weapp-vite/dashboard` 是 Node 端共享核心;CLI 独立工作台与 Vite DevTools 复用同一个 `DevframeDefinition` 和 `@weapp-vite/dashboard` 面板。可选适配器位于 `weapp-vite/dashboard/vite`,使用官方 `createPluginFromDevframe`,不会由普通包入口或 CLI 自动加载。
100
+
101
+ 接入方安装 `@weapp-vite/dashboard`、`@vitejs/devtools` 和 `@vitejs/devtools-kit`。当前接入按 Vite `8.3.0`、DevTools / Kit `0.7.6`、Devframe `1.1.0` 验证;Kit 是可选 peer,宿主依赖不进入小程序产物。
102
+
103
+ ```ts
104
+ import type { DevToolsConfig } from '@vitejs/devtools/config'
105
+ import type { DashboardAnalyzeSnapshot, DashboardContentRoots } from 'weapp-vite/dashboard'
106
+ import { DevTools } from '@vitejs/devtools'
107
+ import { createAnalyzeDashboardDevframe, resolveDashboardClientAssets } from 'weapp-vite/dashboard'
108
+ import { createAnalyzeDashboardPlugin } from 'weapp-vite/dashboard/vite'
109
+
110
+ export function createDashboardHost(snapshot: DashboardAnalyzeSnapshot, roots: DashboardContentRoots) {
111
+ const dashboard = createAnalyzeDashboardDevframe({
112
+ snapshot,
113
+ roots,
114
+ clientAssets: resolveDashboardClientAssets(roots.projectRoot),
115
+ })
116
+ const hostOptions: DevToolsConfig = {
117
+ builtinDevTools: false,
118
+ clientAuth: true,
119
+ allowedOrigins: [],
120
+ mcp: false,
121
+ }
122
+ return {
123
+ dashboard,
124
+ plugins: [
125
+ DevTools(hostOptions),
126
+ createAnalyzeDashboardPlugin(dashboard, { base: '/tools/weapp/' }),
127
+ ],
128
+ }
129
+ }
130
+ ```
131
+
132
+ 将返回的 `plugins` 交给 Vite 配置。调用方先完成分析及历史元数据持久化,用 `createDashboardArtifactSnapshot().capture` 收集该次分析的产物,再提交 `{ current, previous, artifacts }`。后续调用 `dashboard.update(result, artifacts, previousResult?)`;仅运行事件变化时调用 `dashboard.emitRuntimeEvents(events)`。提交后不要再修改报告或产物 Map。
133
+
134
+ 每个控制器只同时挂载到一个逻辑宿主。适配器记录成功安装的 Vite 配置身份,并仅在该配置拥有的环境关闭时释放核心。成功重启将所有权移交给新配置,旧实例和未安装的失败候选的清理都不会误释放当前控制器;替换前的资源校验失败时,旧宿主仍可查询和更新。首次 setup 失败或 SDK 安装开始后的失败会释放核心,不承诺回滚部分安装。自行使用 `dashboard.definition` 对接其他 Devframe 宿主时,调用方必须负责最终关闭和启动失败时的 `dashboard.dispose()`。核心不启动服务器,也不拥有外部宿主的认证、Origin 或 MCP 策略;共享宿主不是只读沙箱。
135
+
136
+ DevTools `0.7.6` 自身存在程序化重启边界:重复使用同一个 `DevTools()` 返回值时,旧实例关闭可能同时关闭新实例的 WebSocket;不安装 Dashboard 也能复现。应在每次重载的 Vite 配置中重新调用 `DevTools()`,不要把该 SDK 插件实例长期缓存在复用的 inline 配置里。上述重启验证使用重新创建的 SDK 宿主和保留的 Dashboard 控制器,不代表修复了上游传输问题。
137
+
138
+ 面板默认位于 `/__weapp-vite/`,自定义目录与应用 `base` 独立。前端复用宿主连接或从页面相对位置发现元数据,复制视图链接保留目录和查询参数但排除认证 fragment。适配器只在开发模式挂载,生产构建不要求可选面板资源,也不导出报告。以上入口仅用于 Node 开发 / 构建宿主,不应导入小程序 AppService。
139
+
140
+ 仓库内可通过 `apps/dashboard-ui-lab` 的 `dev:inspector` 与 `dev:inspector:host` 验证两种宿主,详见其 [实验说明](../../apps/dashboard-ui-lab/README.md)。
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
+
67
151
  ### Vue 项目
68
152
 
69
153
  ```typescript
@@ -73,10 +157,10 @@ import { defineConfig } from 'weapp-vite/config'
73
157
  export default defineConfig({
74
158
  weapp: {
75
159
  srcRoot: 'src',
160
+ wxml: { remove: { comment: true } },
76
161
  vue: {
77
162
  enable: true,
78
163
  template: {
79
- removeComments: true,
80
164
  htmlTagToWxml: true,
81
165
  htmlTagToWxmlTagClass: true,
82
166
  },
@@ -321,20 +405,61 @@ weapp-vite dev --open
321
405
  # o -> 重新打开当前 DevTools 项目
322
406
  ```
323
407
 
408
+ ## 六端构建并上传
409
+
410
+ 显式执行 `wv build --upload`,在本次构建成功并校验产物后上传,不重复构建。支持微信 `weapp`、支付宝 `alipay`、抖音 `tt`、小红书 `xhs`、京东 `jd`、百度 `swan`;只上传开发版本,不自动提审或正式上线。
411
+
412
+ ```sh
413
+ wv build --upload --dry-run
414
+ wv build --upload -p weapp
415
+
416
+ # 独立 upload 命令仍支持多个小程序目标;all 在此表示六端
417
+ wv upload --platform jd,swan
418
+ wv upload --platform all --dry-run
419
+ wv upload --platform xhs,tt --json --timeout 180
420
+
421
+ # 内置本地自动版本演练,不修改版本或锁文件
422
+ wv upload -p xhs,tt --mode test --bump patch --git-desc --dry-run
423
+ ```
424
+
425
+ 通常无需配置 `weapp.upload`:默认读取业务 `package.json.version`,说明自动生成 `项目名@版本`;默认不升版、不读取 Git、不运行 npm。需要覆盖时用 `weapp.upload` 或 CLI `--uv` / `--desc`;本地自动版本显式使用 CLI `--bump patch|minor|major` / `--git-desc`,分别与 `--uv` / `--desc` 冲突,不写入 Vite 配置。`.env.test` / `.env.production`、不同 AppID、本地自动版本与 CI 方案见[上传环境与自动版本](https://vite.weapp.dev/guide/upload/environments.html)。普通 `build`、`dev/HMR` 不上传,`preview` 不使用上传默认参数;配置文件仍正常求值。`build` 的上传专属参数必须与 `--upload` 一起使用,不支持 `--watch` 或 Web-only。
426
+
427
+ 自动元数据在首次配置求值、编译前准备一次,批量共用;升版仅处理命令根目录的应用清单,不向父目录查找。真实升版需要本机 npm,只有 Git 说明要求已有提交的 Git 仓库;不执行生命周期钩子、不 commit/tag/push。dry-run 不运行 npm、不修改版本或锁文件,直接导入 `package.json` 的构建代码仍读取原始版本。实际升版后的构建或上传失败不回滚,重试去掉 `--bump` 并复用原版本,必要时用 `--uv` / `--desc` 固定上一批元数据。
428
+
429
+ `build -p all --upload` 保持“小程序 + Web”语义,等两个后端都构建成功后只上传小程序;独立 `wv upload -p all` 才是六端逐一构建上传,首次失败停止。`--dry-run` 只构建并校验产物,不校验凭据、不调用 SDK。
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
+
433
+ 多个平台可用一份 `weapp.multiPlatform.projectConfigs` 映射集中配置 AppID,公共字段用对象展开复用,不必手工维护六份原生 JSON。构建器在代码输出目录内生成对应项目配置;原生文件方式仍可使用。完整配置见[一份配置与批量上传](https://vite.weapp.dev/guide/upload.html#batch)。
434
+
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` 替代。
436
+
437
+ ## 六端构建并预览
438
+
439
+ ```sh
440
+ wv preview -p tt --mode test
441
+ wv preview -p xhs,jd,swan --mode production
442
+ wv preview -p all --dry-run
443
+ ```
444
+
445
+ `preview` 复用上述六端构建与凭据,调用官方预览接口,不上传开发版本、不提审、不正式发布。微信返回 `.weapp-vite/preview/` 下本次生成的二维码图片;支付宝、京东返回二维码图片 URL;抖音、小红书、百度返回官方预览链接。默认 mode 为 `production`,不要求上传版本,也不接受 `--uv`、`--bump` 或 `--git-desc`。百度预览也需要 `SWAN_MIN_VERSION`。
446
+
447
+ `--dry-run` 只构建和校验产物,不调用 SDK、不生成预览结果。真实扫码权限与有效期依平台规则,详情见 [CLI 预览文档](https://vite.weapp.dev/guide/cli.html)。
448
+
324
449
  ## CLI 中调用 weapp-ide-cli
325
450
 
326
- `weapp-vite` 内置了对 `weapp-ide-cli` 的透传能力,除了 `dev/build/close/open/init/generate/analyze/npm/prepare/mcp` 等原生命令外,其它 IDE 相关命令都可以直接调用:
451
+ `weapp-vite` 内置了对 `weapp-ide-cli` 的透传能力:原生命令通常优先,其他命令仅在 IDE catalog 命中时透传。`wv upload` 默认走六端 SDK,但保留带明确旧参数的顶层微信 IDE 上传;`wv preview` 仍是 SDK 预览,不属于旧语法兼容范围。稳定的显式 `ide upload`、`ide preview` 不弃用:
327
452
 
328
453
  ```sh
329
- weapp-vite preview --project ./dist/build/mp-weixin
330
- weapp-vite upload --project ./dist/build/mp-weixin -v 1.0.0 -d "release"
454
+ weapp-vite ide preview --project ./dist/build/mp-weixin
455
+ weapp-vite ide upload --project ./dist/build/mp-weixin -v 1.0.0 -d "release"
331
456
  weapp-vite cache --clean compile
332
457
  weapp-vite cache --clean all
333
458
  weapp-vite config lang zh
334
459
  weapp-vite config set autoTrustProject true
335
460
  weapp-vite navigate pages/index/index --project ./dist/build/mp-weixin
336
461
  # 等价写法
337
- wv preview --project ./dist/build/mp-weixin
462
+ wv ide preview --project ./dist/build/mp-weixin
338
463
  wv cache --clean all
339
464
  ```
340
465
 
@@ -349,6 +474,21 @@ weapp-vite ide logs --open
349
474
  wv ide preview --project ./dist/build/mp-weixin
350
475
  ```
351
476
 
477
+ 原有顶层上传的长、短参数仍可原样执行,不额外触发 weapp-vite 构建:
478
+
479
+ ```sh
480
+ wv upload --project ./dist --version 1.2.3 --desc "release"
481
+ wv upload -p ./dist -v 1.2.3 -d "release"
482
+ ```
483
+
484
+ 新 SDK 上传使用 `wv upload -p weapp` 即可,无需 `--project`,框架按项目配置与本轮实际输出自动定位。上面 `./dist` 只是旧 IDE 工程目录示例,应包含 `project.config.json`;旧入口省略定位参数时保持透传,不会默认补 `dist`。
485
+
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]`。
487
+
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。
489
+
490
+ `wv upload --help` 查看 SDK 帮助;`wv help upload` 保留旧 IDE 帮助并提示未来弃用;`wv ide help upload` 不弃用、不警告。等号写法、选项值与 `--` 边界等完整规则见[旧上传兼容与迁移](https://vite.weapp.dev/guide/cli.html#legacy-upload)。
491
+
352
492
  ## CLI 启动 MCP
353
493
 
354
494
  `weapp-vite` 已集成 `@weapp-vite/mcp`:
@@ -442,3 +582,11 @@ const artifact = await buildTestArtifact({ cwd: process.cwd() })
442
582
  [MIT](./LICENSE)
443
583
 
444
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-cqr9Y4EV.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) {