Bun

Watch 模式

Bun 透過 CLI 旗標支援兩種自動重新載入模式

  • --watch 模式,會在匯入的檔案變更時硬重新啟動 Bun 的程序。
  • --hot 模式,會在匯入的檔案變更時軟重新載入程式碼 (不會重新啟動程序)。

--watch 模式

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

以 watch 模式執行 bun test,並啟用 save-on-keypress

bun --watch test

bun test gif

在您不希望終端機清除畫面的情況下,例如同時使用 concurrently 等工具執行多個 bun build --watch 命令時,--no-clear-screen 旗標非常有用。如果沒有此旗標,一個執行個體的輸出可能會清除其他執行個體的輸出,可能會將一個執行個體的錯誤隱藏在另一個執行個體的輸出之下。 --no-clear-screen 旗標,類似於 TypeScript 的 --preserveWatchOutput,可以防止這個問題。它可以與 --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 物件)都會被保留。

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,以實現更好的熱重新載入生命週期管理,並與生態系統保持一致。

實作細節