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.
- package/README.md +154 -6
- package/bin/bootstrap.js +14 -1
- package/dist/adapters-CcHrsYaj.mjs +1 -0
- package/dist/analyze-ZJUvEdaY.mjs +248 -0
- package/dist/auto-import-components/resolvers.mjs +1 -2
- package/dist/auto-import-presets/wevu-router.mjs +1 -2
- package/dist/auto-import-presets/wevu.mjs +1 -2
- package/dist/auto-routes.mjs +2 -1
- package/dist/budget-BD7VqLCl.d.mts +178 -0
- package/dist/chunkStrategy-DRA5WpB-.mjs +1436 -0
- package/dist/cli-acceptance.d.mts +1 -0
- package/dist/cli-acceptance.mjs +21 -0
- package/dist/cli.mjs +1918 -2089
- package/dist/compatibility.mjs +1 -2
- package/dist/{config-1J4rToMR.d.mts → config-V0L-IAJf.d.mts} +419 -39
- package/dist/config.d.mts +2 -2
- package/dist/config.mjs +1 -1
- package/dist/constants-DEZdcsMn.mjs +85 -0
- package/dist/{createContext-cqr9Y4EV.mjs → createCompilerContextInstance-DJH_P_nZ.mjs} +17602 -15886
- package/dist/createContext-BqYzHhY9.mjs +12 -0
- package/dist/dashboard/analyze.d.mts +48 -0
- package/dist/dashboard/analyze.mjs +1 -0
- package/dist/dashboard/vite.d.mts +9 -0
- package/dist/dashboard/vite.mjs +44 -0
- package/dist/dashboard-DvqF3Key.mjs +1842 -0
- package/dist/dashboard.d.mts +3 -0
- package/dist/dashboard.mjs +1 -0
- package/dist/dashboardViteBridge-Dy3nAD4m.mjs +299 -0
- package/dist/dev-fR5GiJRO.mjs +63 -0
- package/dist/devProvider-BGBkw28J.mjs +1050 -0
- package/dist/docs/README.md +154 -6
- package/dist/docs/ai-workflows.md +4 -0
- package/dist/docs/doctor.md +38 -0
- package/dist/docs/getting-started.md +52 -1
- package/dist/docs/index.md +6 -2
- package/dist/docs/mcp.md +94 -1
- package/dist/docs/testing.md +29 -2
- package/dist/docs/troubleshooting.md +8 -0
- package/dist/docs/uni-app-component-libraries.md +8 -7
- package/dist/docs/upload.md +226 -0
- package/dist/docs/vite-plugin.md +171 -0
- package/dist/docs/vue-sfc.md +19 -0
- package/dist/docs/weapp-config.md +374 -2
- package/dist/docs/wevu-authoring.md +10 -0
- package/dist/doctor-worker.d.mts +1 -0
- package/dist/doctor-worker.mjs +59 -0
- package/dist/doctor.d.mts +144 -0
- package/dist/doctor.mjs +848 -0
- package/dist/eslint.mjs +1 -2
- package/dist/file-DRb4eWqw.mjs +1 -0
- package/dist/{file-CKB0Tn8Z.mjs → file-sC3jD7Fh.mjs} +16 -93
- package/dist/files-BqxFIPRp.mjs +45 -0
- package/dist/getInstance-DiGSzBNI.mjs +28 -0
- package/dist/getInstance-SiE6WZRh.mjs +1 -0
- package/dist/index-C9HjUX5c.d.mts +741 -0
- package/dist/index.d.mts +10 -8
- package/dist/index.mjs +3 -2
- package/dist/json.d.mts +1 -1
- package/dist/json.mjs +1 -2
- package/dist/lifecycle-BROTlwSL.mjs +320 -0
- package/dist/loadConfig-C3BQhz7F.mjs +59 -0
- package/dist/loadConfig-VGtBF4qm.mjs +1 -0
- package/dist/logger-DGn5iEVN.mjs +1 -0
- package/dist/{mcp-BG6TliEg.mjs → mcp-Cj8Maqo6.mjs} +16 -7
- package/dist/mcp-D3Yh24Cj.mjs +529 -0
- package/dist/mcp.d.mts +6 -3
- package/dist/mcp.mjs +1 -2
- package/dist/package-7swhyLmf.mjs +91 -0
- package/dist/path-doV773b7.mjs +103 -0
- package/dist/platform-CnkySBKz.mjs +175 -0
- package/dist/processCleanup-B6KA30Zc.mjs +77 -0
- package/dist/protocol-vg8HGJ4n.mjs +138 -0
- package/dist/{resolvers-icNxkpcy.mjs → resolvers-Dod-euqX.mjs} +4 -1
- package/dist/resolvers.mjs +1 -2
- package/dist/runtime.mjs +1 -2
- package/dist/session-PskhD-nZ.mjs +390 -0
- package/dist/test.d.mts +1 -0
- package/dist/test.mjs +201 -44
- package/dist/types.d.mts +2 -2
- package/dist/upload-D4msblBf.mjs +562 -0
- package/dist/upload-worker.d.mts +1 -0
- package/dist/upload-worker.mjs +161 -0
- package/dist/utils-CJSCgEj6.mjs +1094 -0
- package/dist/vite.d.mts +9 -0
- package/dist/vite.mjs +270 -0
- package/dist/volar.d.mts +2 -2
- package/dist/web-apis.mjs +1 -2
- package/package.json +85 -37
- package/dist/file-CvgkbGIx.mjs +0 -2
- package/dist/getInstance-CZ1s63zd.mjs +0 -2
- package/dist/logger-mt4mSTqV.mjs +0 -2
|
@@ -14,6 +14,12 @@ export default defineConfig({
|
|
|
14
14
|
})
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
+
## 构建语法目标
|
|
18
|
+
|
|
19
|
+
顶层 `build.target` 沿用 Vite 标准语义。若关闭 IDE 的 ES6 转 ES5 和增强编译后,真机调试上传在可选链(`?.`)处报 `Unexpected token .`,可设置 `build: { target: 'es2019' }` 并重新构建,由 Vite 降级语法。IDE 模拟器可运行不代表上传解析器支持相同语法;生成二维码也不代替目标设备上的功能验证。
|
|
20
|
+
|
|
21
|
+
`build.target` 不补齐运行时 API。完整配置边界见[构建与产物配置](https://vite.weapp.dev/config/build-and-output.html)。
|
|
22
|
+
|
|
17
23
|
## 高频配置项
|
|
18
24
|
|
|
19
25
|
### `srcRoot`
|
|
@@ -24,6 +30,32 @@ export default defineConfig({
|
|
|
24
30
|
|
|
25
31
|
适合希望用约定生成页面路由的项目。启用后要保持 pages 目录与输出约定稳定。
|
|
26
32
|
|
|
33
|
+
`autoRoutes: { extensions: ['vue', 'tsx'] }` 只选择允许后缀的页面入口,声明提取、构建与增量更新使用同一选择;未配置或空数组保持原行为。`include` 仍匹配无扩展名 base。多个允许源码沿用 `ts/js/tsx/jsx/vue` 优先级;同名模板、JSON、样式和显式业务导入不会被过滤。
|
|
34
|
+
|
|
35
|
+
### `multiPlatform.projectConfigs`
|
|
36
|
+
|
|
37
|
+
在一份配置中按 `weapp` / `alipay` / `tt` / `xhs` / `jd` / `swan` 提供原生项目字段,公共项用普通对象展开。没有显式 `targets` 时从映射键推导;完整示例见[上传速查](./upload.md#多平台与输出校验)。
|
|
38
|
+
|
|
39
|
+
各平台已知字段及嵌套设置提供智能提示;原生对象允许未知扩展字段,字符串选项允许新增取值,不需要 `as any`。独立映射推荐从 `weapp-vite/config` 导入 `MultiPlatformProjectConfigs` 并使用 `satisfies`,保留扩展字段推导。此开放能力不放宽平台名、AppID 类型和生成代码根限制。
|
|
40
|
+
|
|
41
|
+
`defineConfig` 的泛型不保证拒绝所有多余属性;需要静态检查平台名拼写时使用 `satisfies MultiPlatformProjectConfigs`,构建时仍拒绝不支持的平台。
|
|
42
|
+
|
|
43
|
+
标准项目 JSON 由打包器原生生成在代码目录内,默认 `dist/<平台>/dist/`,与 `app.json` 同级。SDK 代码根为 `.`;输入不能填写 `miniprogramRoot`、`srcMiniprogramRoot`、`smartProgramRoot`,修改目录用 `build.outDir`。这里只管理 IDE/SDK 项目配置,不代替业务 `app.json`。
|
|
44
|
+
|
|
45
|
+
不读取源码侧原生项目 JSON 或私有 JSON;缺少选中平台时直接报错,不回退到旧文件。不能同时指定 `projectConfigRoot` 或 `enabled: false`。独立插件仍使用原生文件模式;Web/组件库不生成项目 JSON。不写映射时保留原生文件模式。凭据始终走环境变量,不写入映射。
|
|
46
|
+
|
|
47
|
+
### `upload`
|
|
48
|
+
|
|
49
|
+
`weapp.upload: { version?: string; desc?: string }` 只设置显式 `wv build --upload` 和独立 `wv upload` 的默认参数,不是自动上传开关,也不支持凭据字段或 `bump`、`gitDesc`。版本优先级为 CLI `--uv` 或 `--bump` 生成值 > `weapp.upload.version` > `package.json.version`;说明优先级为 CLI `--desc` 或 `--git-desc` 生成值 > `weapp.upload.desc` > 项目名称与最终版本。值会去除首尾空白,显式空版本报错,空说明使用自动生成的说明。
|
|
50
|
+
|
|
51
|
+
普通 `build`、`dev/HMR` 不使用这组上传默认参数也不上传,`preview` 不使用该配置。配置文件本身仍会正常加载与合并,不保证其中的 JavaScript getter 延迟求值。`wv build --upload` 复用本次构建,等待所有选中的构建后端成功、产物校验通过后才调用平台工具;`wv build --upload --dry-run` 不校验凭据、不调用 SDK。
|
|
52
|
+
|
|
53
|
+
`build` 上的 `--uv`、`--desc`、`--bump`、`--git-desc`、`--dry-run` 必须与 `--upload` 一起使用;`--watch --upload`、仅 Web 的 `-p web --upload` 会报错。`build -p all --upload` 是“小程序 + Web”,两者都构建成功后只上传小程序;独立 `upload -p all` 则保持六端逐一构建上传。
|
|
54
|
+
|
|
55
|
+
默认不执行 Git 或 npm 版本操作。需要时显式使用 `wv upload -p xhs,tt --bump patch --git-desc`:`--bump patch|minor|major` 与 `--uv` 冲突,`--git-desc` 与 `--desc` 冲突,`preview` 不接受这两个选项。真实升版需要本机 npm;只有 Git 说明要求已有提交的 Git 仓库。版本只取命令根目录的应用清单,不向父目录查找;首次配置求值前准备一次,批量共用,不运行生命周期钩子、不 commit/tag/push。dry-run 不运行 npm、不修改版本或锁文件,直接导入清单的构建代码仍看到原始版本。升版后的失败不回滚,重试去掉 `--bump` 并复用同一版本。详见[内置本地自动版本](./upload.md#内置本地自动版本)。
|
|
56
|
+
|
|
57
|
+
CI 可在测试通过后显式执行 `wv build --upload -p weapp --uv 1.2.3 --desc "release"`。凭据仍通过环境变量提供;先读本地[上传与预览速查](./upload.md),完整的 AppID、私钥、支付宝 JSON 身份密钥、各端 Token、环境文件和 CI Secrets 示例见[分平台操作指南](https://vite.weapp.dev/guide/upload.html)。
|
|
58
|
+
|
|
27
59
|
### `buildScope`
|
|
28
60
|
|
|
29
61
|
用于只构建主包和指定分包。常用在大项目里只调试某几个业务分包:
|
|
@@ -136,6 +168,10 @@ const moduleExport = await import('../../packages/order/modules/price.ts')
|
|
|
136
168
|
|
|
137
169
|
适合用目录扫描自动注册组件的项目。组件重名时要先解决命名冲突,不要让自动引入规则长期处于歧义状态。
|
|
138
170
|
|
|
171
|
+
开发态下,目录扫描与文件监听使用一致的组件路径标识,Windows 路径分隔符不同不会形成两份注册记录。删除组件会移除注册;恢复文件或修改组件声明后,会重新判断是否满足注册条件。重建页面配置时,会重新计算自动生成的 `usingComponents`,移除失效的自动绑定,同时保留源码中显式声明的绑定。
|
|
172
|
+
|
|
173
|
+
派生配置变化后,增量构建也会发布新的页面 JSON,包括清空配置时的 `{}`,不依赖变更文件是否为 JSON。
|
|
174
|
+
|
|
139
175
|
### `i18n`
|
|
140
176
|
|
|
141
177
|
微信项目可以通过 `weapp.i18n` 启用由 `@weapp-vite/i18n` 提供核心语义的 locale 编译与运行时切换:
|
|
@@ -208,11 +244,17 @@ export default defineConfig({
|
|
|
208
244
|
|
|
209
245
|
provider 的状态由 provider 自己维护,host 负责插件顺序、源码所有权冲突、依赖监听和产物生命周期。`weapp.tailwindcss` 仍然是内置 Tailwind adapter 的兼容门面;UnoCSS 等实现可以独立包的形式提供同一协议。
|
|
210
246
|
|
|
247
|
+
源码转换的 `dependencies` 与该次转换内的 `context.addWatchFile(id)` 共同声明依赖;成功转换后替换该源码的依赖集合,由 Vite 的模块图传播失效。开发快照写出结束不会提前释放 controller,所属开发会话结束时只调用一次 `dispose`。状态保持 HMR 将已声明依赖的新增、修改、删除纳入冻结输入,provider 应读取 `request.sources`,不能读取后续保存的可变文件。
|
|
248
|
+
|
|
249
|
+
微信状态保持 HMR 使用可选的 `controller.prepareHmr(request)` 协作:输入提供 `revision`、`changedFiles` 与固定的 `sources` 内容视图,返回本批次的 `assets`、`transformJavaScript`、依赖信息和资源释放方法。资产路径相对于输出目录;所有 Patch 共用该批次的编译状态。宿主通过 Vite/Rolldown 提交资产后才发布补丁,并在客户端执行回报后通知 DevEngine。开启 sourcemap 时,修改代码的转换必须同时返回映射。没有批次接口的内容 provider 使用完整构建回退。
|
|
250
|
+
|
|
251
|
+
共享协议由实验包 `@weapp-vite/hmr` 提供,Tailwind 控制器委托 `@weapp-vite/tailwindcss` 和 `weapp-tailwindcss/core`。两个包均不创建 DevEngine、watcher 或直接写出产物,框架与宿主运行时仍由适配器拥有;现有配置和 `prepareHmr` 类型兼容。Taro 的实验适配保留其持久发布与应用确认两阶段,不改变 weapp-vite 在应用确认后通知 DevEngine 的语义。
|
|
252
|
+
|
|
211
253
|
### `tailwindcss`
|
|
212
254
|
|
|
213
255
|
内置的 `weapp-tailwindcss` 集成支持显式配置和 Tailwind CSS v4 自动检测。显式配置优先级最高:设置为 `false` 会完全关闭(包括自动检测),设置为 `true` 或对象会按显式选项启用。未配置时,项目解析到 Tailwind CSS v4 且 CSS 模块实际包含 `@import "tailwindcss"`(也支持 `source(...)` 等合法参数)才会自动启用;Tailwind CSS v3、未安装或未引入该模块时不会生成 Tailwind CSS。
|
|
214
256
|
|
|
215
|
-
启用后,`weapp-vite`
|
|
257
|
+
启用后,`weapp-vite` 通过 `weapp-tailwindcss/core` compiler 处理 WXSS、WXML 和 JavaScript,通过 `compiler.generate()` 生成 Tailwind CSS,并将结果写入正常的样式产物。WXSS 最终化由 core 统一完成,Tailwind 构建阶段的 `@plugin`、`@source` 等指令不会泄漏到小程序产物:
|
|
216
258
|
|
|
217
259
|
```ts
|
|
218
260
|
import { defineConfig } from 'weapp-vite/config'
|
|
@@ -260,6 +302,12 @@ export default defineConfig({
|
|
|
260
302
|
|
|
261
303
|
微信构建会把 `preload` 合成为 `app.json.preloadRule`;手写的同一路由规则优先,其他平台不会生成微信专属字段。多条 glob 命中时选择具体程度最高的一条。需要检查静态跨分包跳转时,运行 `wv analyze --preload`;它只输出建议,不修改源码,并按触发页所属包汇总实际分包体积与共享的 2 MB 额度。
|
|
262
304
|
|
|
305
|
+
### `wevu.preset`
|
|
306
|
+
|
|
307
|
+
`weapp.wevu.preset: 'performance'` 默认开启 patch、隐藏时暂停、`setData.diagnostics: 'fallback'`、开发态高频告警和自动 `setData.pick`。`weapp.wevu.defaults` 的同名字段优先;内建诊断没有 `devOnly` 限制,可显式设为 `'off'`。
|
|
308
|
+
|
|
309
|
+
首次快照收集也可能记录 `needsFullSnapshot`;阶段日志不等于独立回退或物理调用。配置覆盖与计数边界见 [`wevu-authoring.md`](./wevu-authoring.md)。
|
|
310
|
+
|
|
263
311
|
### `vue.template.htmlTagToWxml`
|
|
264
312
|
|
|
265
313
|
适合从 Web/Vue 模板迁移到小程序 `.vue` 的项目。开启后,会把常见 HTML 标签映射成小程序内置标签,例如 `div -> view`、`span -> text`、`img -> image`、`a -> navigator`,也包含 `br/hr` 这类容易在迁移时“消失”的标签。
|
|
@@ -486,6 +534,10 @@ export default defineConfig({
|
|
|
486
534
|
|
|
487
535
|
不要在 `srcRoot`、路由来源、分包边界都没确认前就先调 chunk 策略。
|
|
488
536
|
|
|
537
|
+
### `web`
|
|
538
|
+
|
|
539
|
+
Web 重新扫描项目期间,已扫描 Vue SFC 的模板、样式与脚本继续使用上一次成功扫描的完整快照。扫描成功后才切换到新版本;扫描失败会保留旧快照并报告错误,修复后可继续更新。同一文件的正斜杠与反斜杠路径共用缓存,不会混入尚未发布的磁盘内容。
|
|
540
|
+
|
|
489
541
|
### `hmr.runtime`
|
|
490
542
|
|
|
491
543
|
默认值为 `auto`。微信项目会在 `wv dev` 启动时根据开发者工具设置自动选择 HMR 运行时,也可显式锁定状态保持型热更新:
|
|
@@ -502,6 +554,16 @@ export default defineConfig({
|
|
|
502
554
|
|
|
503
555
|
安全的 JavaScript/Vue 更新会保留当前 Page/Component 实例、route/query、输入和可序列化 data/setup ref,并替换原生 Page、原生 Component 与 wevu 方法。CSS、资源、JSON/配置、不兼容模块图或补丁失败会回退完整构建与当前路由重载。
|
|
504
556
|
|
|
557
|
+
入口拓扑更新先验证完整快照,再把仍符合源目录和声明依赖内容版本的快照一次性交给新宿主,避免重复编译。输入变化、依赖覆盖不足或固定输入批次无法验证时重新构建;快照失败时保留旧宿主,修复尚未进入旧图的新文件也能触发重试。会话关闭会取消未交接的候选。
|
|
558
|
+
|
|
559
|
+
Vue `<style module>` 会生成脚本中的类名映射,因此其内容、模块名称、`src` 及块增删都按脚本与样式共同更新处理,避免后续补丁引用未交付的样式模块。独立的普通 `<style>` 变化仍按纯样式处理;产物更新和真实 DevTools 已应用计算样式需要分别验收。
|
|
560
|
+
|
|
561
|
+
样式合并按真实文件身份判断所有权:已由模块图处理的样式,即使又通过符号链接、目录连接或 Windows 路径别名被发现,也不会作为独立原生样式重复读取并合并。固定输入批次保持该批次的样式内容,不混入同一文件较新的磁盘保存;真正独立的原生同名样式仍参与输出,移除显式样式导入后仍保留原生样式回退。
|
|
562
|
+
|
|
563
|
+
回退时,同一输出当前收集到的多个 sidecar 按收集顺序合并后一次发布,不会相互覆盖;指向同一真实文件的重复路径只保留一份。常规 HMR 更新按完整合并内容去重,而不是分别缓存每个片段。
|
|
564
|
+
|
|
565
|
+
上述保证不涵盖原生样式文件删除事件对历史登记集合的清理;本次修复没有验证或改变该上游生命周期。
|
|
566
|
+
|
|
505
567
|
`auto` 在 `project.private.config.json` 的 `setting.compileHotReLoad` 严格为 `true` 时选择 `stateful-experimental`,否则选择 `classic`;非微信平台也会回退到 `classic`。该判断只在启动时执行,修改开发者工具设置后需要重启 `wv dev`。启动日志会以 `HMR 模式` 和 `HMR 切换` 两行显示最终模式、选择来源,以及通过 DevTools 热重载开关或 `weapp.hmr.runtime` 切换模式的方法。显式配置通常优先,但 Skyline 兼容降级不受显式配置覆盖。
|
|
506
568
|
|
|
507
569
|
状态保持模式目前只支持微信小程序 WebView,需要微信开发者工具开启服务端口和热重载。微信开发者工具暂不支持 Skyline 热重载;首次编译检测到任意生成的应用或页面 JSON 使用 `renderer: 'skyline'` 时,`wv dev` 会输出带官方兼容文档链接的警告,将当前项目私有配置中的 `setting.compileHotReLoad` 持久化为 `false`,并强制使用 `classic`,包括显式配置 `stateful-experimental` 的场景。其他私有配置字段不会改变,切回 WebView 后也不会自动重新开启热重载。需要既有写盘/刷新行为时显式配置 `classic`。
|
|
@@ -529,6 +591,10 @@ export default defineConfig({
|
|
|
529
591
|
|
|
530
592
|
- `logLevel: 'default' | 'concise' | 'verbose'` 控制终端诊断详细程度。
|
|
531
593
|
- `profileJson: boolean | string` 控制是否输出 JSONL profile,字符串表示自定义输出路径。
|
|
594
|
+
- JSONL v1 保留旧字段,增加 `sessionId` / `buildId` / `batchId` / `sourceEvents` 与时钟来源;按来源精确匹配编辑。失败记录只有 `elapsedMs`;无受影响入口的批次以 `incomplete` / `reason: no-affected-entries` 结束观测,不污染后续构建。未知版本、未完成或缺失阶段不能按零耗时统计。`buildCoreMs` 是残差估算,阶段可能重叠。
|
|
595
|
+
- `analyze --hmr-profile --json` 的 `inputCoverage` 提供输入覆盖计数;旧版无版本记录仍兼容,未关联样本不归给当前编辑。
|
|
596
|
+
- stateful JSONL 以 `pipeline: 'stateful'` 区分,记录源通知到批次接收、准备、提交等待、提交及发布阶段。`completionBoundary` 区分客户端交付确认与产物发布;缺失来源、失败或取消不能计为成功耗时。`timelines` 只累加互不重叠的外层时段,未知阶段及负残差保持 `null`,不把嵌套 hook 重复累加。
|
|
597
|
+
- 模板 benchmark 的预算使用外部 `wallMs`,缺失 profile 不再填充 `totalMs`。仓库 `verify:edit-sequence --engine weapp-classic|weapp-stateful` 默认以 512 个真实 SFC 页面比较长期编译宿主和逐步新进程基线,同时记录进程树 RSS、强制 GC 后 heap、GC 开销及资源/转换范围。完整页面 JS 由 mpcore 执行,此结果不能替代真实 IDE 验收;profile 开关语义与开销比较入口为 `scripts/editSequence/compareProfiles.ts`。
|
|
532
598
|
|
|
533
599
|
### `mcp`
|
|
534
600
|
|
|
@@ -548,7 +614,7 @@ wv mcp doctor codex
|
|
|
548
614
|
|
|
549
615
|
```bash
|
|
550
616
|
weapp-vite build
|
|
551
|
-
weapp-vite preview --
|
|
617
|
+
weapp-vite preview -p weapp --mode test
|
|
552
618
|
weapp-vite ide preview --project ./dist/build/mp-weixin
|
|
553
619
|
```
|
|
554
620
|
|
|
@@ -557,3 +623,309 @@ weapp-vite ide preview --project ./dist/build/mp-weixin
|
|
|
557
623
|
- 项目结构与 `AGENTS.md`:[`project-structure.md`](./project-structure.md)
|
|
558
624
|
- wevu 运行时写法:[`wevu-authoring.md`](./wevu-authoring.md)
|
|
559
625
|
- Vue SFC 宏与模板:[`vue-sfc.md`](./vue-sfc.md)
|
|
626
|
+
|
|
627
|
+
## 函数式转换
|
|
628
|
+
|
|
629
|
+
`weapp.wxml.transform` 接收一个函数或函数数组,支持异步。每个函数收到当前模板源码;数组按声明顺序等待执行。返回 `null` / `undefined` 保持当前源码,返回空字符串清空模板。
|
|
630
|
+
|
|
631
|
+
```ts
|
|
632
|
+
import { defineConfig } from 'weapp-vite/config'
|
|
633
|
+
|
|
634
|
+
export default defineConfig({
|
|
635
|
+
weapp: {
|
|
636
|
+
wxml: {
|
|
637
|
+
transform: async (code, ctx) => {
|
|
638
|
+
if (ctx.isDev) {
|
|
639
|
+
return
|
|
640
|
+
}
|
|
641
|
+
return ctx.edit(code, (node) => {
|
|
642
|
+
if (node.tagName === 'view') {
|
|
643
|
+
node.removeAttribute('data-testid')
|
|
644
|
+
}
|
|
645
|
+
if (node.tagName === 'button') {
|
|
646
|
+
node.renameAttribute('data-track', 'data-analytics')
|
|
647
|
+
if (!node.hasAttribute('hover-class')) {
|
|
648
|
+
node.setAttribute('hover-class', 'none')
|
|
649
|
+
}
|
|
650
|
+
node.setAttribute('disabled', { expression: 'submitting' })
|
|
651
|
+
}
|
|
652
|
+
if (node.tagName === 'text' && node.hasAttribute('data-use-view')) {
|
|
653
|
+
node.renameTag('view')
|
|
654
|
+
node.removeAttribute('data-use-view')
|
|
655
|
+
}
|
|
656
|
+
})
|
|
657
|
+
},
|
|
658
|
+
},
|
|
659
|
+
},
|
|
660
|
+
})
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
匹配编译后的静态标签名,例如 Vue HTML 映射后的 `view`。第一版只转换最终模板:替换成自定义组件时,仍需通过既有 `usingComponents` 等配置注册组件;不会生成组件依赖、JS 或样式。
|
|
664
|
+
|
|
665
|
+
### 回调上下文
|
|
666
|
+
|
|
667
|
+
| 字段 / 方法 | 含义 |
|
|
668
|
+
| --- | --- |
|
|
669
|
+
| `fileName` | 相对输出根目录的 POSIX 文件名,包含分包目录 |
|
|
670
|
+
| `root` | 项目根目录 |
|
|
671
|
+
| `platform` / `mode` / `isDev` | 当前平台、模式及开发状态 |
|
|
672
|
+
| `subPackageRoot` | 独立分包构建的根目录;主包构建(含普通分包)为 `undefined` |
|
|
673
|
+
| `edit(code, visitor)` | 返回 `Promise<string>`,支持异步 visitor |
|
|
674
|
+
| `addWatchFile(path)` | 注册外部文件依赖,相对路径从项目根目录解析 |
|
|
675
|
+
| `warn(message)` / `error(message)` | 报告警告 / 中止本轮构建 |
|
|
676
|
+
|
|
677
|
+
`WxmlTransform`、`WxmlTransformResult`、`WxmlTransformContext`、`WxmlTransformVisitor`、`WxmlTransformNode`、`WxmlElementInfo`、`WxmlAttribute`、`WxmlAttributeValue`、`WxmlSourceLocation` 均可从 `weapp-vite/config` 和 `weapp-vite/types` 导入。回调执行于构建端,可以使用闭包、正则和异步读取;非法返回值或异常会中止输出,并报告文件名、回调序号及原始错误。
|
|
678
|
+
|
|
679
|
+
### 编辑节点与属性值
|
|
680
|
+
|
|
681
|
+
`ctx.edit` 每次只扫描一次,按源码顺序深度优先遍历标签。未修改的区间逐字保留;WXS 等脚本模块的原始内容不作为标签遍历。
|
|
682
|
+
|
|
683
|
+
- `tagName`、`attributes`、`parent`、`location` 为只读观察信息;位置包含从零开始的 `offset` 和从一开始的 `line` / `column`。父节点没有修改接口。
|
|
684
|
+
- `hasAttribute(name)` 和 `getAttribute(name)` 读取当前编辑状态。属性记录包含 `name`、原始 `rawValue` 与 `quote`,不求值动态或混合绑定;无值属性的 `rawValue` 为 `null`。
|
|
685
|
+
- `setAttribute(name, value)` 设置属性:字符串为字面量,数字和布尔值输出保持类型的绑定,`{ expression: 'submitting' }` 输出模板表达式。不要给表达式再包 `{{ }}`。
|
|
686
|
+
- `setBooleanAttribute(name)` 设置无值属性。`setAttribute(name, false)` 保留布尔 `false` 语义,不表示删除。
|
|
687
|
+
- `renameAttribute(from, to)` 保留原值,目标存在时抛错;源不存在时无操作。删除清除全部同名项,设置将重复属性收敛为一个。
|
|
688
|
+
- `renameTag(name)` 同时改开始和结束标签;`remove()` 删除整个子树并跳过子节点回调。
|
|
689
|
+
|
|
690
|
+
同一节点后续操作可以读取已修改状态。编辑句柄仅在当前 `edit` 会话内有效。不提供节点移动、插入或 unwrap;需要这些操作时可自行返回完整源码。
|
|
691
|
+
|
|
692
|
+
编辑工具沿用关键属性、结构标签及条件链保护。明确修改事件、平台指令或已识别的框架元数据会抛错并附带位置。直接返回源码允许完整控制,不提供上述语义保护;后续 `remove` 与宿主编译检查仍会执行。
|
|
693
|
+
|
|
694
|
+
### 子节点访问与子树编辑
|
|
695
|
+
|
|
696
|
+
`node.children` 返回按源码顺序排列的直接子标签;`await node.walk(visitor)` 深度优先遍历全部后代,不包含节点自身。下面的完整配置只处理带 `data-card` 的 `view`:
|
|
697
|
+
|
|
698
|
+
```ts
|
|
699
|
+
import { defineConfig } from 'weapp-vite/config'
|
|
700
|
+
|
|
701
|
+
export default defineConfig({
|
|
702
|
+
weapp: {
|
|
703
|
+
wxml: {
|
|
704
|
+
transform: (code, ctx) => ctx.edit(code, async (node) => {
|
|
705
|
+
if (node.tagName !== 'view' || !node.hasAttribute('data-card')) {
|
|
706
|
+
return
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
for (const child of node.children) {
|
|
710
|
+
if (child.tagName === 'text') {
|
|
711
|
+
child.setAttribute('selectable', true)
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
await node.walk(async (child) => {
|
|
716
|
+
if (child.hasAttribute('data-private-zone')) {
|
|
717
|
+
child.skipChildren()
|
|
718
|
+
return
|
|
719
|
+
}
|
|
720
|
+
if (child.tagName === 'button') {
|
|
721
|
+
child.setAttribute('hover-class', 'none')
|
|
722
|
+
}
|
|
723
|
+
if (child.hasAttribute('data-debug')) {
|
|
724
|
+
child.remove()
|
|
725
|
+
}
|
|
726
|
+
})
|
|
727
|
+
node.skipChildren()
|
|
728
|
+
}),
|
|
729
|
+
},
|
|
730
|
+
},
|
|
731
|
+
})
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
- 直接子 `text` 获得 `selectable="{{true}}"`;更深的 `text` 不会因直接子节点循环而改变。
|
|
735
|
+
- 后代 `button` 获得 `hover-class="none"`,带 `data-debug` 的普通标签及其子树删除。带 `data-private-zone` 的标签保留,其后代在这次手动遍历中跳过。
|
|
736
|
+
- 末尾的 `node.skipChildren()` 跳过外层自动遍历,避免同一子树再次被外层回调处理;因此示例中的 private zone 也不会再被外层自动遍历访问。删除该行时,外层仍会继续访问所有未删除后代。
|
|
737
|
+
|
|
738
|
+
| 接口 | 行为 |
|
|
739
|
+
| --- | --- |
|
|
740
|
+
| `children` | 当前未删除的直接子标签;只读数组,元素是可编辑句柄 |
|
|
741
|
+
| `walk(visitor)` | 返回 `Promise<void>`;同步或异步回调按源码顺序逐个等待,不包含自身 |
|
|
742
|
+
| `skipChildren()` | 仅跳过当前回调所属遍历的后代;不影响兄弟、其他遍历或输出 |
|
|
743
|
+
| `parent.children` | 只读观察节点,不允许借父节点修改祖先或兄弟 |
|
|
744
|
+
|
|
745
|
+
每次读取 `children` 得到一个数组快照;旧数组不会自动减少,删除节点及其全部后代的编辑句柄立即失效。子节点提前改名或修改属性后,后续自动回调与父节点观察到的是同一份新状态。源码位置始终对应本次 `edit` 输入,不因编辑重新计算。
|
|
746
|
+
|
|
747
|
+
手动 `walk` 每调用一次都会遍历一次,不会自动消费外层遍历;多层标记容器可能因此重复处理后代。若某个容器已负责全部后代处理,在它的外层回调中显式 `skipChildren()`。先 `skipChildren()` 再显式 `walk()` 也有效。内层回调中的跳过只属于内层遍历,不会跳过外层后续访问。
|
|
748
|
+
|
|
749
|
+
`skipChildren()` 只能对当前正在回调的节点调用;对 `children[0]`、其他保存的节点或回调结束后的句柄调用会报带源码位置的错误。嵌套遍历必须正确 `await`/`return`;同一编辑会话不支持 `Promise.all` 并发遍历或编辑,也不要发起未等待的异步任务或跨构建保存节点句柄。
|
|
750
|
+
|
|
751
|
+
`children` 与 `walk` 只识别本模板里的标签,不包含文本、注释、插值和 WXS/SJS 原始内容,不展开导入模板或自定义组件内部。事件、指令、结构标签、框架元数据与条件链保护在子树操作中同样生效。删除整个父节点会覆盖已记录的子节点编辑,并跳过全部相关后代回调。
|
|
752
|
+
|
|
753
|
+
`validate` 的 `node.children` 同样可用于结构检查,但元素只有只读观察接口;遍历仍用 `ctx.walk()`,没有节点编辑、`node.walk()` 或 `skipChildren()`:
|
|
754
|
+
|
|
755
|
+
```ts
|
|
756
|
+
import { defineConfig } from 'weapp-vite/config'
|
|
757
|
+
|
|
758
|
+
export default defineConfig({
|
|
759
|
+
weapp: {
|
|
760
|
+
wxml: {
|
|
761
|
+
validate: async (_code, ctx) => {
|
|
762
|
+
await ctx.walk((node) => {
|
|
763
|
+
if (node.hasAttribute('data-card')
|
|
764
|
+
&& !node.children.some(child => child.tagName === 'button')) {
|
|
765
|
+
ctx.report({
|
|
766
|
+
severity: 'warning',
|
|
767
|
+
code: 'card-button',
|
|
768
|
+
message: '卡片缺少直接子 button',
|
|
769
|
+
location: node.location,
|
|
770
|
+
})
|
|
771
|
+
}
|
|
772
|
+
})
|
|
773
|
+
},
|
|
774
|
+
},
|
|
775
|
+
},
|
|
776
|
+
})
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
### 输出顺序与热更新
|
|
780
|
+
|
|
781
|
+
执行顺序:模板编译 / 平台归一化 / i18n → `transform` → `remove` → 既有 Tailwind 与 compiler-plugin 输出处理 → `validate` → HMR 内容比较 → bundler 输出。后续输出插件仍可修改模板。独立分包转换完成后汇入主包,不重复转换。
|
|
782
|
+
|
|
783
|
+
外部规则文件必须显式调用 `ctx.addWatchFile('rules.json')`,建议在读取前注册,以便文件缺失导致构建失败后仍能恢复。外部依赖修改、删除、恢复会触发完整模板重建,覆盖主包、普通和独立分包。同一文件跨模板注册会去重;不自动追踪任意文件读取、环境变量或网络请求,也不允许监听构建输出目录。
|
|
784
|
+
|
|
785
|
+
每轮从当前编译输入重新转换,避免连续 HMR 累加上轮结果。回调应根据输入与显式依赖生成结果;不保证跨文件、跨分包的全局调用顺序,也不保证整个开发会话只调用一次。未配置 `transform` 时不增加编辑扫描;只返回字符串而不调用 `edit` 时,也不会为了回调额外解析模板。
|
|
786
|
+
|
|
787
|
+
## 最终模板校验
|
|
788
|
+
|
|
789
|
+
`weapp.wxml.validate` 在 `transform`、`remove` 和框架管理的 Tailwind / compiler-plugin 输出处理完成后执行,在 HMR 内容比较和发布前检查模板。可用于禁止调试节点残留、检查指定标签的必填属性或验证项目约定;默认不启用任何规则。
|
|
790
|
+
|
|
791
|
+
```ts
|
|
792
|
+
import { defineConfig } from 'weapp-vite/config'
|
|
793
|
+
|
|
794
|
+
export default defineConfig({
|
|
795
|
+
weapp: {
|
|
796
|
+
wxml: {
|
|
797
|
+
remove: { attr: [{ tag: 'view', name: 'data-testid' }] },
|
|
798
|
+
validate: async (_code, ctx) => {
|
|
799
|
+
if (ctx.isDev) {
|
|
800
|
+
return
|
|
801
|
+
}
|
|
802
|
+
await ctx.walk((node) => {
|
|
803
|
+
if (node.tagName === 'debug-panel') {
|
|
804
|
+
ctx.report({
|
|
805
|
+
severity: 'error',
|
|
806
|
+
code: 'no-debug-panel',
|
|
807
|
+
message: '发布模板不能包含 debug-panel',
|
|
808
|
+
location: node.location,
|
|
809
|
+
})
|
|
810
|
+
}
|
|
811
|
+
if (node.tagName === 'button' && !node.hasAttribute('data-track')) {
|
|
812
|
+
ctx.report({
|
|
813
|
+
severity: 'warning',
|
|
814
|
+
code: 'button-tracking',
|
|
815
|
+
message: 'button 缺少 data-track',
|
|
816
|
+
location: node.location,
|
|
817
|
+
})
|
|
818
|
+
}
|
|
819
|
+
})
|
|
820
|
+
},
|
|
821
|
+
},
|
|
822
|
+
},
|
|
823
|
+
})
|
|
824
|
+
```
|
|
825
|
+
|
|
826
|
+
### 校验接口与诊断
|
|
827
|
+
|
|
828
|
+
```ts
|
|
829
|
+
type WxmlValidate = (
|
|
830
|
+
code: string,
|
|
831
|
+
ctx: WxmlValidationContext,
|
|
832
|
+
) => void | Promise<void>
|
|
833
|
+
|
|
834
|
+
interface WxmlValidationDiagnostic {
|
|
835
|
+
severity: 'warning' | 'error'
|
|
836
|
+
code?: string
|
|
837
|
+
message: string
|
|
838
|
+
location?: WxmlSourceLocation
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
// weapp.wxml
|
|
842
|
+
// validate?: WxmlValidate | WxmlValidate[]
|
|
843
|
+
```
|
|
844
|
+
|
|
845
|
+
`WxmlValidate`、`WxmlValidationContext`、`WxmlValidationVisitor`、`WxmlValidationDiagnostic` 均从 `weapp-vite/config` 和 `weapp-vite/types` 导出。
|
|
846
|
+
|
|
847
|
+
- 单函数和函数数组都支持异步;数组按声明顺序等待,所有回调读取同一份模板。返回值必须为 `undefined`,返回字符串、`null`、`false` 等会报错;修改模板请使用 `transform`。
|
|
848
|
+
- `ctx.walk(visitor)` 返回 `Promise<void>`,须 `await` 或 `return`。同步/异步 visitor 按源码顺序深度优先访问节点;同一模板在本轮多个回调间复用一次扫描,只检查 `code` 而不遍历时不解析。
|
|
849
|
+
- 节点使用只读 `WxmlElementInfo`:`tagName`、`attributes`、`children`、`parent`、`location`、`hasAttribute`、`getAttribute`;没有 `setAttribute`、`renameTag` 或 `remove`。属性、父节点和位置不可改写。
|
|
850
|
+
- 属性 `rawValue` 不解码、不求值,`{{tracking}}` 不代表已知运行时值。静态值规则只比较可确定的字面内容,校验不能判断页面数据变化后的属性值。
|
|
851
|
+
- `ctx.report` 的 `warning` 允许输出,`error` 汇总当前构建内其他回调及模板的正常诊断后阻止输出。同轮同文件、回调、严重程度、代码、消息和位置均相同的诊断去重。
|
|
852
|
+
- 诊断包含输出相对路径、从 1 开始的回调序号、可选规则代码和行列;不传 `location` 时为文件级诊断。位置对应本轮最终模板,不映射回 `.vue` 源文件。
|
|
853
|
+
- 回调异常、扫描失败、非法返回值或诊断格式立即中止并保留原始错误;没有静默跳过或自动修复。失败不会推进该构建的成功输出缓存,独立分包失败会传递到主构建。
|
|
854
|
+
|
|
855
|
+
上下文提供与 `transform` 相同含义的 `fileName`、`root`、`platform`、`mode`、`isDev`、`subPackageRoot` 和 `addWatchFile`;不提供 `edit`,校验诊断统一通过 `report` 发出。
|
|
856
|
+
|
|
857
|
+
### 按范围校验与复用规则
|
|
858
|
+
|
|
859
|
+
下面把普通分包的静态属性检查拆成可复用函数;`fileName` 为输出相对 POSIX 路径,`subPackageRoot` 只标识独立分包构建,普通分包应按路径筛选。
|
|
860
|
+
|
|
861
|
+
```ts
|
|
862
|
+
import type { WxmlValidate } from 'weapp-vite/config'
|
|
863
|
+
import { defineConfig } from 'weapp-vite/config'
|
|
864
|
+
|
|
865
|
+
const checkCheckout: WxmlValidate = async (_code, ctx) => {
|
|
866
|
+
if (ctx.platform !== 'weapp' || !ctx.fileName.startsWith('packages/checkout/')) {
|
|
867
|
+
return
|
|
868
|
+
}
|
|
869
|
+
await ctx.walk((node) => {
|
|
870
|
+
if (node.tagName === 'button' && node.getAttribute('data-track')?.rawValue === '') {
|
|
871
|
+
ctx.report({ severity: 'error', message: '静态埋点属性不可为空字符串', location: node.location })
|
|
872
|
+
}
|
|
873
|
+
})
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
export default defineConfig({
|
|
877
|
+
weapp: { wxml: { validate: [checkCheckout] } },
|
|
878
|
+
})
|
|
879
|
+
```
|
|
880
|
+
|
|
881
|
+
校验按最终静态标签名匹配,因此 Vue HTML 映射后的 `div` 通常需要检查 `view`。已被 `remove` 删除的节点不会再命中;输出插件新添加的节点会被检查。独立分包在所属构建中校验一次,汇入主包不重复执行。
|
|
882
|
+
|
|
883
|
+
### 外部规则与 HMR
|
|
884
|
+
|
|
885
|
+
外部规则文件与转换阶段共用监听、分阶段记录依赖。在读取前登记文件,即使文件缺失导致失败,也能在恢复时触发重新构建:
|
|
886
|
+
|
|
887
|
+
```ts
|
|
888
|
+
import { readFile } from 'node:fs/promises'
|
|
889
|
+
import { resolve } from 'node:path'
|
|
890
|
+
import { defineConfig } from 'weapp-vite/config'
|
|
891
|
+
|
|
892
|
+
export default defineConfig({
|
|
893
|
+
weapp: {
|
|
894
|
+
wxml: {
|
|
895
|
+
validate: async (_code, ctx) => {
|
|
896
|
+
ctx.addWatchFile('wxml-policy.json')
|
|
897
|
+
const policy: unknown = JSON.parse(await readFile(resolve(ctx.root, 'wxml-policy.json'), 'utf8'))
|
|
898
|
+
if (!Array.isArray(policy) || !policy.every(tag => typeof tag === 'string')) {
|
|
899
|
+
throw new Error('wxml-policy.json 必须是禁用标签名的字符串数组')
|
|
900
|
+
}
|
|
901
|
+
const forbidden = new Set<string>(policy)
|
|
902
|
+
await ctx.walk((node) => {
|
|
903
|
+
if (forbidden.has(node.tagName)) {
|
|
904
|
+
ctx.report({ severity: 'error', message: `不允许使用 ${node.tagName}`, location: node.location })
|
|
905
|
+
}
|
|
906
|
+
})
|
|
907
|
+
},
|
|
908
|
+
},
|
|
909
|
+
},
|
|
910
|
+
})
|
|
911
|
+
```
|
|
912
|
+
|
|
913
|
+
`wxml-policy.json` 例如 `["debug-panel"]`。同一文件跨模板或阶段登记会去重;修改、删除、恢复触发完整模板重建与校验。局部构建保留未触及模板的依赖,成功完整构建清理失效登记。不要监听输出目录,也不要把一次读取的结果永久缓存而忽略规则更新。
|
|
914
|
+
|
|
915
|
+
“最终”指框架管理的输出链完成后的模板,不保证覆盖任意排在该阶段之后的第三方 Vite 插件修改。不保证跨文件/分包回调顺序,不追踪任意文件读取、环境变量或网络响应;第一版不提供内置业务规则、跨文件全局校验、独立 CLI 或报告文件,也不能替代宿主完整语法和运行时检查。
|
|
916
|
+
|
|
917
|
+
## Analyze 产物消费与预算
|
|
918
|
+
|
|
919
|
+
小程序 `wv analyze --json --budget-check` 输出 schema v2 的 `artifacts.files`、`build` 与 `budgetChecks`,日志进入 stderr。每个物理文件保留路径、包归属、字节和 SHA-256;runtime 依据模块所属包分类,不依赖 chunk 名称。分包复制的 JS asset 仍保留原模块来源。
|
|
920
|
+
|
|
921
|
+
`weapp.analyze.budgets.runtimeBytes` 限制包含 runtime 模块的文件字节上界(包含混合 chunk 的业务部分);`packageBytes` 按分包 root 覆盖单包预算,主包键为 `__main__`。超限或缺少归因时 `--budget-check` 返回非零。
|
|
922
|
+
|
|
923
|
+
`estimatedBytes` 是按打包器长度分摊的模块估算,`unattributedBytes` 显式保留未知部分。单份共享文件计一次,真正的分包副本分别计入总包;runtime 和重复模块估算不能再加到总包上。旧的无版本报告仍保留兼容读取,但不能作为新 runtime 预算通过证据。
|
|
924
|
+
|
|
925
|
+
## 构建目录与外部缓存
|
|
926
|
+
|
|
927
|
+
默认清理策略适合构建器独占的输出目录。共享目录使用 `build.emptyOutDir: false` 时,构建上下文只清理它已登记的旧产物,不能删除新进程开始前由其他工具或外部缓存写入的未知文件。
|
|
928
|
+
|
|
929
|
+
推荐 dev 输出到独立目录,Turbo 只缓存生产目录,dev 任务设置 `cache: false`、`persistent: true`。必须共用目录时,由缓存集成持久记录成功构建的 emitted 文件清单与内容摘要,恢复及清理仅针对该任务拥有的文件;用户改写或同名冲突必须保留并报告。不要把无条件清空输出目录加入 HMR 兜底逻辑。最终构建产物仍由 Vite/Rolldown emit/write 持久化。
|
|
930
|
+
|
|
931
|
+
仓库组合回归入口为 `pnpm verify:edit-sequence --engine weapp-modes --require-clean --report .tmp/output-mode-sequence.json`,运行前重建 weapp-vite。它逐步比较模式切换、组件/页面/分包拓扑变化和旧缓存恢复后的完整生产文件,与独立进程基线按字节核对;共享目录额外检查用户文件保护。此项不是真实 IDE runtime 验收。
|
|
@@ -37,6 +37,16 @@ else if (import.meta.env.PLATFORM === 'web') {
|
|
|
37
37
|
|
|
38
38
|
这类写法通常会导致时序错误或生命周期不触发。
|
|
39
39
|
|
|
40
|
+
## performance 预设与 setData 诊断
|
|
41
|
+
|
|
42
|
+
`weapp.wevu.preset: 'performance'` 为 app/component 注入 `setData.strategy: 'patch'`、`suspendWhenHidden: true`、`diagnostics: 'fallback'` 和开发态 `highFrequencyWarning`,并默认启用 `autoSetDataPick`。`weapp.wevu.defaults` 的同名字段覆盖预设;`autoSetDataPick` 的显式布尔值也优先。
|
|
43
|
+
|
|
44
|
+
内建 `diagnostics` 默认关闭,预设开启后没有 `devOnly` 限制,生产构建也可能输出日志。将 app/component 的 `setData.diagnostics` 设为 `'off'` 只关闭内建日志,自定义 `debug` 回调仍有效。
|
|
45
|
+
|
|
46
|
+
`needsFullSnapshot` 可能来自 patch 首次收集快照、变更路径无法定位,或此前提交失败后的恢复。首次收集仍可只下发差异,单条 reason 不证明失败或完整 payload;恢复须结合 `commitFailure`、revision 和成功结算判断。
|
|
47
|
+
|
|
48
|
+
显式开启 `debugPhases: true` 后,同一 revision 会增加 prepare、dispatch、commit 记录,内建日志也会打印这些记录。按同一会话内的 `(phase.observerId, revision)` 关联更新,按 `phase.dispatch.id` 去重调用;将初始化与计时区间分开,不能从 warning 条数推导回退率或预设收益。宿主 heap 缺失时保留未完成的内存验收,不用 Node worker RSS 替代。
|
|
49
|
+
|
|
40
50
|
## 事件与双向绑定
|
|
41
51
|
|
|
42
52
|
复杂表单或可复用字段组件优先使用 `bindModel` / `useBindModel`,不要让事件细节分散在大量不一致的自定义协议里。
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { t as createCompilerContext } from "./createContext-BqYzHhY9.mjs";
|
|
2
|
+
import { r as resolveAnalyzeBudgets, t as terminateStaleSassEmbeddedProcess } from "./processCleanup-B6KA30Zc.mjs";
|
|
3
|
+
import { r as readDoctorFiles } from "./files-BqxFIPRp.mjs";
|
|
4
|
+
import process from "node:process";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { randomUUID } from "node:crypto";
|
|
7
|
+
//#region src/doctor/buildWorker.ts
|
|
8
|
+
process.once("message", async (options) => {
|
|
9
|
+
try {
|
|
10
|
+
const outputRoot = path.join(options.cwd, ".weapp-vite", "doctor", options.target, randomUUID());
|
|
11
|
+
const limitations = /* @__PURE__ */ new Set();
|
|
12
|
+
const ctx = await createCompilerContext({
|
|
13
|
+
cwd: options.cwd,
|
|
14
|
+
configFile: options.configFile,
|
|
15
|
+
cliPlatform: options.target,
|
|
16
|
+
isDev: false,
|
|
17
|
+
mode: "production",
|
|
18
|
+
outputRoot,
|
|
19
|
+
inlineConfig: {
|
|
20
|
+
build: {
|
|
21
|
+
outDir: outputRoot,
|
|
22
|
+
emptyOutDir: true
|
|
23
|
+
},
|
|
24
|
+
plugins: [{
|
|
25
|
+
name: "weapp-vite-doctor-output-scope",
|
|
26
|
+
enforce: "post",
|
|
27
|
+
writeBundle(output) {
|
|
28
|
+
const relative = path.relative(outputRoot, path.resolve(output.dir ?? path.dirname(output.file ?? outputRoot)));
|
|
29
|
+
if (relative.startsWith("..") || path.isAbsolute(relative)) limitations.add("构建器输出包含快照根目录外的路径;不能证明产物覆盖完整。");
|
|
30
|
+
}
|
|
31
|
+
}]
|
|
32
|
+
},
|
|
33
|
+
syncSupportFiles: false,
|
|
34
|
+
preloadAppEntry: false,
|
|
35
|
+
emitDefaultAutoImportOutputs: false
|
|
36
|
+
});
|
|
37
|
+
if (path.resolve(ctx.configService.outDir) !== outputRoot || ctx.configService.platform !== options.target) throw new Error("实际编译目标或产物目录与 Doctor 请求不一致");
|
|
38
|
+
await ctx.buildService.build();
|
|
39
|
+
if (ctx.configService.weappViteConfig.npm?.buildOptions) limitations.add("自定义 npm.buildOptions 可改变输出目录;当前快照不证明目录外 npm 产物完整。");
|
|
40
|
+
const snapshot = {
|
|
41
|
+
files: await readDoctorFiles(outputRoot),
|
|
42
|
+
origin: "build",
|
|
43
|
+
freshness: "current-build",
|
|
44
|
+
capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
45
|
+
budgets: resolveAnalyzeBudgets(ctx.configService),
|
|
46
|
+
sourceRoot: path.relative(options.cwd, ctx.configService.absoluteSrcRoot).split(path.sep).join("/"),
|
|
47
|
+
outputRoot: path.relative(options.cwd, outputRoot).split(path.sep).join("/"),
|
|
48
|
+
limitations: [...limitations]
|
|
49
|
+
};
|
|
50
|
+
terminateStaleSassEmbeddedProcess();
|
|
51
|
+
process.send?.({ snapshot }, () => process.exit(0));
|
|
52
|
+
} catch (error) {
|
|
53
|
+
process.stderr.write(`${error instanceof Error ? error.stack : String(error)}\n`);
|
|
54
|
+
terminateStaleSassEmbeddedProcess();
|
|
55
|
+
process.exit(2);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
//#endregion
|
|
59
|
+
export {};
|