Bun

Bun v1.0.20


Jarred Sumner · 2023年12月24日

Bun v1.0.20 減少了 fs.readlinkfs.readFilefs.writeFilefs.statHTMLRewriter 中的記憶體用量。修復了 setTimeout 在 Linux 上導致高 CPU 使用率的迴歸錯誤。HTMLRewriter.transform 現在支援字串和 ArrayBufferfs.writeFile()fs.readFile() 現在支援 hexbase64 編碼。Bun.spawn 顯示了程序使用的 CPU 和記憶體量。

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

  • v1.0.15 - 修復了 23 個錯誤(解決了 117 個 👍 表情符號),tsc 啟動速度快了 2 倍。穩定的 WebSocket 客戶端、語法突顯錯誤、更清晰的堆疊追蹤、使用 expect.extend() 新增自訂測試匹配器 + 其他 expect 匹配器。
  • v1.0.16 - 修復了 49 個錯誤(解決了 38 個 👍 表情符號)。Bun.file 和 Bun.write 的並行 IO 速度提高了 3 倍,現在支援 Google Cloud Run 和 Vercel,Bun.write 在父目錄不存在時自動建立,expect.extend 在 preload 內部運作,napi_create_object 速度提高了 2.5 倍,修復了影響 Astro v4 和 p-limit 的模組解析錯誤,console.log 錯誤修復
  • v1.0.17 - 修復了 15 個錯誤(解決了 152 個 👍 表情符號)。bun install postinstall 腳本為前 500 個套件執行,bunx supabase 的啟動速度比 npx supabase 快 30 倍,bunx esbuild 的啟動速度比 npx esbuild 快 50 倍,以及 bun install 的錯誤修復
  • v1.0.18 - 修復了 27 個錯誤(解決了 28 個 👍 表情符號)。已修復影響 create-vite 和 create-next 和 stdin 的掛起問題。已修復生命週期腳本報告 "node" 或 "node-gyp" 找不到的問題。expect().rejects 現在像 Jest 一樣運作,以及更多錯誤修復
  • 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

node:fs 中減少記憶體用量

此版本進行了基礎架構變更,減少了 Bun 中涉及字串的非同步工作的記憶體用量。

我們也改進了偵錯組建中記憶體分配的內部報告,這有助於我們識別記憶體洩漏。

在平行讀取符號連結 1,000,000 次之後

方法JavaScript 執行時環境平台RSS (MB)
fs.readlinkBun v1.0.20macOS arm6445 MB
fs.readlinkNode.js v21.4.0macOS arm6470 MB
fs.readlinkBun v1.0.19macOS arm64107 MB

fs.stat 最多減少 2 倍記憶體用量

在平行 stat 檔案 1,000,000 次之後

方法JavaScript 執行時環境平台RSS (MB)
fs.statBun v1.0.20 --smolmacOS arm6445 MB
fs.statBun v1.0.20macOS arm6471 MB
fs.statNode.js v21.4.0macOS arm6470 MB
fs.statBun v1.0.19macOS arm64107 MB

fs.writeFile 記憶體洩漏已修復

將 16 MB 非 ASCII 字串寫入磁碟 100 次

方法JavaScript 執行時環境平台RSS (MB)
fs.writeFileBun v1.0.20macOS arm6491 MB
fs.writeFileNode.js v21.4.0macOS arm64130 MB
fs.writeFileBun v1.0.19macOS arm641,696 MB

HTMLRewriter.transform 現在支援字串和 ArrayBuffer

HTMLRewriter 可讓您動態轉換 HTML。它對於以下事項很有用,例如

  • 重新編寫 URL 以指向 CDN
  • 從 HTML 中提取元數據
  • 取得頁面上的所有圖片

Bun 的 HTMLRewriter 實作現在支援將字串和 ArrayBuffer 傳遞給 HTMLRewriter.transform。先前,您必須傳遞 Response 物件。

將字串傳遞給 HTMLRewriter.transform 會將該字串解析為 HTML 並傳回字串。

const html = new HTMLRewriter()
  .on("img", {
    element(element) {
      element.setAttribute("src", "https://example.com/image.png");
    },
  })
  .on("title", {
    element(element) {
      element.setInnerContent("Hello world!");
    },
  })
  .transform(
    "<html><body><img src='image.png'><title>My page</title></body></html>",
  );

console.log(html);
// <html><body><img src="https://example.com/image.png"><title>Hello world!</title></body></html>

HTMLRewriter 中的記憶體洩漏已修復

HTMLRewriter 中的記憶體洩漏已修復。這是由於未在適當的時間呼叫解構子所導致。

fs.readFile() 和 fs.writeFile() 現在支援 hex 和 base64 編碼

fs.readFilefs.writeFile 現在支援 hexbase64 編碼。這對於讀取和寫入二進制檔案非常有用。

import { readFile, writeFile } from "fs/promises";

const buffer = await readFile("image.png", { encoding: "hex" });
await writeFile("image-copy.png", buffer, { encoding: "hex" });

已修復:setTimeout 在 Linux 上導致高 CPU 使用率的迴歸錯誤

Bun v1.0.19 中存在一個迴歸錯誤,其中 setTimeout 在 Linux 上導致高 CPU 使用率。這已修復,感謝 @cirospaciari

Bun.spawn 現在報告 resourceUsage

Bun.spawnBun.spawnSync 取得了 resourceUsage 方法,該方法報告程序的 CPU 和記憶體使用量。

import { spawnSync } from "bun";

// for spawnSync, it is a property on the return value
const { resourceUsage } = spawnSync([
  "bun",
  "-e",
  "console.log('Hello world!')",
]);

console.log(resourceUsage);

// in Bun.spawn, it is a function that you call

這會印出

ResourceUsage {
  contextSwitches: {
    voluntary: 0,
    involuntary: 120,
  },
  cpuTime: {
    user: 5578n,
    system: 4488n,
    total: 10066n,
  },
  maxRSS: 22020096,
  messages: {
    sent: 0,
    received: 0,
  },
  ops: {
    in: 0,
    out: 0,
  },
  shmSize: 0,
  signalCount: 0,
  swapCount: 0,
}

感謝 @cirospaciari 的貢獻!

我們使用它來編寫測試,以防止 setTimeout 在 Linux 上導致高 CPU 使用率的迴歸錯誤再次發生。

基礎架構改進

在 Bun 的偵錯組建中,我們新增了對 macOS 的 'malloc zone' 功能的支援,以更準確地追蹤原生程式碼中的記憶體分配。這有助於我們識別記憶體洩漏。

這會印出如下的輸出

DefaultMallocZone:
  blocks_in_use:   278
  size_in_use:     2318192
  max_size_in_use: 2696288
  size_allocated:  19922944

WebKit Malloc:
  blocks_in_use:   0
  size_in_use:     0
  max_size_in_use: 0
  size_allocated:  0

Bun__Response:
  blocks_in_use:   2
  size_in_use:     240
  max_size_in_use: 16976
  size_allocated:  1048576

Bun__BufferOutputSink:
  blocks_in_use:   1
  size_in_use:     32
  max_size_in_use: 16832
  size_allocated:  1048576

我們也變更了我們執行 JavaScript 字串的跨執行緒複製的方式。先前,我們有時會將字串複製兩次,然後從未使用第一個副本。這非常浪費。現在,我們只複製字串一次,且僅在我們確實需要時才複製。

bun init 現在使用 @types/bun

bun init 現在使用 @types/bun 而不是 bun-types,並且我們啟用了一些新選項,例如 verbatimModuleSyntax

感謝 @ArnaudBarre 的貢獻!

感謝五位貢獻者!

完整變更日誌