今天,Bun 有兩個主要優先事項:與 Node.js 和 Web API 穩定性和相容性。在 v0.3.0 中,我們在這兩個目標上都取得了重大進展。有很多變更要介紹,因此我們先從重點開始。
注意 — 我們是一個小型團隊,致力於讓使用 JavaScript 進行建置更快更簡單。如果您有興趣加入我們,請查看我們的職涯頁面,我們正在招聘 JavaScript、C/C++ 和 Zig 工程師!
安裝方式
curl -fsSL https://bun.dev.org.tw/install | bash
升級方式
bun upgrade
穩定性改進
Bun 現在在負載下使用的記憶體減少 3-5 倍。先前,Bun 未協調事件迴圈排程垃圾收集。(請參閱此處的基準測試)
Bun 現在針對
console.log()
具有更好的格式設定(對於偵錯很重要!)Bun 已修正文字編碼的數個錯誤,現在使用 simdutf 以實現 速度快 3 倍 的
TextEncoder.encodeInto()
Bun 現在可在更多 Linux 環境中運作,包括 Amazon Linux 2 以及適用於 Vercel 和 Cloudflare Pages 的組建。(先前,您可能看過類似「version 'GLIBC_2.29' not found」的錯誤)
還有許多其他變更
- 提高
fetch()
、Bun.spawn()
和Bun.spawnSync()
、串流檔案等的測試涵蓋率 - 改進 JavaScriptCore 和 Zig 之間的繫結,這導致許多垃圾收集器相關當機正在修正
- 修正使用
WebCrypto
時的各種問題 - 修正
fetch()
的編碼和壓縮問題 - 修正
fetch()
中的資料損毀錯誤 - 修正在
setTimeout()
內執行非同步程式碼時當機的問題
Node.js 相容性
Bun 現在支援下列 Node.js API
node:child_process
process.stdout
、process.stderr
和process.stdin
Error.captureStackTrace()
(從 V8 移植到 WebKit)fs.createWriteStream()
和fs.createReadStream()
process.release
全新和改進的 API
一覽,以下是變更內容
console
現在是AsyncIterable
FileSystemRouter
是類似 Next.js 的檔案系統路由器,用於解析檔案bun:ffi
現在支援從原生程式碼到 JavaScript 的 安全執行緒回呼bun:test
取得 10 個新比對器,例如expect().toEqual()
bun:test
支援用於非同步測試的done
回呼- 串流檔案時,
Bun.serve()
的Content-Range
標頭支援 - Bun 的轉譯器適用於 TypeScript
satisfies
關鍵字 WebSocketServer
取得publish()
方法,可將訊息發佈到所有用戶端Array.fromAsync()
和ArrayBuffer.resize()
,感謝 WebKitBun.file().size
現在一律回報 數字Headers
取得.toJSON()
和.getAll("Set-Cookie")
的支援Bun.deepEquals()
,由expect().toEqual()
使用
console
現在是 AsyncIterable
Bun 正在使用對非瀏覽器有意義的 API,讓您更容易從主控台讀取輸入。console
現在是 AsyncIterable
,可讓您透過對 console
進行 for await
迴圈,從 stdin 串流文字行。
for await (const line of console) {
console.log("Received:", line);
}
若要寫入 stdout,您也可以使用 console.write()
,這會略過 console.log()
的格式設定。
console.write("hello");
console.write("hello", "world", "\n");
const response = await fetch("https://example.com/");
console.write("Response: ", await response.arrayBuffer());
從 npm 自動安裝套件
當沒有 node_modules
目錄時,Bun 現在會自動從 npm 安裝 import
上的套件。為了節省磁碟空間,套件會下載到共用全域快取目錄中。為了安全起見,不會執行 postinstall
指令碼。

