Bun v0.8.0 新增了偵錯器支援,實作了 fetch 串流,並解鎖了 SvelteKit。實作了來自 node:tty
的 ReadStream 和 WriteStream,且 .setRawMode()
現在可在 process.stdin
上運作,解鎖了數個互動式 CLI 工具。此外還有 Node.js 相容性更新、錯誤修正和穩定性改善。
Bun 1.0 即將在 9 月 7 日推出!請在 https://bun.dev.org.tw/1.0 註冊以收看發佈直播。
Bun 是一個速度極快的 JavaScript 執行階段、打包器、轉譯器和套件管理器 — 功能All-in-One。我們最近發佈了很多 Bun 的變更。以下是最近幾個版本的重點回顧。以防您錯過了
v0.7.0
- Web Workers、--smol
、structuredClone()
、WebSocket 可靠性改善、node:tls
修正及更多。v0.7.1
- ES Modules 載入速度提升 30-250%、fs.watch
修正及許多node:fs
相容性改善。v0.7.2
- 實作node:worker_threads
、node:diagnostics_channel
和BroadcastChannel
。v0.7.3
-bun test
中的覆蓋率報告,以及使用bun test -t
進行測試篩選。
若要安裝 Bun
curl -fsSL https://bun.dev.org.tw/install | bash
npm install -g bun
brew tap oven-sh/bun
brew install bun
docker pull oven/bun
docker run --rm --init --ulimit memlock=-1:-1 oven/bun
若要升級 Bun
bun upgrade
偵錯器支援
Bun 現在透過 WebKit 的 Inspector Protocol 實作偵錯器支援。若要使用,請使用 --inspect
旗標執行您的檔案或指令碼。考量以下簡單的 HTTP 伺服器。
const server = Bun.serve({
fetch(req){
console.log(req.url);
return new Response("Hello world!");
}
});
console.log(`Listening on https://127.0.0.1:${server.port}`);
當我們使用 --inspect
執行此檔案時,它會啟動我們的 HTTP 伺服器並在未使用的連接埠上啟動 localhost WebSocket 伺服器。此 WebSocket 伺服器使用 Inspector Protocol 與偵錯工具通訊,偵錯工具可以內省和控制正在執行的 bun
程序。
bun --inspect server.ts
Listening on https://127.0.0.1:3000
------------------ Bun Inspector ------------------
Listening at:
ws://127.0.0.1:6499/0tqxs9exrgrm
Inspect in browser:
https://debug.bun.sh/#localhost:6499/0tqxs9exrgrm
------------------ Bun Inspector ------------------
使用 debug.bun.sh
--inspect
旗標也會在主控台中列印 https://debug.bun.sh#
URL。網域 debug.bun.sh
託管了 Safari Developer Tools 的精簡版本,專為 Bun 偵錯而設計。在您偏好的瀏覽器中開啟連結,新的偵錯工作階段將自動開始。
從網頁偵錯器,您可以檢查目前正在執行的程式碼並設定中斷點。一旦觸發中斷點,您可以
- 檢視範圍內的所有變數
- 在主控台中執行程式碼,完全存取範圍內的變數和 Bun API
- 逐步執行您的程式碼
請參閱 使用網頁偵錯器偵錯 Bun 指南以取得更完整的說明文件。
bun update
新的 bun update
命令會將所有專案依賴項更新為與您 package.json
中的語意版本範圍相容的最新版本。
bun update
若要更新特定的依賴項
bun update zod
注意 — 與 npm
不同,bun upgrade
命令保留用於升級 Bun 本身。它不是 bun update
的別名。
感謝 @alexlamsl 實作此功能。
SvelteKit 支援
改善對 Worker
中的環境變數 的支援,已解鎖 SvelteKit。使用 create-svelte
建立您的專案骨架。
bunx create-svelte my-app
create-svelte version 5.0.5
┌ Welcome to SvelteKit!
│
◇ Which Svelte app template?
│ SvelteKit demo app
│
◇ Add type checking with TypeScript?
│ Yes, using TypeScript syntax
│
◇ Select additional options (use arrow keys/space bar)
│ none
│
└ Your project is ready!
✔ Typescript
Inside Svelte components, use <script lang="ts">
Install community-maintained integrations:
https://github.com/svelte-add/svelte-add
若要安裝依賴項並啟動開發伺服器
cd my-app
bun install
bun run dev -- --open
開啟 localhost:3000
以查看運作中的 SvelteKit 示範應用程式。
Nuxt 支援 (nuxt dev
)
透過改善 node:tty
和 node:fs
支援,Nuxt 開發伺服器現在可與 Bun 執行階段搭配使用。若要開始使用,請使用 nuxi
命令列工具。
bunx --bun nuxi init my-app
cd my-app
bun install
安裝依賴項後,使用 "dev"
package.json 指令碼啟動開發伺服器。
bun --bun run dev
$ nuxt dev
Nuxt 3.6.5 with Nitro 2.5.2
> Local: https://127.0.0.1:3000/
> Network: http://192.168.0.21:3000/
> Network: http://[fd8a:d31d:481c:4883:1c64:3d90:9f83:d8a2]:3000/
✔ Nuxt DevTools is enabled v0.8.0 (experimental)
ℹ Vite client warmed up in 547ms
✔ Nitro built in 244 ms
--bun
旗標確保伺服器使用 Bun 執行階段而不是 Node.js。依預設,nuxt
CLI 使用 Node.js。
然後瀏覽 https://127.0.0.1:3000 以查看預設的 Nuxt 歡迎畫面。
注意 — Nuxt 的 build
命令仍有一些問題。在執行生產建置時,請使用 bun run build
而不是 bun --bun run build
。這會使用 Node.js 執行 Nuxt 的建置管線。請在此處追蹤此問題 here。
請參閱 使用 Nuxt 和 Bun 建置應用程式 以取得更完整的逐步解說。
Fetch 回應主體串流
感謝 @cirospaciari,Bun 現在實作了 fetch()
回應主體串流。這表示您現在可以從 fetch 回應串流資料,而無需等待下載整個回應。
const res = await fetch("https://example.com/bigfile.txt");
// read the response chunk-by-chunk!
for await (const chunk of res.body) {
console.log(chunk);
}
在 Bun 中使用 OpenAI
當使用需要較長時間才能回應的 API 時,串流特別有用。現在您可以在 Bun 中串流來自 OpenAI API 的回應。
import OpenAI from "openai";
const openai = new OpenAI({
apiKey: "my api key",
});
const stream = await openai.chat.completions.create({
model: "gpt-4",
messages: [{ role: "user", content: "Say this is a test" }],
stream: true,
});
for await (const part of stream) {
process.stdout.write(part.choices[0]?.delta?.content || "");
}
Bun.serve()
串流改善
先前,以下程式碼會緩衝回應主體,表示它只會在產生整個主體後才傳送回應。
import { serve, sleep } from "bun";
serve({
fetch(req) {
return new Response(
new ReadableStream({
async pull(controller) {
for (let i = 0; i < 20; i++) {
controller.enqueue("Hello world!");
await sleep(42);
}
controller.close();
},
}),
);
},
});
// Hello World!Hello World!Hello World!...[~840ms]
這不是人們想要的!現在,回應主體會進行串流,表示它會在產生時傳送至用戶端。
import { serve, sleep } from "bun";
serve({
fetch(req) {
return new Response(
new ReadableStream({
async pull(controller) {
for (let i = 0; i < 20; i++) {
controller.enqueue("Hello world!");
await sleep(42);
}
controller.close();
},
}),
);
},
});
// Hello world! [42ms]
// Hello world! [42ms]
// Hello world! [42ms]
先前,僅在使用 ReadableStream 且 type: "direct"
時才支援串流,這是 Bun 特有的快速串流路徑。
import { serve, sleep } from "bun";
serve({
port: 3000,
fetch(req) {
return new Response(
new ReadableStream({
// bun specific option
type: "direct",
async pull(controller) {
for (let i = 0; i < 20; i++) {
controller.write("Hello world!");
// in bun < 0.8.0, flush() was required
controller.flush();
// now bun will automatically flush pending writes once the microtask queue is drained
await sleep(42);
}
controller.end();
},
}),
);
},
});
// Hello world! [42ms]
// Hello world! [42ms]
// Hello world! [42ms]
// Hello world! [42ms]
我們還有最佳化工作要做,以使使用預設 ReadableStream 類型的串流變得快速。目前,我們建議使用 type: "direct"
以獲得最快的串流速度。
支援 node:tty
和 process.stdin.setRawMode()
已實作來自 node:tty
的 ReadStream
和 WriteStream
類別,且 process.stdin
現在是 ReadStream
的執行個體。因此,現在可以在 process.stdin
上啟用「原始模式」。
process.stdin.setRawMode(true);
支援 inquirer
和其他提示程式庫
這使得無需等待換行字元即可讀取按鍵輸入,這對於互動式 CLI 工具非常重要。現在完全支援熱門程式庫 inquirer
、enquirer
和 prompts
。
執行以下命令以使用 Bun 和互動式 create-remix
命令列工具互動式地建立 Remix 應用程式骨架。
bunx --bun create-remix
感謝 @dylan-conway 實作此功能。
bun test
的改善
test.each
和 describe.each
感謝 @jecquas,Bun 現在支援 Jest 中的 test.each
和 describe.each
。這使得使用不同輸入執行相同測試變得容易。
describe.each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
])("add(%i, %i)", (a, b, expected) => {
test(`returns ${expected}`, () => {
expect(a + b).toBe(expected);
});
});
.toSatisfy()
和 .toIncludeRepeated()
感謝 @TiranexDev,bun test
現在支援 其他匹配器。這些匹配器是 jest-extended
的一部分,現在由 bun test
原生支援。
.toSatisfy()
的範例用法
const isOdd = (value: number) => value % 2 !== 0;
it("toSatisfy", () => {
expect(1).toSatisfy(isOdd);
expect(2).not.toSatisfy(isOdd);
});
.toIncludeRepeated()
的範例用法
test("toIncludeRepeated", () => {
// check if string contains substring exactly 2 times
expect("hello hello").toIncludeRepeated("hello", 2);
// works with .not
expect("hello hello world").not.toIncludeRepeated("hello", 1);
});
速度提升 40 倍的 buffer.toString("hex")
Node.js Buffer.toString("hex")
函數透過 SIMD 進行最佳化,效能提升 40 倍。
在 Bun 的下一個版本中
— Jarred Sumner (@jarredsumner) 2023 年 8 月 21 日
Buffer.toString("hex") 速度提升 40 倍 pic.twitter.com/Hz7rXBAjJw
Bun.inspect.custom
現在可以使用 Bun.inspect.custom
符號來擴增物件,以使用自訂格式器。基於相容性考量,Node.js node:util
中的 util.inspect.custom
也適用。
class Password {
value: string;
constructor(value: string) {
this.value = value;
}
[Bun.inspect.custom]() {
return "Password <********>";
}
}
const p = new Password("secret");
console.log(p);
// => "Password <********>"
全域 File
建構函式
已新增 File
建構函式作為新的全域變數。可以建構 File
執行個體。
const file = new File(["hello world"], "hello.txt", {
type: "text/plain",
lastModified: Date.now() - 1000,
});
file.size; // 11
file.name; // "hello.txt"
file.type; // "text/plain"
file.lastModified; // 1693597759310573
已修正 Buffer 相關函數中的當機問題
已修正 Buffer
相關函數中的 JIT 當機問題。此當機是由傳遞至 DOMJIT 時不正確的副作用所造成,這會在呼叫函數時導致類型驗證期間當機。這影響了數個程式庫,且當機在 Bun v0.7.3 中的 JavaScriptCore 升級後開始發生。
在足夠多次呼叫 Buffer.alloc
、Buffer.allocUnsafe
、Buffer.isBuffer
後,此當機會導致擲回 EXC_BREAKPOINT
。
錯誤修正和穩定性改善
Buffer.toString("hex") 記憶體洩漏修正
已修正 buffer.toString("hex")
實作中的記憶體洩漏問題。
NAPI 修正和 resvg
、sharp
支援
已修正 NAPIClass 建構函式
和 napi_create_external_arraybuffer
/ napi_create_external_buffer
中的幾個錯誤。這解決了使用 resvg-js
或 sharp
時的問題。
當 this
無效時,提供更佳的錯誤訊息
當使用非預期的 this
值呼叫方法時,Bun 現在會報告 資訊豐富的錯誤訊息。
const { json } = new Response(`"hello"`);
json();
// ^ TypeError: Expected `this` to be instanceof Response
處理跨裝置檔案複製
Bun 現在會偵測 檔案複製作業 (例如 fs.copyFile
) 何時嘗試跨裝置或分割區複製檔案,並回復為手動檔案複製系統呼叫。
修正 Bun.deepEqual
URL 比較
#4105
修正了 URL 未透過其內部 href
正確比較的錯誤。
已修正 macOS 上 async-await 效能的 10% 衰退問題
- 日光節約時間快取不再於每個微任務呼叫時更新。此衰退從 v0.7.x 開始發生。
數個串流修正
#4251
包含 ReadableStream
實作中的許多改善和錯誤修正。這包括
- 一旦微任務佇列已排空,HTTP 回應主體的擱置寫入會自動刷新,修正 #1886
- 改善
pull
內部的錯誤處理。
變更記錄
隨著 Bun 1.0 即將推出,我們一直在追蹤剩餘的記憶體洩漏和當機問題。
#4028 | [install] 正確處理現有 peerDependencies 的 bun add ,作者:@alexlamsl |
#4026 | 執行遺失的指令碼會以非 0 結束,作者:@YashoSharma |
#4030 | 繫結 require.resolve`()`,作者:@Jarred-Sumner |
#4034 | 正規化 Request URL,作者:@Jarred-Sumner |
#4042 | 修正 path.normalize 邊緣案例。作者:@Hanaasagi |
#4043 | 將 Bun 的轉譯器編譯為 WASM 並新增測試分析器,作者:@Jarred-Sumner |
#4048 | 修正使用 set-cookie 逐一查看標頭的問題,作者:@dylan-conway |
#4000 | 實作擷取資料 URL,作者:@dylan-conway |
#4054 | 修正 Bun.hash 函數,作者:@jhmaster2000 |
#4064 | 修正 path.format 相容性問題。作者:@Hanaasagi |
#4073 | 修正 require("console") #3820,作者:@paperclover |
#4076 | 在使用者建構的 CommonJSModuleRecords 中將 exports 設定為 {},作者:@paperclover |
#4086 | 修正 XLSX.read 核心傾印問題,作者:@Hanaasagi |
#4027 | 新增 bun --revision 支援,作者:@YashoSharma |
#4106 | 修正 base64url 編碼器中的區段錯誤 #4062,作者:@Jarred-Sumner |
#4109 | 處理 setInterval 的群體性湧入問題,作者:@Jarred-Sumner |
#4111 | 修正 Buffer.toString('base64url') 中的記憶體洩漏問題,作者:@Jarred-Sumner |
#4113 | 執行沒有副檔名的檔案,作者:@dylan-conway |
#4117 | 讓 astro build 稍微快一點 |
#4125 | 支援 TypeScript 的 export type * as Foo from 'bar' ,作者:@Jarred-Sumner |
#4126 | bun-wasm 修正和改善,作者:@jhmaster2000 |
#4131 | 棄用載入 node_modules.bun ,作者:@Jarred-Sumner |
#4129 | 修正自訂組態路徑無法運作的問題。作者:@Hanaasagi |
#4114 | 修正 worker 事件迴圈 ref/unref + 洩漏問題,作者:@paperclover |
#4152 | 讓內建來源起點使用有效的 url,作者:@paperclover |
#4155 | 修正匯入過長字串的問題,作者:@paperclover |
#4162 | 修正方法名稱錯字,作者:@Hanaasagi |
#4157 | 修正 Bun.connect 的事件迴圈問題,作者:@paperclover |
#4172 | 更新文件以說明我們目前的節點相容性狀態,作者:@paperclover,位於 https://github.com/oven-sh/bun/pull/4172 |
#4173 | 建立 domjit.test.ts,作者:@dylan-conway,位於 https://github.com/oven-sh/bun/pull/4173 |
#4150 | 修正 prisma linux 產生問題,作者:@cirospaciari,位於 https://github.com/oven-sh/bun/pull/4150 |
#4181 | 修正洩漏 .ptr 問題,作者:@Jarred-Sumner,位於 https://github.com/oven-sh/bun/pull/4181 |
#4192 | 更正指南的 bunfig 範例選項,作者:@xxxhussein,位於 https://github.com/oven-sh/bun/pull/4192 |
#4193 | 重構:將 HTMLRewriter 移至 c++ 繫結,作者:@bru02,位於 https://github.com/oven-sh/bun/pull/4193 |
#4191 | Fix(node:fs): 在 fs.read 回呼中新增 buffer 參數。作者:@Hanaasagi,位於 https://github.com/oven-sh/bun/pull/4191 |
#4154 | 允許覆寫 IncomingRequest.req。作者:@paperclover,位於 https://github.com/oven-sh/bun/pull/4154 |
#4098 | 支援 Nitro,作者:@paperclover,位於 https://github.com/oven-sh/bun/pull/4098 |
#4194 | 將 util.inspect.custom 支援新增至 util.inspect/Bun.inspect/console.log ,作者:@paperclover,位於 https://github.com/oven-sh/bun/pull/4194 |
#4187 | 移除大部分 C API 用法,為 Headers 、URLSearchParams 、FormData 、Worker 、EventTarget 新增偵錯器美化列印器,作者:@Jarred-Sumner,位於 https://github.com/oven-sh/bun/pull/4187 |
#4208 | 實作 BigIntStats,作者:@paperclover,位於 https://github.com/oven-sh/bun/pull/4208 |
#4206 | feat: 新增自動關閉 & can-have-content,作者:@bru02,位於 https://github.com/oven-sh/bun/pull/4206 |
#4213 | 當啟用 --inspect 時新增內嵌來源對應,作者:@Jarred-Sumner,位於 https://github.com/oven-sh/bun/pull/4213 |
#4220 | 修正 #172,作者:@Jarred-Sumner,位於 https://github.com/oven-sh/bun/pull/4220 |
#4221 | 修正影響 sharp & resvg 的當機問題,作者:@Jarred-Sumner,位於 https://github.com/oven-sh/bun/pull/4221 |
#4210 | 將不受支援(尚未)註解新增至 distroless 映像檔,作者:@o-az,位於 https://github.com/oven-sh/bun/pull/4210 |
#4163 | Fix(bundler): 根據目標使用不同的別名對應。作者:@Hanaasagi,位於 https://github.com/oven-sh/bun/pull/4163 |
#4231 | 修正來自 3a9a6c63a 的測試失敗問題,作者:@Jarred-Sumner,位於 https://github.com/oven-sh/bun/pull/4231 |
#4222 | 實作 --inspect-brk ,作者:@Jarred-Sumner,位於 https://github.com/oven-sh/bun/pull/4222 |
#4230 | 修正 #1675,作者:@Jarred-Sumner,位於 https://github.com/oven-sh/bun/pull/4230 |
#4235 | 修正 buffer.toString("hex") 中的記憶體洩漏問題,作者:@Jarred-Sumner,位於 https://github.com/oven-sh/bun/pull/4235 |
#4237 | Buffer.toString('hex') 速度提升 40 倍,作者:@Jarred-Sumner,位於 https://github.com/oven-sh/bun/pull/4237 |
#4243 | feat: 實作 Bun.inspect.custom,作者:@paperclover |
#4156 | 實作 napi_ref_threadsafe_function ,作者:@paperclover |
#4242 | 修正 crypto.EC 建構函式,作者:@paperclover |
#4226 | Fix(bundler): 允許在巢狀路徑中產生 exe 檔案。作者:@Hanaasagi |
#4245 | 修正使用退格鍵 + 引號的 emitKeyPresses 問題,作者:@paperclover |
#4127 | fetch(stream) 為壓縮和未壓縮資料新增串流支援,作者:@cirospaciari |
#4244 | 匯入錯誤的 code 設定為 ERR_MODULE_NOT_FOUND ,且 require 錯誤的 code 設定為 MODULE_NOT_FOUND ,作者:@Jarred-Sumner |
#4250 | 修正 stdin 串流 unref 和恢復問題,作者:@dylan-conway |
#4247 | 修正 fsevents 和 qwikcity 的 Stub,作者:@paperclover |
#4264 | fix(parser): ] 之前的 yield 不應是語法錯誤,作者:@paperclover |
#4256 | 在 PR 範本中要求 bun --revision 而不是 bun -v ,作者:@xHyroM |
#4273 | 修正更多類型。作者:@xxxhussein |
#4251 | 大量串流修正,作者:@Jarred-Sumner |