Bun

Bun v1.2.20


Jarred Sumner · 2025年8月10日

此版本修復了 141 個問題(獲得 429 個 👍),並在執行時、打包器和開發伺服器中進行了許多可靠性改進。

安裝 Bun

curl
npm
powershell
scoop
brew
docker
curl
curl -fsSL https://bun.nodejs.com.tw/install | bash
npm
npm install -g bun
powershell
powershell -c "irm bun.sh/install.ps1|iex"
scoop
scoop install bun
brew
brew tap oven-sh/bun
brew install bun
docker
docker pull oven/bun
docker run --rm --init --ulimit memlock=-1:-1 oven/bun

升級 Bun

bun upgrade

降低空閒 CPU 使用率

在空閒時過度排程垃圾回收器嚴重影響了空閒 CPU 使用率。

此更改對記憶體使用率沒有影響。

自動 yarn.lock 遷移

bun install 現在將自動將您的 yarn.lock (v1) 檔案遷移到 bun.lock 檔案。

感謝 @RiskyMH 的貢獻

AbortSignal.timeout 加速 40 倍

我們重寫了 AbortSignal.timeout,使其使用與 setTimeout 相同的底層實現。這使其速度提高了 40 倍。

40x faster `AbortSignal.timeout`

改進了 bun:test 的 diffing

bun:test 中的 diffing 輸出已重新設計,以提高可讀性。

現在會突出顯示空白字元的差異。

bun:test diffing

修復了幾個涉及非 ASCII 字元的邊緣情況以及許多其他錯誤。

感謝 @pfgithub 的貢獻!

用於返回值的新 bun:test 匹配器

已為斷言模擬函式返回值添加了三個新的 bun:test 匹配器:toHaveReturnedWithtoHaveLastReturnedWithtoHaveNthReturnedWith。這些匹配器使用深度相等,類似於 toEqual(),並支援非對稱匹配器。

  • toHaveReturnedWith():檢查模擬函式在其任何呼叫中是否返回了特定值。
  • toHaveLastReturnedWith():檢查最近一次呼叫的返回值。
  • toHaveNthReturnedWith():檢查特定呼叫(從 1 開始索引)的返回值。
import { test, expect, mock } from "bun:test";

test("toHaveReturnedWith", () => {
  const returnsAnObject = mock(() => ({ a: 1 }));
  returnsAnObject();
  expect(returnsAnObject).toHaveReturnedWith({ a: 1 });
});

test("toHaveLastReturnedWith", () => {
  const returnsAString = mock((i) => `call ${i}`);
  returnsAString(1);
  returnsAString(2);
  expect(returnsAString).toHaveLastReturnedWith("call 2");
});

test("toHaveNthReturnedWith", () => {
  const returnsANumber = mock((i) => i * 10);
  returnsANumber(1);
  returnsANumber(2);
  returnsANumber(3);
  expect(returnsANumber).toHaveNthReturnedWith(2, 20);
});

感謝 @dylan-conway 的貢獻!

使用 expectTypeOf 測試您的型別

bun:test 現在包含 expectTypeOf,用於斷言 TypeScript 型別,其 API 與 Vitest 相容。

這些斷言在執行時是 no-ops;它們由 TypeScript 編譯器檢查。要驗證您的型別測試,請執行 bunx tsc --noEmit

import { expectTypeOf, test } from "bun:test";

test("type-level tests", () => {
  // Basic type assertions
  expectTypeOf("hello").toBeString();
  expectTypeOf(123).toBeNumber();

  // Check object shapes
  expectTypeOf({ a: 1, b: "2" }).toMatchObjectType<{ a: number }>();

  // Assert function parameter and return types
  function add(a: number, b: number): number {
    return a + b;
  }

  expectTypeOf(add).parameters.toEqualTypeOf<[number, number]>();
  expectTypeOf(add).returns.toBeNumber();
});

感謝 @pfgithub 的貢獻

bun:testmock.clearAllMocks()

