Skip to main content
Bun 支持两种自动重载方式:
  • --watch 模式:当导入的文件发生更改时,Bun 会硬重启进程。
  • --hot 模式:当导入的文件发生更改时,Bun 会软重载代码(不重启进程)。

--watch 模式

Watch 模式适用于 bun test,以及运行 TypeScript、JSX 和 JavaScript 文件时。 --watch 模式下运行文件:
terminal
--watch 模式下运行测试:
terminal
--watch 模式下,Bun 会跟踪所有导入的文件并监视它们的变化。当文件发生变化时,Bun 会使用与初始运行相同的 CLI 参数和环境变量重新启动进程。如果 Bun 崩溃,--watch 会尝试重新启动进程。
⚡️ 重载速度很快。 你可能已经习惯的文件系统监视器通常有多层库封装原生 API,或者更糟糕的是,依赖轮询。Bun 使用操作系统原生的文件系统监视 API(如 kqueue 或 inotify)来检测文件变化。此外,Bun 还应用了多项优化来支持更大型的项目,例如为文件描述符设置较高的 rlimit、静态分配文件路径缓冲区,以及尽可能复用文件描述符。
以下示例演示了 Bun 在编辑文件时的实时重载,VSCode 被配置为每次按键保存文件
terminal
watchy.tsx
bun watch 动图
启用 save-on-keypress 后,在 watch 模式下运行 bun test
terminal
bun test 动图
--no-clear-screen 标志类似于 TypeScript 的 --preserveWatchOutput,可以防止 Bun 在 watch 模式下清空终端。当你使用 concurrently 等工具同时运行多个 bun build --watch 命令时,可以使用此标志; 这样,其中一个实例清屏时就不会隐藏另一个实例的错误:bun build --watch --no-clear-screen

--hot 模式

使用 bun --hot 在使用 Bun 执行代码时启用热重载。与 --watch 模式不同,Bun 不会完全重启整个进程。它会检测代码变化,并使用新代码更新其内部模块缓存。
这与浏览器中的热重载不同。许多框架都提供“热重载”体验,你可以编辑并保存前端代码(例如 React 组件),然后在不刷新页面的情况下看到浏览器中的变化。Bun 的 --hot 是这种体验在服务器端的对应实现。要在浏览器中实现热重载,请使用 Vite 等框架。
terminal
从入口文件(本例中的 server.ts)开始,Bun 会构建一个包含所有导入源文件的注册表(不包括 node_modules 中的文件),并监视这些文件的变化。当文件发生变化时,Bun 会执行“软重载”。所有文件都会重新求值,但全局状态(尤其是 globalThis 对象)会保留。
server.ts
如果你用 bun --hot server.ts 运行这个文件,每次保存文件时你都会看到重载计数递增。
terminal
nodemon 这样的传统文件监视器会重启整个进程,因此 HTTP 服务器和其他有状态对象都会丢失。相比之下,bun --hot 无需重启进程即可反映更新后的代码。

HTTP 服务器

你可以更新 HTTP 请求处理器,而无需关闭服务器:保存文件时,Bun 会使用更新后的代码重新加载服务器,同时不会重启进程。因此可以实现极快的刷新速度。
server.ts
计划支持 Vite 的 import.meta.hot,以便更好地管理热重载的生命周期,并与生态系统保持一致。
热重载时,Bun 会:
  • 重置内部的 require 缓存和 ES 模块注册表(Loader.registry
  • 同步运行垃圾回收(以减少内存泄漏,但会牺牲一定运行时性能)
  • 重新从头转译所有代码(包括 sourcemaps)
  • 使用 JavaScriptCore 重新求值代码
目前的实现并非特别优化,会重新转译未发生变化的文件,也没有尝试增量编译。这只是一个起点。