Bun

Bun v1.0.22


Ashcon Partovi · 2024年1月9日

Bun v1.0.22 修復了 29 個錯誤(解決了 118 個 👍 反應),修正了 Vercel 上的 bun install 問題,新增了 performance.mark() API,新增了對額外管道的 child_process 支援,使 Buffer.concat 更快,新增了 toBeEmptyObjecttoContainKeys 匹配器,修正了使用表情符號的 console.table 寬度,以及 worker_threads 中對 argvexecArgv 選項的支援,並支援 fetch 中的 Brotli。

Bun 是一個極速的 JavaScript 執行時環境、打包器、轉譯器和套件管理器 —all in one。如果您錯過了,以下是 Bun 最近的一些變更

  • v1.0.21 - 修復了 33 個錯誤(解決了 80 個 👍 反應)。console.table() 支援。Bun.write、Bun.file 和 bun:sqlite 使用更少的記憶體。使用 FormData 上傳大型檔案時使用更少的記憶體。bun:sqlite 錯誤訊息變得更詳細。修復了 node:fs 錯誤中的記憶體洩漏。Node.js 相容性改進,以及修復了許多崩潰問題。
  • v1.0.20 - 減少了 fs.readlinkfs.readFilefs.writeFilefs.statHTMLRewriter 中的記憶體使用量。修復了 setTimeout 在 Linux 上導致 CPU 使用率過高的回歸問題。HTMLRewriter.transform 現在支援字串和 `ArrayBuffer`。fs.writeFile()fs.readFile() 現在支援 `hex` 和 `base64` 編碼。Bun.spawn 顯示了進程使用的 CPU 和記憶體量。
  • v1.0.19 - 修復了 26 個錯誤(解決了 92 個 👍 反應)。使用 @types/bun 而不是 bun-types。修復了 --frozen-lockfile 錯誤。bcrypt 和 argon2 套件現在可以運作了。setTimeout 和 setInterval 獲得了 4 倍更高的吞吐量。bun:test 中的模組模擬解析了規範符。為 Linux 上大型 stdio 優化了 spawnSync()。Bun.peek() 快了 90 倍,expect(map1).toEqual(map2) 快了 100 倍。修復了 NAPI、bun install 和 Node.js 相容性改進的錯誤。

安裝 Bun

curl
npm
brew
docker
curl
curl -fsSL https://bun.dev.org.tw/install | bash
npm
npm install -g 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

已修正:Vercel 上 bun install 的問題

在最近發布的 Bun 版本中,我們對 bun install 進行了變更,以透過平行執行生命週期腳本來加快其速度。在執行此操作時,我們也變更了 Bun 設定生命週期腳本目前工作目錄的方式,並開始使用 posix_spawn_file_actions_addchdir_np C 標準函式庫函數。

Bun 沒有正確檢查該函數是否失敗。該函數是在 glibc 2.29 中引入的,但 Vercel 使用的是 glibc 2.26。因此,在 Vercel 上執行 bun install 時,該函數會失敗,而 bun install 不會處理該失敗。

修復方法是為 Linux 實作一個類似 `posix_spawn` 的 Polyfill。

新增:performance.mark() API

您現在可以使用 user-timings API,其中包括 performance.mark()performance.measure()。這對於測量程式碼的效能非常有用。

performance.mark("start");
while (true) {
  // ...
}
performance.mark("end");
performance.measure("task", "start", "end");

您也可以使用 PerformanceObserver API 來監聽效能事件。

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (entry.entryType === "mark") {
      console.log(entry); // { name: "start", startTime: 0 }
    } else if (entry.entryType === "measure") {
      console.log(entry); // { name: "task", startTime: 0, duration: 1000 }
    }
  }
});

observer.observe({ entryTypes: ["mark", "measure"] });

感謝 @gvilums 提交 PR 將此功能新增至 Bun,並感謝 WebKit 團隊實作這些 API。

新增:child_process 支援額外管道

您現在可以將額外管道傳遞給 child_process 函數。這對於在進程之間傳遞資料非常有用。例如,您可以將管道傳遞給子進程,然後從父進程寫入該管道。

parent.js
child.js
parent.js
import { spawn } from "node:child_process";

const child = spawn(process.argv0, ["child.js"], {
  stdio: ["inherit", "inherit", "inherit", "pipe"],
});

const pipe = child.stdio[3];
pipe.on("data", (data) => {
  console.log(data.toString()); // "hello!"
});
child.js
import { createWriteStream } from "node:fs";

const stream = createWriteStream(null, { fd: 3 });
stream.on("ready", () => {
  stream.write("hello!");
});

即將推出:Playwright 支援