bun:test 模組現在實現了 mock.clearAllMocks(),這是一個用於重置所有模擬函式狀態的函式。此函式會清除所有模擬的 .mock.calls.mock.results 屬性,但重要的是,它不會恢復其原始實現。

這對於在測試之間重置模擬狀態非常有用,例如在全域性設定檔案中,而無需手動跟蹤和清除每個單獨的模擬。

import { test, mock, expect } from "bun:test";

const random = mock(() => Math.random());

test("clearing all mocks", () => {
  random();
  expect(random).toHaveBeenCalledTimes(1);

  // Reset the state of all mocks
  mock.clearAllMocks();

  expect(random).toHaveBeenCalledTimes(0);

  // The mock implementation is preserved
  expect(typeof random()).toBe("number");
  expect(random).toHaveBeenCalledTimes(1);
});

感謝 @pfgithub 的貢獻

bun outdatedbun update 現在支援 --recursive

bun outdatedbun update --interactive 現在對工作區有了更好的支援,從而更容易管理 monorepo 中的依賴項。

您現在可以使用 -r--recursive 標誌在所有工作區中執行這些命令。

# See outdated packages in all workspaces
bun outdated --recursive

# Interactively update packages in all workspaces
bun update -i -r

當在 monorepo 中執行 bun update -i 時,將顯示一個新的“工作區”列,顯示依賴項屬於哪個工作區。

bun update -i --recursive

dependencies             Current  Target  Latest   Workspace
  ❯ □ @types/node        24.1.0   24.2.1  24.2.1   bun-types

此外,bun update -i 現在支援 --filter 標誌,允許您將更新範圍限定到特定工作區。

# Interactively update dependencies only in the "my-app" workspace
bun update -i --filter="my-app"

這還修復了 bun update 未正確處理目錄依賴項的問題。此外,bun outdatedbun update -i 在工作區列中顯示了哪些包使用了目錄。

感謝 @RiskyMH 的貢獻

Bun.serve 靜態路由中的自動 ETagIf-None-Match

Bun.serve 現在會自動為 static 選項中定義的靜態路由生成 ETag 標頭。當客戶端傳送 If-None-Match 標頭時,Bun 會比較 ETag,並在內容未更改時傳送 304 Not Modified 響應。這可以提高快取效率並節省頻寬,無需進行任何程式碼更改即可啟用。

const server = Bun.serve({
  port: 0,
  routes: {
    "/latest.json": Response.json({ ...myBigObject }),
  },
});
const url = new URL("/latest.json", server.url);
const etag = await fetch(url).then((res) => res.headers.get("etag"));
const { status } = await fetch(url, {
  headers: {
    "If-None-Match": etag,
  },
});

console.log({ status, etag });

Windows 長路徑支援

Bun 現在在 Windows 上一致支援長度超過 260 個字元的檔案路徑。這透過應用程式清單啟用,消除了具有深度目錄結構或長檔名的專案中的常見檔案相關錯誤。

import { mkdirSync, existsSync, rmSync } from "fs";
import { join } from "path";

// This path is longer than 260 characters
const longPath = join("C:\\", "a".repeat(270));

// This could've previously failed on Windows
mkdirSync(longPath, { recursive: true });

console.log(`Exists: ${existsSync(longPath)}`); // Exists: true

rmSync(longPath, { recursive: true, force: true });

以前,在 Windows 上支援長檔案路徑涉及我們內部新增到大部分程式碼中的極其複雜的檔案路徑名稱空間。現在它要簡單得多,因為 Win32 API 原生支援長路徑。

WebAssembly.compileStreamingWebAssembly.instantiateStreaming

Bun 現在支援 WebAssembly.compileStreaming()WebAssembly.instantiateStreaming()。這些 API 允許您直接從流源(例如 fetch() 呼叫的 Response)編譯和例項化 WebAssembly 模組。

這種方法比非流式替代方案(WebAssembly.compileWebAssembly.instantiate)更有效,因為它避免將整個 Wasm 模組緩衝到記憶體中。一旦收到第一個位元組,編譯就可以開始,從而降低延遲和記憶體使用。

