> ## Documentation Index
> Fetch the complete documentation index at: https://bun.ll1025.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# 监视模式

> Bun 中 --watch 和 --hot 模式的自动重载

Bun 支持两种自动重载方式：

* `--watch` 模式，当导入的文件发生更改时，硬重启 Bun 的进程。
* `--hot` 模式，当导入的文件发生更改时，软重载代码（不重启进程）。

***

## `--watch` 模式

监视模式适用于 `bun test` 以及运行 TypeScript、JSX 和 JavaScript 文件。

在 `--watch` 模式下运行文件：

```bash terminal icon="terminal" theme={null}
bun --watch index.tsx
```

在 `--watch` 模式下运行测试：

```bash terminal icon="terminal" theme={null}
bun --watch test
```

在 `--watch` 模式下，Bun 会跟踪所有导入的文件并监视其变化。当文件发生更改时，Bun 会使用与初始运行相同的 CLI 参数和环境变量重启进程。如果 Bun 崩溃，`--watch` 会尝试重启进程。

<Note>
  **⚡️ 重载速度很快。** 你可能习惯的文件系统监视器有多层库包装原生 API，更糟糕的是有的依赖轮询。

  相反，Bun 使用操作系统的原生文件系统监视 API（如 kqueue 或 inotify）来检测文件变化。Bun 还应用了若干优化以扩展到更大项目，例如设置较高的文件描述符限制、静态分配文件路径缓冲区以及尽可能重用文件描述符。
</Note>

以下示例展示了 Bun 在编辑文件时实时重载的效果，VSCode 配置为[每次按键](https://code.visualstudio.com/docs/editor/codebasics#_save-auto-save)自动保存文件。

```sh terminal icon="terminal" theme={null}
bun run --watch watchy.tsx
```

```tsx title="watchy.tsx" icon="https://mintcdn.com/span-inc/82N53aP7NFbaCVSl/icons/typescript.svg?fit=max&auto=format&n=82N53aP7NFbaCVSl&q=85&s=787d39d6a7d96d7f9540dc74344eba23" theme={null}
import { serve } from "bun";

console.log("I restarted at:", Date.now());

serve({
  port: 4003,
  fetch(request) {
    return new Response("Sup");
  },
});
```

<Frame>
  ![Bun watch 动图](https://user-images.githubusercontent.com/709451/228439002-7b9fad11-0db2-4e48-b82d-2b88c8625625.gif)
</Frame>

在启用"保存时保存"的情况下运行 `bun test` 的监视模式：

```bash terminal icon="terminal" theme={null}
bun --watch test
```

<Frame>
  ![Bun test 动图](https://user-images.githubusercontent.com/709451/228396976-38a23864-4a1d-4c96-87cc-04e5181bf459.gif)
</Frame>

<Note>
  **`--no-clear-screen`** 标志与 TypeScript 的 `--preserveWatchOutput` 类似，可防止 Bun 在监视模式下清除终端。当使用 `concurrently` 等工具同时运行多个 `bun build --watch` 命令时使用，因为一个实例清除屏幕可能会隐藏另一个实例的错误：`bun build --watch --no-clear-screen`。
</Note>

***

## `--hot` 模式

使用 `bun --hot` 在 Bun 执行代码时启用热重载。与 `--watch` 模式不同，Bun 不会硬重启整个进程。它会检测代码变化并用新代码更新内部模块缓存。

<Note>
  这与浏览器中的热重载不同。许多框架提供了"热重载"体验，你可以编辑和保存前端代码（比如 React 组件），并在浏览器中看到更改而无需刷新页面。Bun 的 `--hot` 是此体验的服务器端等价物。要在浏览器中获得热重载，请使用 [Vite](https://vite.dev) 等框架。
</Note>

```bash terminal icon="terminal" theme={null}
bun --hot server.ts
```

从入口点（本例中为 `server.ts`）开始，Bun 会构建所有导入源文件（`node_modules` 中的除外）的注册表，并监视其变化。当文件变化时，Bun 执行"软重载"。所有文件被重新求值，但全局状态（特别是 `globalThis` 对象）保持不变。

```ts title="server.ts" icon="https://mintcdn.com/span-inc/82N53aP7NFbaCVSl/icons/typescript.svg?fit=max&auto=format&n=82N53aP7NFbaCVSl&q=85&s=787d39d6a7d96d7f9540dc74344eba23" theme={null}
// 让 TypeScript 开心
declare global {
  var count: number;
}

globalThis.count ??= 0;
console.log(`已重载 ${globalThis.count} 次`);
globalThis.count++;

// 防止 `bun run` 退出
setInterval(function () {}, 1000000);
```

如果你使用 `bun --hot server.ts` 运行此文件，每次保存文件时都会看到重载计数递增。

```bash terminal icon="terminal" theme={null}
bun --hot index.ts
```

```txt theme={null}
已重载 1 次
已重载 2 次
已重载 3 次
```

传统的文件监视器（如 `nodemon`）会重启整个进程，因此 HTTP 服务器和其他有状态对象会丢失。相比之下，`bun --hot` 会在不重启进程的情况下反映更新后的代码。

### HTTP 服务器

你可以在不关闭服务器的情况下更新 HTTP 请求处理程序：保存文件时，Bun 会用更新后的代码重载服务器而无需重启进程。这带来了极快的刷新速度。

```ts title="server.ts" icon="https://mintcdn.com/span-inc/82N53aP7NFbaCVSl/icons/typescript.svg?fit=max&auto=format&n=82N53aP7NFbaCVSl&q=85&s=787d39d6a7d96d7f9540dc74344eba23" theme={null}
globalThis.count ??= 0;
globalThis.count++;

Bun.serve({
  fetch(req: Request) {
    return new Response(`已重载 ${globalThis.count} 次`);
  },
  port: 3000,
});
```

<Note>
  计划支持 Vite 的 `import.meta.hot`，以实现更好的热重载生命周期管理并与生态系统对齐。
</Note>

<Accordion title="实现细节">
  在热重载时，Bun：

  * 重置内部 `require` 缓存和 ES 模块注册表（`Loader.registry`）
  * 同步运行垃圾回收器（以最小化内存泄漏，代价是运行时性能）
  * 从头开始重新转译所有代码（包括 sourcemaps）
  * 使用 JavaScriptCore 重新求值代码

  此实现并非特别优化。它会重新转译未更改的文件。它不尝试增量编译。这只是一个起点。
</Accordion>