若要指定套件版本,您可以繼續使用 package.json
,也可以在 import
路徑中包含範圍指定詞。只有在沒有 package.json
的情況下才支援這些範圍指定詞。
import { renderToReadableStream } from "react-dom@latest/server";
import { serve } from "bun";
serve({
async fetch(req) {
const stream = await renderToReadableStream(
<html>
<body>
<h1>Hello, world!</h1>
</body>
</html>,
);
return new Response(stream);
},
});
Bun 繼續支援 node_modules
資料夾,這表示這不是重大變更。如果您想要停用此功能,可以使用 --no-install
旗標執行 Bun。
FileSystemRouter
Bun 現在公開 FileSystemRouter
,這是一個快速 API,用於針對檔案系統路由器解析傳入路徑。初始化後,它可以快速針對路由器解析路徑或 Request
。
請考慮下列 Next.js 樣式 pages
目錄
/path/to/project
├── server.ts
├── pages
├── index.tsx
├── settings.tsx
├── blog
│ ├── index.tsx
│ └── [slug].tsx
└── [[...catchall]].tsx
在 server.ts
中,您可以初始化指向 pages
目錄的 FileSystemRouter
。
import { FileSystemRouter } from "bun";
const router = new FileSystemRouter({
dir: import.meta.dir + "/pages",
style: "nextjs",
});
路由器樣式 — 目前,唯一支援的 style
是 nextjs
。我們計劃在未來支援其他樣式,包括 Next.js 13 樣式 app
目錄。
您可以使用 router
執行個體來針對您定義的頁面解析傳入的要求。此比對是在原生程式碼中實作,而且比以 JavaScript 為基礎的路由器快得多。
router.match("/");
// { filePath: "/pages/index.tsx" }
router.match("/blog");
// { filePath: "/pages/blog/index.tsx" }
router.match("/blog/my-first-post?foo=bar");
// {
// filePath: "/pages/blog/[slug].tsx" }
// params: { slug: "hello-world" },
// query: { foo: "bar" }
// }
bun:test
中的 Expect 比對器
已在 bun:test
中實作 expect()
比對器上的更多方法。我們也對 expect()
進行效能改進,這使得 toEqual()
比 Jest 快 100 倍。長期而言,我們希望 bun:test 成為使用 Jest 和 Vitest 的公司的極快速直接替換方案。
import { test, expect } from "bun:test";
test("new expect() matchers", () => {
expect(1).not.toBe(2);
expect({ a: 1 }).toEqual({ a: 1, b: undefined });
expect({ a: 1 }).toStrictEqual({ a: 1 });
expect(new Set()).toHaveProperty("size");
expect([]).toHaveLength(0);
expect(["bun"]).toContain("bun");
expect(true).toBeTruthy();
expect(Math.PI).toBeGreaterThan(3.14);
expect(null).toBeNull();
});
注意 — 您可以使用 bun wiptest
試用測試執行器。
Headers
上的新方法
Headers
類別現在實作 .getAll()
和 .toJSON()
方法。這些在技術上都是非標準方法,但我們認為它們會讓您的生活更輕鬆。
const headers = new Headers();
headers.append("Set-Cookie", "a=1");
headers.append("Set-Cookie", "b=1; Secure");
console.log(headers.getAll("Set-Cookie")); // ["a=1", "b=1; Secure"]
console.log(headers.toJSON()); // { "set-cookie": "a=1, b=1; Secure" }
可調整大小的 ArrayBuffer
和可成長的 SharedArrayBuffer
在 WebKit 中實作了 .resize()
ArrayBuffer
和 .grow()
SharedArrayBuffer
的能力,現在 Bun 中已提供。感謝 WebKit!
const buffer = new ArrayBuffer({
byteLength: 1024,
maxByteLength: 2048,
});
console.log(buffer.byteLength); // 1024
buffer.resize(2048);
console.log(buffer.byteLength); // 2048
Array.fromAsync()
WebKit 中也實作了 Array.fromAsync()
方法,現在 Bun 中已提供。它類似於 Array.from()
,但它接受非同步可迭代輸入。再次感謝 WebKit!
async function* listReleases() {
for (let page = 1; ; page++) {
const response = await fetch(
`https://api.github.com/repos/oven-sh/bun/releases?page=${page}`,
);
const releases = await response.json();
if (!releases.length) {
break;
}
for (const release of releases) {
yield release;
}
}
}
const releases = await Array.fromAsync(listReleases());
變更記錄
還有許多其他變更!以下是完整清單
- 修正各種記憶體洩漏 -
a9aa3e7
、1cce9da
、9090f06
- 實作
process.release
-901c4f5
- 修正
RegExp
的各種錯誤 -5398ed5
、#1537
、#1528
、74e87b5
- 修正
fs.stat()
的問題 -f9f169b
- 防止
process.stdout
和process.stderr
關閉 -8519ff0
- 變更
Blob.size
的行為,以針對非檔案回報Infinity
-d5c81b7
- 修正
spawn()
的不正確exitCode
-30e1fe1
- 修正 TypeScript 中
export = value
的不正確轉譯 -1cb5a73
- 修正當父進程被終止時,
spawn()
未被終止的問題 -1f174b9
- 修正當
port
不是數字時的無聲錯誤 -e5b2e3c
- 新增
done
回呼以支援bun:test
中的非同步函式 -c00359a
- 修正
process.nextTick()
的各種問題 -fd26d2e
、2eb19a9
- 修正
console.log(Request)
顯示空白url
的問題 -cb41d77
- 實作
AbortSignal.timeout()
-fe4f39f
- 支援 package.json 中的萬用字元
imports
-a3dc33c
- 修正計時器不必要地讓進程保持運作的問題 -
f408749
- 修正物件擴展
process.env
時的問題 -a6cadce
- 修正在
Response.arrayBuffer()
會傳回Uint8Array
的錯誤 -de9a2b9
- 針對
Bun.spawn()
實作signalCode
-0617896
- 支援在提供檔案時的
Content-Range
標頭 -0617896d
- 支援使用
bun link
時的bin
-0642cf3
- 改進
console.log()
的輸出 -c65c320
- 修正串流過早關閉的問題 -
d68f44d
- 修正使用含表情符號的
console.log()
時的問題 -3cb462a
- 修正連線到
localhost
時的問題 -d90a638
- 修正
Request.url
未顯示Host
標頭中的值的問題 -da25733
- 修正
HTMLRewriter
中text
未正確複製時的記憶體問題 -a85826
、904716f
- 修正在
WebSocket
開啟事件中擲回例外狀況時的問題 -c52ebd9
- 新增對預先發行識別碼之前沒有
-
的 npm 套件的支援(例如1.0.0beta
)-5f5ef81
- 改進
Bun.spawn()
和node:child_process
的 IO 輪詢效能 -#1496
- 修正 Linux 上無限 IO
write()
-a78b6f9
- 新增
fs.rmdir()
的支援 -92b7660
- 修正在主體未壓縮時 gzip 解壓縮的問題 -
#1510
- 修正
fetch()
的 URL 中有@
的問題 -6c01a11
- 修正
fetch()
的 URL 中有尾端/
的問題 -4f22c39
- 修正
console.log()
期間的罕見當機問題 -b0c89ba
- 改進
node:http.createServer()
的支援 -bf6b174
- 實作
FileSink.ref()
和FileSink.unref()
-d1a4f4f
- 實作
console.timeLog()
-f677919
- 修正
fs.createWriteStream()
-#1433
- 支援 TypeScript 裝飾器 -
#1445
- 支援使用
bun:ffi
的 JavaScript 回呼 -81033c5
- 新增屬性,讓 JavaScript 回呼使用
bun:ffi
標記為threadsafe
-006a2f3
- 修正各種
WebCrypto
問題和當機 -#1448
、#1450
- 修正
Bun.which()
未處理絕對路徑的問題 -d6520cd
- 允許 URL 用作
fetch()
的引數 -#1460
- 修正遭拒絕的 Promise 未在
bun:test
中觸發測試失敗的問題 -370d9c
- 修正環境變數被強制轉換為非字串的問題 -
#1256
- 讓小型輸入的
TextDecoder
速度加快 20% -160466
- 修正
os.EOL
的不正確值 -8b0a3c7
- 修正
Buffer.toString("base64")
有時不正確的問題 -af39313
- 修正使用
bun install
時的不正確檔案權限 -2c4777
- 支援 TypeScript
satisfies
-565996
- 實作在事件處理常式外部叫用時的
WebSocketServer.publish()
-8753c48
- 改進 Node.js 串流的效能 -
#1502
- 修正
bun:sqlite
將數字截斷為 int32 而非 int52 的問題 -ce6fc86
- 修正 HTTP 狀態文字與標準不符的問題 -
949d715
- 修正
bun:sqlite
未正確處理 latin1 字元的問題 -c65c320
- 支援
fetch()
中的手動重新導向 -5854d39
- 修正
fetch()
重新導向遺失port
的問題 -f8d9a8b
- 修正
fetch()
回應主體格式錯誤的問題 -b230e7a