// Bun will stream the response body directly to the Wasm compiler.
const { instance, module } = await WebAssembly.instantiateStreaming(
  fetch("https://:3000/add.wasm"),
);

// Use the instantiated module
console.log(instance.exports.add(2, 3)); // => 5

感謝 @CountBleck 的貢獻

Node.js 相容性改進

  • 已修復:由於型別定義過時,在賦值給 require.main 時出現型別錯誤。main 屬性不再是 readonly
  • 已修復:在執行 next dev --turbopack 時錯誤地記錄了 Invalid source map 錯誤。
  • 已修復:取消 HTTP 請求(例如在 next dev 中快速重新整理頁面)可能會導致 ERR_STREAM_ALREADY_FINISHED 錯誤。
  • 已修復:使用 zlib 模組時的 Zstandard 流的執行緒安全問題。
  • 已修復:在 node:cryptoX509Certificate 中提供無效輸入時可能發生的崩潰。
  • 已修復:在 process.nextTick 本身或微任務中未捕獲的異常未報告的假設性 bug。
  • 已修復:在使用 { recursive: true }fs.mkdirfs.mkdirSync 中記憶體洩漏已得到解決。
  • 已修復:在 TTY 或管道的 process.stdoutprocess.stderr 中缺少 [Symbol.asyncIterator]。此 bug 影響了 Linux 上 Claude Code 的某些使用者。

Bun shell 修復

  • 已修復:在 bun shell 中使用管道連線立即退出的內建命令時發生的崩潰。
  • 已修復:$.braces() 現在支援包含 Unicode 字元的模式和更深層次的巢狀展開。
  • 已修復:Shell 詞法分析器會在錯誤訊息中錯誤地將 = token 顯示為 +
  • 已修復:在某些情況下解析無效語法時發生的崩潰。

打包器 bug 修復

  • 已修復:JavaScript 解析器在解析深度巢狀表示式時發生的堆疊溢位。透過重構解析器以使用更少的堆疊空間,這得到了解決,從而防止了具有長成員訪問鏈或函式呼叫鏈的崩潰。
  • 已修復:bun build 為包含頂級 await 依賴項的迴圈匯入生成無效程式碼的 bug,導致了語法錯誤。

bun install bug 修復

  • 已修復:在使用路徑包含非 ASCII 字元的生命週期指令碼時,--linker=isolated 出現的 bug。
  • 已修復:在 bun install 中安裝依賴項期間出現許可權錯誤時可能發生的崩潰,這種情況可能在 GitHub Actions 等非互動式環境中發生。

前端開發伺服器 bug 修復

  • 已修復:在使用類似 vim 的交換檔案並當檔案的匯入被更改或刪除時,--hot 模式下可能發生的崩潰。
  • 已修復:在啟用 --hot 的開發伺服器中,刪除被多個其他檔案匯入的檔案時發生的崩潰。
  • 已修復:Windows 上的檔案觀察者崩潰,當許多檔案同時更改時(例如切換 git 分支)可能發生。這是由於檔案系統事件數量超過內部緩衝區時發生的索引越界錯誤。
  • 已修復:客戶端中止 HTTP 請求時可能發生的崩潰。
  • 已修復:透過改進路徑解析的內部緩衝區管理,解決了開發伺服器中潛在的效能瓶頸。
  • 修復了在使用熱模組替換 (HMR) 時,瀏覽器中 import.meta.url 不正確的 bug。現在它正確地使用 window.location.origin 而不是 bun://

