我們正在招募 C/C++ 和 Zig 工程師,一同打造 JavaScript 的未來!
Bun v0.5 滿載新功能,包含 npm workspaces
、Bun.dns
,以及支援 node:readline
。也改善了與 node:tls
和 node:net
的相容性,因此數個資料庫驅動程式首次能在 Bun 中運作,包含 Postgres.js、mysql2
、node-redis
以及其他。Bun 也持續變得更快更穩定 — Buffer
實例化速度提升 10 倍、crypto.createHasher()
速度提升 50 倍,而 bun install
修正了數十個錯誤。
# Install Bun
curl https://bun.dev.org.tw/install | bash
# Upgrade to latest release of Bun
bun upgrade
package.json
中的 Workspaces
Bun 現在支援 package.json
中的 workspaces
,而且速度很快。Bun 在 Linux 上安裝 Remix monorepo 約需 500 毫秒。
- 比
npm install
快 28 倍 - 比
yarn install
(v1) 快 12 倍 - 比
pnpm install
快 8 倍

什麼是 workspaces?
Workspaces 讓開發複雜軟體變得容易,以包含數個獨立套件的 monorepo 形式。若要嘗試使用,請在您的 package.json
的 workspaces
欄位中指定子套件列表;慣例上會將這些子套件放置在名為 packages
的目錄中。
{
"name": "my-project",
"version": "1.0.0",
"workspaces": ["packages/a", "packages/b"]
}
Bun 尚未支援 workspace 名稱的 glob 模式,但即將推出!
這有幾個主要優點。
- 程式碼可以拆分為邏輯部分。 如果一個套件依賴另一個套件,您可以簡單地使用
bun add
將其新增為依賴項。如果套件b
依賴a
,bun install
會將您的本地packages/a
目錄符號連結到b
的node_modules
資料夾中,而不是嘗試從 npm 登錄檔下載它。 - 依賴項可以重複資料刪除。 如果
a
和b
共用一個常見的依賴項,它將被提升 (hoisted) 到根node_modules
目錄。這減少了多餘的磁碟使用量,並盡可能減少了與同時安裝多個套件版本相關的「依賴地獄」問題。
Bun.dns
和 node:dns
Bun 現在可以使用內建的 Bun.dns
API 解析網域名稱。目前,Bun.dns
公開一個單一函式:lookup
。
import { dns } from "bun";
const records = await dns.lookup("example.com", { family: 4 });
console.log(records); // [{ address: "93.184.216.34" }]
我們也新增了 Node.js node:dns
的最簡實作,底層使用 Bun.dns
。它由 c-ares 和 MacOS 上的非阻塞 getaddrinfo
提供支援。
import { resolve4 } from "node:dns/promises";
const records = await resolve4("example.com");
console.log(records); // [ "93.184.216.34" ]
使用 node:tls
和 node:net
的 Sockets
Bun 現在支援使用 net.connect()
和 tls.connect()
建立 sockets。這解鎖了數個資料庫驅動程式庫。一些具代表性的範例:
使用 Postgres.js by @porsager 連接到 Bun 中的 Postgres
import postgres from "postgres";
const sql = postgres();
const [{ version }] = await sql`SELECT version()`;
console.log(version); // "PostgreSQL 14.2 ..."
使用 mysql2
client by @sidorares 連接到 Bun 中的 MySQL
import { createConnection } from "mysql2/promise";
const connection = await createConnection({
host: "localhost",
user: "root",
database: "test",
});
const [rows] = await connection.execute("SELECT 1+2 AS count");
console.log(rows); // [{ count: 3 }]
使用官方 Node.js client 從 Bun 連接到 Redis
import { createClient } from "redis";
const client = createClient();
await client.connect();
await client.set("key", "Hello!");
const value = await client.get("key");
console.log(value); // "Hello!"
支援 node:readline
由於 Bun 現在支援 node:readline
模組,建置 CLI 工具應該會變得更加容易。
import * as readline from "node:readline/promises";
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
terminal: true,
});
const answer = await rl.question("How fast is Bun from 1 to 10?\n");
if (parseInt(answer) > 10) {
console.log("Good answer!");
}
執行此腳本會產生
bun readline.ts
How fast is Bun from 1 to 10?
11
Good answer!
WebSocket
中的自訂 headers
WebSocket
規範 上一個長期存在的功能請求是,在開啟 WebSocket 時設定自訂 headers 的能力。雖然這尚未在 WebSocket 標準中實現,但 Bun 現在實作了它。這允許使用者自訂用於 WebSocket
client 握手請求 的 headers。
const ws = new WebSocket("ws://127.0.0.1/chat", {
headers: {
Authorization: "...",
},
});
bun wiptest
的改進
雖然 bun wiptest
仍是進行中的工作,但我們持續增加 Bun 與 Jest 的相容性。
test.skip()
您可以使用 test.skip()
來跳過不需要的測試。
import { describe, test, expect } from "bun:test";
describe("fetch()", () => {
test.skip("can connect to localhost", async () => {
const response = await fetch("https://127.0.0.1");
expect(response.ok).toBe(true);
});
test("can connect to example.com", async () => {
const response = await fetch("http://example.com");
expect(response.ok).toBe(true);
});
});
當您跳過測試時,它將在測試輸出中顯示為灰色。

