参考约 3 分钟
开发 Rust 侧
为什么原生模块无法热重载、重新编译的实际耗时,以及 bun run dev 的工作流。
JS 重挂载已在热重载里讲过。原生那一半没有热重载,也不可能做到:对 .node 文件的 require() 会调用 process.dlopen,而 Node 没有配套的卸载,活动状态(GPUI 的平台、GPU 设备、已打开的窗口、UI 线程以及选区注册表)都留在已加载的库里。第二次加载会在第一个库仍被加载的同时创造出独立的原生状态。
重新编译足够快,所以其实无所谓。在一台 M 系列 Mac 上改动一个文件后实测:
| 步骤 | 耗时 |
|---|---|
cargo check --lib |
1.5s |
cargo build --lib |
4.9s |
bun run build:debug (napi) |
~2s |
| 单个 vitest 截图文件 | ~2s |
bun run dev 把这套流程串成一个循环:它监视 packages/native/src,重新编译并重渲染截图测试。从改动 Rust 到生成新 PNG 大约 4 秒。
bun run dev # rebuild, re-render the showcase screenshots
bun scripts/dev.ts --shots diff # only tests matching "diff"
bun scripts/dev.ts --app native-text # rebuild, restart an example app
两件完全避免重新编译的事
- 内容本身就在 props 里。修改
patch或source,下一帧就会显示。 - 设计数值在
theme.metrics里。调整行高或标题字号只是一次 React 重渲染。
参见原生文本组件。
确定性调度
测试渲染器使用 VisualTestAppContext 配合 TestDispatcher 来实现确定性调度。事件模拟走的是 GPUI 基于坐标的命中测试与派发 —— 而不是合成的 JS 事件。
详见测试。
贡献指南
详细的架构、通信流程与贡献指南见 AGENTS.md。