bun:test bug 修復

  • 已修復:expect(...).toHaveBeenCalledWith() 和相關的模擬函式匹配器在斷言失敗時現在顯示彩色的 diff,這使得除錯具有複雜物件引數的測試更加容易。
  • 已修復:bun test 中的 beforeAll 鉤子會為不包含任何符合當前測試過濾器條件的測試的 describe 塊執行。
  • 已修復:expect(() => { throw undefined }).toThrow(ErrorClass) 的 bug。
  • 已修復:如果模擬函式從未被呼叫,jest.fn().mockRejectedValue() 會導致未處理的拒絕。
  • 已修復:即使 describe 塊中的所有測試都被過濾掉,bun test 中的 beforeAll 鉤子仍會為 describe 塊執行。
  • 已修復:當將目錄名稱作為引數傳遞時,bun test 不會正確過濾測試。
  • 已修復:bun test 會在錯誤的位置顯示透過的 test.failing() 的警告。
  • 已修復:bun:test 中的 toIncludeRepeated 檢查的是*至少*指定的出現次數,而不是*確切*的次數,這與 Jest 的行為一致。
  • 已修復:使用 node:test 模組執行多個測試檔案時,bun test 會失敗。

Windows bug 修復

  • 已修復:在 Windows 上解析無效檔案路徑時發生的斷言失敗。
  • 已修復:在 Windows 上讀取大檔案時發生的整數強制轉換 panic。

執行時 bug 修復

  • 已修復:終端語法高亮器會將額外的閉合大括號 } 錯誤地新增到涉及模板字面量的錯誤訊息中。
  • 已改進:對重複值的 Transfer-Encoding 標頭驗證。感謝 Radman Siddiki 的報告。

Bun.SQL

  • 已修復:資料庫連線失敗時 Bun.SQL 中可能發生的崩潰。
  • 已修復:在大批次插入期間可能發生的“索引越界”錯誤。
  • 已修復:Bun.sql 客戶端中可能導致程序無限期掛起的 bug,尤其是在關閉期間查詢待處理時。

檔案系統和 Bun.file

  • 已修復:在只讀 Blob(非透過 Bun.file() 建立的)上呼叫 .write().writer().unlink().delete() 不會丟擲錯誤。現在它會正確地丟擲錯誤,指出由位元組支援的 Blob 是隻讀的,這與 Bun.write() 的行為一致。

Bun.which 和可執行檔案解析

  • 已修復:Windows 上的 Bun.which 無法找到包含非 ASCII 字元的目錄路徑中的可執行檔案。這也影響了 bun install 中的生命週期指令碼。

Bun.resolve 和模組解析

  • 已修復:Bun.resolve()Bun.resolveSync() 現在在失敗時始終丟擲 Error 物件。以前,它們可能會丟擲原始值,導致 try...catch 塊崩潰。

Bun.s3

  • 已修復 Bun.s3.unlink() 在未配置 S3 憑證時可能發生的崩潰。

Response 建構函式和 Web API

  • 已修復:statusTextResponse 建構函式的字串強制轉換。
  • 已修復:當提供無效的狀態碼時,Response.redirect() 現在會正確地丟擲 RangeError

環境變數和配置

  • 已修復從 .env 檔案載入的環境變數過長(超過 4096 個字元)會被截斷的 bug。這也可能導致崩潰。

安裝和特定平臺修復

  • 已修復 Windows 安裝指令碼 (install.ps1) 中的一個 bug,該 bug 透過使用分號而不是冒號連線路徑,錯誤地連線了本地指令碼的 PATH 環境變數。

記憶體管理和效能

  • Bun 的執行緒池現在將在不活動 10 秒後更積極地釋放記憶體,從而在空閒期間減少記憶體使用。
  • 透過用原子操作替換互斥鎖,優化了內部同步原語 WaitGroup。這可以提高併發任務數量較多的場景下的效能。

TypeScript 型別改進

  • 已修復:@types/bun 現在與 TypeScript 5.9 相容,解決了 ArrayBuffer 的型別衝突,該衝突以前需要在 tsconfig.json 中設定 skipLibCheck: true
  • bun:sqlite 中,db.transaction() 的 TypeScript 型別已得到改進,以正確推斷事務回撥的返回型別。這允許您以型別安全的方式從事務中返回資料。傳遞給事務的引數也已正確鍵入。

感謝 19 位貢獻者!