Bun 通过 CLI 标志支持两种自动重新加载方式
--watch
模式,当导入的文件发生更改时,硬重启 Bun 的进程。--hot
模式,当导入的文件发生更改时,软重载代码(无需重启进程)。
--watch
模式
监听模式可以与 bun test
或在运行 TypeScript、JSX 和 JavaScript 文件时使用。
要在 --watch
模式下运行文件
bun --watch index.tsx
要在 --watch
模式下运行测试
bun --watch test
在 --watch
模式下,Bun 会跟踪所有导入的文件并监视它们的变化。当检测到更改时,Bun 会重启进程,保留初始运行时使用的相同 CLI 参数和环境变量集。如果 Bun 崩溃,--watch
将尝试自动重启进程。
⚡️ 重新加载速度很快。 您可能习惯的文件系统监视器通常有多个库层包装原生 API,或者更糟糕的是,依赖轮询。
相反,Bun 使用操作系统原生文件系统监视器 API,如 kqueue 或 inotify,来检测文件更改。Bun 还进行了许多优化,使其能够扩展到更大的项目(例如,为文件描述符设置高 rlimit,静态分配文件路径缓冲区,尽可能重用文件描述符等)。
以下示例显示了 Bun 在文件编辑时实时重新加载文件,VSCode 配置为在每次击键时保存文件。
bun run --watch watchy.tsx
import { serve } from "bun";
console.log("I restarted at:", Date.now());
serve({
port: 4003,
fetch(request) {
return new Response("Sup");
},
});
在此示例中,Bun 正在

在监听模式下运行 bun test
并且启用了 save-on-keypress
bun --watch test

--no-clear-screen
标志在您不希望终端清除屏幕的情况下很有用,例如当使用 concurrently
等工具同时运行多个 bun build --watch
命令时。如果没有此标志,一个实例的输出可能会清除其他实例的输出,从而可能将一个实例的错误隐藏在另一个实例的输出之下。与 TypeScript 的 --preserveWatchOutput
类似,--no-clear-screen
标志可以防止此问题。它可以与 --watch
结合使用,例如:bun build --watch --no-clear-screen
。
--hot
模式
使用 bun --hot
在使用 Bun 执行代码时启用热重载。这与 --watch
模式不同,Bun 不会硬重启整个进程。相反,它检测代码更改并使用新代码更新其内部模块缓存。
注意 — 这与浏览器中的热重载不同!许多框架都提供了“热重载”体验,您可以在其中编辑和保存前端代码(例如,React 组件),并在浏览器中看到更改的反映,而无需刷新页面。Bun 的 --hot
是这种体验的服务器端等效项。要在浏览器中获得热重载,请使用 Vite 等框架。
bun --hot server.ts
从入口点(在上面的示例中为 server.ts
)开始,Bun 构建所有导入的源文件(不包括 node_modules
中的文件)的注册表,并监视它们的变化。当检测到更改时,Bun 会执行“软重载”。所有文件都会被重新评估,但所有全局状态(特别是 globalThis
对象)都会被保留。
// make TypeScript happy
declare global {
var count: number;
}
globalThis.count ??= 0;
console.log(`Reloaded ${globalThis.count} times`);
globalThis.count++;
// prevent `bun run` from exiting
setInterval(function () {}, 1000000);
如果您使用 bun --hot server.ts
运行此文件,您将看到每次保存文件时重新加载计数都会递增。
bun --hot index.ts
Reloaded 1 times
Reloaded 2 times
Reloaded 3 times
像 nodemon
这样的传统文件监视器会重启整个进程,因此 HTTP 服务器和其他有状态对象会丢失。相比之下,bun --hot
能够反映更新后的代码,而无需重启进程。
HTTP 服务器
这使得例如在不关闭服务器本身的情况下更新 HTTP 请求处理程序成为可能。当您保存文件时,您的 HTTP 服务器将被重新加载更新后的代码,而无需重启进程。这带来了极快的刷新速度。
globalThis.count ??= 0;
globalThis.count++;
Bun.serve({
fetch(req: Request) {
return new Response(`Reloaded ${globalThis.count} times`);
},
port: 3000,
});
注意 — 在未来版本的 Bun 中,计划支持 Vite 的 import.meta.hot
以实现更好的热重载生命周期管理,并与生态系统保持一致。
实现细节