Bun

監控模式

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 設定為在 每次按鍵時儲存檔案

bash
watchy.tsx
bun run --watch watchy.tsx
watchy.tsx
import { serve } from "bun";
console.log("I restarted at:", Date.now());

serve({
  port: 4003,

  fetch(request) {
    return new Response("Sup");
  },
});

在此範例中,Bun

bun watch gif

在監控模式下執行 bun test,並啟用 save-on-keypress

bun --watch test

bun test gif

--hot 模式

使用 bun --hot 在使用 Bun 執行程式碼時啟用熱重新載入。這與 --watch 模式不同,因為 Bun 不會強制重新啟動整個處理程序。相反地,它會偵測程式碼變更並使用新程式碼更新其內部模組快取。

注意 — 這與瀏覽器中的熱重新載入不同!許多框架提供「熱重新載入」體驗,你可以編輯並儲存你的前端程式碼(例如 React 元件),並在不重新整理頁面的情況下看到瀏覽器中反映的變更。Bun 的 --hot 是此體驗的伺服器端等效項。若要在瀏覽器中進行熱重新載入,請使用 Vite 等框架。

bun --hot server.ts

從進入點開始(如上範例中的 server.ts),Bun 會建立一個登錄檔,記錄所有已匯入的原始檔(不包含 node_modules 中的檔案),並監控其變更。當偵測到變更時,Bun 會執行「軟性重新載入」。所有檔案都會重新評估,但所有全域狀態(特別是 globalThis 物件)都會持續存在。

server.ts
// 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 伺服器會重新載入更新的程式碼,而不用重新啟動程序。這會帶來非常快速的更新速度。

server.ts
globalThis.count ??= 0;
globalThis.count++;

Bun.serve({
  fetch(req: Request) {
    return new Response(`Reloaded ${globalThis.count} times`);
  },
  port: 3000,
});

注意 — 在 Bun 的未來版本中,計畫支援 Vite 的 import.meta.hot,以啟用更好的生命週期管理,進行熱重新載入,並與生態系統保持一致。

實作細節