這些變更是支援 Playwright 所必需的,Playwright 使用額外管道與瀏覽器進程通訊。但是,還有一個 待處理的 PR 需要合併,才能讓 Playwright 與 Bun 一起運作。

感謝 @nektro 實作這個遺失的 API。

新增:fetch 的 Brotli 支援

您現在可以使用 fetch 發出帶有 br 編碼的請求。這對於向支援 Brotli 壓縮的伺服器發出請求非常有用。

const response = await fetch("https://example.com", {
  headers: {
    "Accept-Encoding": "br",
  },
});

我們也將 brotli 支援變更為在 Bun 中靜態連結,而不是動態連結。這修正了某些 Linux 發行版和較舊 macOS 版本沒有必要函式庫的問題。

新增:toBeEmptyObjecttoContainKeys 匹配器

您現在可以使用 expect().toBeEmptyObject() 來檢查物件是否為空。

expect({}).toBeEmptyObject();
expect({ a: 1 }).not.toBeEmptyObject();

您也可以使用 expect().toContainKeys()expect().toContainAnyKeys() 來檢查物件是否包含某些鍵。

expect({ a: 1, b: 2 }).toContainKeys(["a", "b"]);
expect({ a: 1, b: 2 }).not.toContainKeys(["c"]);
expect({ foo: "bar" }).toContainAnyKeys(["foo", "baz"]);
expect({ foo: "bar" }).not.toContainAnyKeys(["baz"]);

感謝 @coratgerl 實作此功能。

新增:速度提升 15% 至 400% 的 Buffer.concat

現在使用 Buffer.concat 的速度提高了 15% 到 400%,具體取決於要串連的緩衝區大小。

我們也修復了一個錯誤,即當串連大量緩衝區時,Buffer.concat 會崩潰。這是由於記憶體不足錯誤未正確處理所導致的。

新增:速度提升 10% 至 15% 的 new Headers(object)

現在使用帶有物件的 new Headers(object)new URLSearchParams(object) 的速度提高了 10% 到 15%。

已修正:使用表情符號的 console.table 寬度

在 Bun v1.0.21 中,我們新增了對 console.table 的支援。但是,我們沒有正確處理表情符號,如果表格中有表情符號或 Unicode 字元,表格就會錯位。透過使用官方 Unicode 資料集來確定每個字元的寬度,此問題已得到修正。

之前 (Bun v1.0.21)之後 (Bun v1.0.22)

感謝 @otgerrogla 實作 console.table,並跟進修復此錯誤。

新增:worker_threadsargvexecArgv 選項

Bun 不支援 worker_threadsargvexecArgv 選項。此問題已修正。

index.js
worker.js
index.js
import { Worker } from "node:worker_threads";

const worker = new Worker("./worker.js", {
  argv: ["--foo", "bar"],
  execArgv: ["--inspect"],
});

worker.on("message", (data) => {
  console.log(data);
  // { argv: [ "--foo", "bar" ], execArgv: [ "--inspect" ] }
});
worker.js
postMessage({
  argv: process.argv,
  execArgv: process.execArgv,
});

感謝 @otgerrogla 修復此遺失的功能。

已修正:繫結到 0.0.0.0 也會繫結到 IPv6

有一個錯誤,即當繫結到 0.0.0.0 時,createServer 會同時繫結到 IPv4 和 IPv6。感謝 @Hanaasagi,此問題已得到修正。

已修正:`node:http` 中的 HTTP 方法大小寫

在 Bun v1.0.10 中,我們引入了一個錯誤,即 PURGEOPTIONS 標頭未正確轉換為大寫。這導致了 Fastify 和 CORS 預檢請求的問題。感謝 @asomethings,此問題已得到修正。

已修正:BufferList 上的部分消耗

有一個錯誤,即 BufferList 上的多個部分消耗不會正確增加 offset。這導致 cbor 無法正常運作,感謝 @hborchardt,此問題已得到修正。

已修正:使用 `compiled://` URL 的 bun build --compile

我們修復了一個錯誤,即 bun build --compile 無法與 compiled:// URL 搭配使用。透過將 compiled:// URL 變更為使用 Bun 識別的特殊前綴,此問題已得到修正。

新增:assert.doesNotMatch

您現在可以使用 assert.doesNotMatch 來檢查字串是否與正則表達式不匹配。

assert.doesNotMatch("I will not match", /match/);

感謝 @markusn 實作這個遺失的 API。

感謝 22 位貢獻者!

感謝所有為此 Bun 版本做出貢獻的貢獻者,包括提交了第一個 Pull Request 的 13 位新貢獻者!

您也可以閱讀完整的變更日誌