expect(fn).toThrow()
您可以使用 expect(fn).toThrow()
來捕獲預期的錯誤。
import { test, expect } from "bun:test";
test("catch error", async () => {
expect(() => {
throw new Error();
}).toThrow();
});
describe
標籤包含在輸出中
先前,巢狀 describe
標籤未包含在測試執行器輸出中。感謝 @ethanburrell,此問題已修正。
之前
✓ outer > my test
之後
✓ outer > inner > my test
測試檔案
import { describe, test } from "bun:test";
describe("outer", () => {
describe("inner", () => {
test("my test", () => {});
});
});
效能提升
new Buffer()
快 10 倍
先前,Bun 中的 Buffer
實作使用 Object.setPrototypeOf()
來建立每個新實例。消除此瓶頸使在 Bun 中實例化小型 Buffer
快 10 倍。

crypto.createHash()
快 50 倍
先前,Bun 使用純 JavaScript 實作 crypto.createHash()
。現在它使用來自 BoringSSL 的原生程式碼實作,效能提升 50 倍。
支援 HTTPS_PROXY
Bun 現在將在發出外送 HTTP 請求時辨識 HTTPS_PROXY
、HTTP_PROXY
和 NO_PROXY
環境變數,包含 fetch()
和 bun install
。這些變數讓您可以指定代理伺服器來轉發或不轉發特定的 HTTP 請求,在公司防火牆內執行 Bun 時非常有用。
export HTTPS_PROXY="http://proxy.example.com:8080"
export NO_PROXY="localhost,noproxy.example.com"
如果您想了解更多關於這些變數的資訊,GitLab 撰寫了一篇不錯的解釋文章。
模組解析變更
模組解析有兩個變更可能會影響少數套件。
- Bun 不再檢查
package.json
中的browser
屬性。這是因為某些套件會停用 Node.js 功能,這不是我們對 Bun 想要的。 - 為了更好的 Node.js 和 npm 相容性,Bun 的 JavaScript 執行時環境現在會讀取 package.json
exports
中的"node"
匯出條件。
Bun 的 JavaScript 執行時環境讀取 package.json "exports"
條件的順序為
["bun", "worker", "module", "node", "browser", "default"];
這表示如果套件具有 "node"
匯出條件,將會使用它來取代 "default"
或 "browser"
匯出條件。
變更日誌
當我們持續為 Bun 新增功能時,我們仍然專注於提高穩定性和修正錯誤。此版本修正了許多問題:
bun install
的修正
Bun 套件管理員的數個錯誤在此版本中已修正,主要由 @alexlamsl 完成。感謝 Alex!
#1664 | 先前,使用 bun install 設定的 scoped 和 private 套件會具有 localhost 的登錄檔,這非常沒有道理。我們已修正此問題,如果未指定,private 登錄檔現在將預設為預設登錄檔,通常是 registry.npmjs.org 。 |
#1667 | 通常,npm client 應該要傳遞 npm-auth-type header,但 bun install 沒有。我們已修正此問題,現在 bun install 將會傳遞 npm-auth-type header。 |
a345efd | 在某些 CI 環境中,例如 Vercel,連結 node_modules/.bin 會失敗,因為未掛載 /proc 檔案系統 (用於解析絕對檔案路徑)。我們已透過在 /proc/fd 無法使用時回退到 fchdir 和 getcwd 來修正此問題。 |
385c81d | 當 package.json 中的 "dependencies" 列表從空白變為非空白時,執行 bun add <package> 有時會發生當機。 |
#1665 | 當設定 scopes 時,使用 npm 作為預設登錄檔 |
#1671 | 修正 bun install 中的記錄詳細程度 |
#1799 | 修正 bun install 中的生命週期腳本執行 |
新 API
6260aaa | 實作 crypto.scrypt() 和更多 node:crypto API |
d726a17 | 實作 Bun.RIPEMD160 |
940ecd0 | 實作 process.uptime() 和 process.umask() |
85eda20 | 實作 Bun.CryptoHasher |
#1727 | 實作 expect().toThrow() |
#1659 | 實作 Buffer.{swap16,swap32,swap64} — @malcolmstill |
c18165b | 在 Bun.listen() 中新增對 ttl: true 的支援 |
734b5b8 | 為 Server.stop() 和 Socket.stop() 新增 closeActiveConnections 參數 |
8e9af05d | 變更 WebSocket 以接受具有 http 或 https 協定的 URL |
其他修正
#1670 | 修正不正確的 206 Partial Content 回應 |
#1674 | 修正 console.log({ name: "" }) 會印出不正確格式的錯誤 |
3d60b87 | 修正 ReadableStream.pipeTo() |
#1689 | 修正 bun wiptest 未等待非同步生命週期 hooks |
#1700 | 修正 Bun.listen() 和 Bun.connect() 的殘留程序 |
#1705 #1730 | 修正未以 Bun.listen() 呼叫 connectError 回呼的問題 |
#1695 | 修正影響 @tensorflow/tfjs-backend-wasm 的轉譯器錯誤 — @theoparis |
#1716 | 修正 TextDecoder 被匯出為 TextEncoder 的錯誤 (糟糕!) — @torbjorn-kvist |
#1734 | 修正未處理的 Promise 拒絕未導致錯誤結束代碼的問題 |
fadd1c0 | 修正 Bun.connect() 不會在連線錯誤時拒絕的問題 |
2392e48 | 修正 describe 區塊中未捕獲的錯誤會結束 bun wiptest 的問題 |
88ffdc5 | 修正 export default class implements 的轉譯器錯誤 |
#1800 | 修正 Response 不接受 2xx 以下 status 的問題 |
7dd28bb | 修正 Bun.which() 會意外偵測到 macOS 上的目錄的問題 |
— | 修正各種錯誤並改善與 Node-API 的相容性:59655d0 f79301c 994e58b c505f17 02f0212 d54e23c 59655d0 f79301c |
貢獻者
感謝所有為 Bun v0.5 做出貢獻的人!
- @Vexu 協助將 Bun 升級到最新版本的 Zig
- @alexlamsl 貢獻
npm
workspaces、net.Socket
、bun install
的改進以及許多非常多的錯誤修正 - @ThatOneBro 貢獻
node:readline
- @colinhacks 引入
bun-types@canary
的 Canary 版本 - @cirospaciari 實作
HTTP_PROXY
支援 - @srh、@lucifer1004、@u9g、@eltociear、@jiaz、@malcolmstill 和 @ethanburrell 對 Bun 的貢獻