Bun v1.0.16 修復了 49 個錯誤(解決了 38 個 👍 表情符號)。針對 Bun.file 重寫了 IO,Bun.write 現在會自動建立父目錄(如果不存在),expect.extend
在 preload 內運作正常,napi_create_object
速度提升 2.5 倍,修復了模組解析影響 Astro v4 和 p-limit 的錯誤,console.log 錯誤修復,以及更多。
Bun 是一個速度極快的 JavaScript 執行時、打包器、轉譯器和套件管理器 — 功能All-in-One。如果您錯過了,這裡有一些 Bun 最近的變更
v1.0.12
- 新增了bun -e
用於評估腳本、bun --env-file
用於載入環境變數、server.url
、import.meta.env
、expect.unreachable()
、改進的 CLI 說明輸出等等v1.0.13
- 修復了 6 個錯誤(解決了 317 個 👍 表情符號)。現在 'http2' 模組和 gRPC.js 可以正常運作。Vite 5 和 Rollup 4 可以正常運作。實作 process.report.getReport(),改進了對 ES5 'with' 語句的支援,修復了 bun install 中的回歸錯誤,修復了列印例外時的崩潰問題,修復了 Bun.spawn 錯誤,並修復了 peer dependencies 錯誤v1.0.14
-Bun.Glob
,一個使用 glob 模式比對檔案和字串的快速 API。它還修復了在bun install
期間提取依賴項時的競爭條件,改進了node_modules
中的 TypeScript 模組解析,並使錯誤訊息更易於閱讀。v1.0.15
- 修復了 23 個錯誤(解決了 117 個 👍 表情符號),tsc
啟動速度提升 2 倍。穩定的WebSocket
客戶端、語法突顯的錯誤、更清晰的堆疊追蹤,使用expect.extend()
+ 其他 expect 比對器新增自訂測試比對器。
要安裝 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.write
現在會建立父目錄(如果不存在)
先前,如果目錄不存在,Bun.write
會拋出錯誤。現在,如果目錄不存在,它會建立目錄。
// script.ts
import { write } from "bun";
await write("i/dont/exist.txt", "Hello, world!");
現在,如果 i/dont
不存在,將會建立它。
$ bun script.ts
先前,它會拋出錯誤
1 | import { write } from "bun";
2 | await write("i/dont/exist.txt", "heyyy");
^
ENOENT: No such file or directory
path: "i/dont/exist.txt"
syscall: "open"
errno: -2
若要在父目錄不存在時拋出錯誤:createPath: false
可以透過將 createPath: false
傳遞給 Bun.write
來停用此行為。
// script.ts
import { write } from "bun";
await write("i/dont/exist.txt", "Hello, world!", { createPath: false });
現在,如果目錄不存在,它將拋出錯誤。
$ bun script.ts
1 | import { write } from "bun";
2 | await write("i/dont/exist.txt", "heyyy", { createPath: false });
^
ENOENT: No such file or directory
path: "i/dont/exist.txt"
syscall: "open"
errno: -2
在下一個 Bun 版本中
— Jarred Sumner (@jarredsumner) 2023 年 12 月 10 日
Bun.write() 將自動建立父目錄(如果不存在) pic.twitter.com/jNgjZ5LAtl
您執行
— Bun (@bunjavascript) 2023 年 12 月 7 日
await Bun.write(“/dir-doesnt-exist/file.txt”, “abc”)
您是否期望此函式拋出錯誤,因為 “dir-doesn’t-exist” 不存在?
針對 Bun.file
重寫 IO
Linux 上 Bun.file
的內部結構已重新編寫為使用 epoll 而不是 io_uring,這提高了在 Docker 和雲端主機(如 Vercel 和 Google Cloud Run)中的相容性。
這解決了使用 Bun.file
時與 EBADF
相關的 11 個問題
此變更的動機是 Docker 在 2023 年 11 月預設停用了 io_uring。
Bun.write() 和 Bun.file().text() 在並行負載下速度提升 3 倍
在此過程中,我們使用 Bun.file() 和 Bun.write() 提高了並行讀取和寫入檔案的效能。
讀取
❯ N=100 hyperfine "bun ./read.js" "bun-1.0.15 read.js" --warmup=20
Benchmark 1: bun ./read.js
Time (mean ± σ): 40.9 ms ± 2.9 ms [User: 27.6 ms, System: 181.7 ms]
Range (min … max): 37.1 ms … 48.3 ms 73 runs
Benchmark 2: bun-1.0.15 read.js
Time (mean ± σ): 134.5 ms ± 19.0 ms [User: 24.8 ms, System: 82.5 ms]
Range (min … max): 98.8 ms … 161.2 ms 23 runs
Summary
bun ./read.js ran
3.29 ± 0.52 times faster than bun-1.0.15 read.js
寫入
❯ N=100 hyperfine "bun ./write.js" "bun-1.0.15 write.js" --warmup=20
Benchmark 1: bun ./write.js
Time (mean ± σ): 35.0 ms ± 8.0 ms [User: 13.0 ms, System: 364.6 ms]
Range (min … max): 25.7 ms … 71.5 ms 83 runs
Benchmark 2: bun-1.0.15 write.js
Time (mean ± σ): 134.7 ms ± 13.6 ms [User: 23.6 ms, System: 193.3 ms]
Range (min … max): 117.8 ms … 171.2 ms 23 runs
Summary
bun ./write.js ran
3.85 ± 0.96 times faster than bun-1.0.15 write.js
read.js
const promises = new Array(parseInt(process.env.N || "20"));
for (let i = 0; i < promises.length; i++) {
promises[i] = Bun.file("out.log." + i).text();
}
await Promise.all(promises);
write.js
const toPipe = new Blob(["abc".repeat(1_000_000)]);
const promises = new Array(parseInt(process.env.N || "20"));
for (let i = 0; i < promises.length; i++) {
promises[i] = Bun.write("out.log." + i, toPipe);
}
await Promise.all(promises);
已修復:Bun.stdin.text() 讀取不完整
先前,Bun.stdin.text()
有時不會傳回來自 stdin 的所有資料。
import { stdin } from "bun";
console.log(await stdin.text());
$ echo "Hello, world!" | bun script.ts
先前,有時它會不列印任何內容
現在,它會列印完整輸入
Hello, world!
napi_create_object
速度提升 2.5 倍
在下一個 Bun 版本中
— Jarred Sumner (@jarredsumner) 2023 年 12 月 5 日
napi_create_object 速度提升 2.5 倍 pic.twitter.com/lXyj6koceT
expect
和 expect.extend
在 --preload
中
先前,expect
的作用域限定於個別測試檔案,如果在共用檔案中呼叫 expect.extend
,則會中斷。現在已修復此問題,您現在可以使用包含自訂比對器的共用檔案,例如。
import { expect } from "bun:test";
// Based off of from Jest's example documentation
// https://jest.dev.org.tw/docs/expect#expectextendmatchers
function toBeWithinRange(actual, floor, ceiling) {
const pass = actual >= floor && actual <= ceiling;
return {
pass,
message: () =>
"expected " +
this.utils.printReceived(actual) +
" to " +
(pass ? "not " : "") +
"be within range " +
this.utils.printExpected(`${floor} - ${ceiling}`),
};
}
expect.extend({
toBeWithinRange,
});
然後設定 bunfig.toml
以在測試期間載入它們,
test.preload = "./custom-matchers.ts"
並執行 bun test
import { expect, test } from "bun:test";
test("example", () => {
expect(1234).toBeWithinRange(1000, 2000);
});
example.test.ts:
-TypeError: expect.extend is not a function. (In 'expect.extend({
- toBeWithinRange
-})', 'expect.extend' is undefined)
- at /custom-matchers.ts:21:1
+✓ example [1.31ms]
您也可以在 test
回呼之外使用 expect()
。
-error: This function can only be used in a test.
- at /custom-matchers.ts:21:1
已修復:package.json
中帶有 "imports"
的模組解析錯誤
套件可以在其 package.json
檔案中宣告僅限內部使用的匯入清單,Bun 將使用它來解析匯入。這對於避免向使用者公開內部檔案很有用。
{
"name": "my-package",
"imports": {
"my-package": "./dist/index.js"
}
}
這些匯入以 #
為前綴。
import { foo } from "#my-package";
這也可以用於重寫來自其他套件的匯入。例如,如果您想將所有來自 async-hooks
的匯入重寫為 #async-hooks
,您可以執行
{
"name": "my-package",
"imports": {
"async-hooks": "async-hooks"
}
}
然後,它將載入 async-hooks
套件
import { foo } from "#async-hooks";
但,有一個錯誤導致以這種方式別名套件在 Bun 中無法運作。這已修復。
此錯誤影響的著名套件
- Astro v4
p-limit
已修復:稀疏陣列在 console.log 中顯示為 undefined
先前,稀疏陣列在 console.log
中會顯示為 undefined
。這已修復。
console.log([1, , 3]);
現在
[ 1, empty item, 3 ]
先前
[1, undefined, 3];
已修復:createRequire() 中包含空格的 file: URL
先前,當傳遞包含未逸出空格的 file:
URL 時,createRequire()
會拋出錯誤。這已修復。
import { createRequire } from "node:module";
const require = createRequire(import.meta.url);
require("file:///Users/jarred/My%20Folder/script.js");
感謝 @paperclover 修復此問題。
已修復:console.log 有時會省略 length
屬性
有時,console.log
會省略物件的 length
屬性。這已修復。
console.log({ length: 1, a: 1 });
先前,它會列印
{
a: 1
}
現在,它會列印
{
length: 1,
a: 1,
}
已修復:轉譯器在 spread 後面 JSX key 的不一致性
以下輸入在 Bun 中的行為會與 TypeScript 中不同
const obj = {};
console.log(<div {...obj} key="after" />, <div key="before" {...obj} />);
這已修復,感謝 @rhyzx。
已修復:console.log("%d", value)
錯誤
已修復導致 %d
無法正確處理非數值的錯誤。
console.log("%d", "1");
先前,它會列印
0
現在,它會列印
1
已修復:語法突顯器範本字串處理
在 Bun 的先前版本中,我們為錯誤訊息中顯示的程式碼新增了語法突顯功能,但它有一個錯誤,導致某些範本字串使突顯器崩潰。這已修復。
已修復:jest.fn(jest.fn()) 崩潰
已修復呼叫 jest.fn(jest.fn(() => {}))
時發生的崩潰,感謝 @Hanassagi。
感謝 16 位貢獻者!
我們總是很高興歡迎新的貢獻者加入 Bun。在這個版本中,有 6 位新的貢獻者首次做出貢獻。
- @mkayander 在 #7453 中做出了首次貢獻
- @asilvas 在 #7446 中做出了首次貢獻
- @annervisser 在 #7289 中做出了首次貢獻
- @sstephant 在 #7477 中做出了首次貢獻
- @DaleSeo 在 #7532 中做出了首次貢獻
- @bradymadden97 在 #7529 中做出了首次貢獻
- @dfaio 在 #7542 中做出了首次貢獻
感謝 16 位讓此版本成為可能的貢獻者