把项目从「手写 dist/」改成「wallpapers/ 是唯一真相来源,dist/ 由 pnpm build 生成」,
并补上配套的类型、门禁与抓取器。一次提交落地整条管线,因为拆开会留下不能构建的中间态。
- src/:运行时与模拟器源码(TS,strict),编译到 build/ 再拷进各分发
- tools/:build / dev / check-{syntax,paths,dist},以及抓取器与回归门禁 tools/checks/
(.scratch/ 下那批一次性脚本移入 tools/checks/ 并入库为长期门禁)
- wallpapers/:七档壁纸的源数据 + README.md(id/音频/预设的完整规范)
- docs/adr/0005-0008:构建管线与分发拓扑、模拟器契约、自包含 sim、每骨架资源布局
- .gitignore:排除 .scratch/ 的参考资料副本(上游 spine 整仓克隆 ~1.2 GB、
抓取侦查数据 ~680 MB)与调试转储;这些是本地调查材料,补偿会让仓库无法克隆
- 归一化 .gitignore/CONTEXT.md 行尾(工作区 CRLF、索引 LF 造成的整文件假 diff)
同时修掉三档卡住构建的未完工壁纸:
- kv45 的 meta.json 里 id 还是抓取期场景名 scene_main,经 downloader promote 正名为 kv45
- shajin / zhigengniao_juheye 的 meta.json 误用了骨架描述文件(name/spine/animations/pages)、
且都缺 preset.template.json;现按规范重建:骨架沉到 spines/<名>/(spine-ts 按 atlas 所在
目录解析贴图页)、补上元数据与单骨架预设,并清掉 zhigengniao 骨架里指向作者机的绝对路径
- 顺带 promote 已在 sources.yml 里的 kv46(月升之前,与兽共舞)
pnpm check 五道门全绿:10 个分发 / 7 档壁纸 / 141 处引用自包含。
74 lines
3.4 KiB
Markdown
74 lines
3.4 KiB
Markdown
# 12 — pnpm dev 热更新
|
|
|
|
Status: resolved
|
|
Type: task
|
|
|
|
## 需求
|
|
|
|
> pnpm dev 开发模式支持热更新
|
|
|
|
## 做法
|
|
|
|
监听 `src/` 与 `wallpapers/`,按改动**只跑必要的那几步**构建,然后经 SSE 通知浏览器。
|
|
|
|
| 改动 | 跑什么 | 浏览器怎么更新 | 实测 |
|
|
| --- | --- | --- | --- |
|
|
| `src/styles/*.css` | 重铺产物 | **只换样式表** | 850 ms |
|
|
| `src/runtime/*` | tsc runtime + 重铺产物 | 整页刷新 | 1.1 s |
|
|
| `src/simulator/*` | tsc simulator(产物里也带模拟器时再重铺) | 整页刷新 | 600 ms |
|
|
| `wallpapers/**`、模板、vendor、`VERSION` | 重铺产物 | 整页刷新 | 850 ms |
|
|
| 构建失败 | — | **只报错,不刷新** | — |
|
|
|
|
全量 `pnpm build` 是 2.2 秒;按改动拆开之后,改样式只要 0.85 秒,改模拟器 0.6 秒。
|
|
|
|
### 为什么 CSS 单独一条路
|
|
|
|
整页刷新要重新下载 3.4 MB 骨架、重建 Spine 播放器、面板状态全丢。改样式时这些全是白费——
|
|
换一下 `<link>` 的 `href`(加个 `?t=` 时间戳)就够了。实测确认:换完样式表,
|
|
`window` 上的标记**还在**,也就是页面确实没有重载。
|
|
|
|
### 为什么构建失败不刷新
|
|
|
|
刷新会把一个半成品页面端上来,而错误信息在控制台里——很容易被当成"改了没生效"。
|
|
现在构建失败只在左下角显示一条红药丸,页面保持原样。
|
|
|
|
### 为什么状态药丸挂在 `<html>` 下
|
|
|
|
与模拟器面板同一个理由:`body` 上会被打 `transform`/`filter`(翻转、颜色选项),
|
|
挂 `body` 里会跟着壁纸一起被镜像、被调色。
|
|
|
|
## 两个必须记住的约束
|
|
|
|
1. **绝不能监听 `dist/`**。构建写 `dist/`,监听它就是一个死循环。只监听 `src/`、`wallpapers/`、`VERSION`。
|
|
2. **`--with-sim` 产物里也有一份模拟器**,而且它的驱动排在调试服注入的那份**之前**(幂等闸先到先得)。
|
|
所以那种构建下,改模拟器必须连产物一起重铺,否则浏览器会一直跑旧模拟器。
|
|
调试服启动时会探一次产物里有没有模拟器,据此决定要不要多跑那一步。
|
|
|
|
## 调试期代码不许进产物
|
|
|
|
热更新客户端连的是 `/__dev/events`——那在真实 WE 里、在任何静态托管上都不存在。
|
|
它由 `tools/dev.ts` 的 `html()` 注入,`tools/build.ts` 的 `renderIndexHtml` 完全不碰它。
|
|
|
|
这条**钉进了 `check:dist`**,不再靠人工抽查。实测过它会拦:
|
|
|
|
```
|
|
✗ collection-all/index.html 里有调试服专属的 /__dev/events
|
|
```
|
|
|
|
(一个从不失败的检查等于没有检查——所以注入标记确认它会红,再还原。)
|
|
|
|
三种产物都确认过干净:默认产物 0 处、`--with-sim` 产物 0 处、自包含包 0 处。
|
|
|
|
## 验证
|
|
|
|
`tools/checks/verify-hot-reload.mts`:真的改源文件,用"页面上的标记还在不在"区分两种更新方式
|
|
(只看"页面变了没有"是分不出"整页刷新"和"只换样式表"的):
|
|
|
|
- 页面注入了热更新客户端;`/__dev/events` 返回 `text/event-stream`
|
|
- 改 CSS → 被改的那条样式表 href 换成带 `?t=` 的新地址、**标记还在**(没整页重载)、换上的确实是新内容
|
|
- 改 runtime → **标记被抹掉**(整页刷新)、刷新后面板重新挂上
|
|
- 测完还原源文件,并确认仓库里没有探针注释残留
|
|
|
|
其余回归全绿:`pnpm check`、调试服与浏览器冒烟、面板还原度、四档自包含包 `file://`、
|
|
静态托管预览、6 组渲染与重构前逐像素相同。
|