Bun v1.1.27 版本發布了!此版本修正了 130 個錯誤(解決了 250 個 👍 的問題)。bun pm pack
、更快的 node:zlib
。Bun.serve() 中的靜態路由。response.clone() & request.clone() 中支援 ReadableStream。每個請求的逾時。呼叫了 ReadableStream 中的 Cancel 方法。bun run
更好地處理 CTRL + C。更快的緩衝串流。bun outdated
套件過濾。在 --hot 和 --watch 中監看任意檔案類型。修正了 Windows 上 Proxy 的問題。多項 Node.js 相容性改進。
我們正在舊金山招聘系統工程師,共同打造 JavaScript 的未來!
安裝 Bun
curl -fsSL https://bun.dev.org.tw/install | bash
npm install -g bun
powershell -c "irm bun.sh/install.ps1|iex"
scoop install 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
原生 node:zlib
我們重寫了 node:zlib
以使用原生程式碼。
執行階段 | node:zlib | 串流 (MB/s) | 同步 (MB/s) |
---|---|---|---|
Bun v1.1.27 | deflate | 32.79 MB/s | 14.82 MB/s |
Node v22.5.1 | deflate | 15.50 MB/s | 31.39 MB/s |
Bun v1.1.26 | deflate | 15.59 MB/s | 10.29 MB/s |
Bun v1.1.27 | deflateRaw | 32.68 MB/s | 14.60 MB/s |
Node v22.5.1 | deflateRaw | 19.77 MB/s | 31.41 MB/s |
Bun v1.1.26 | deflateRaw | 15.67 MB/s | 10.38 MB/s |
Bun v1.1.27 | gunzip | 87.72 MB/s | 107.60 MB/s |
Bun v1.1.26 | gunzip | 46.49 MB/s | 42.74 MB/s |
Node v22.5.1 | gunzip | 31.01 MB/s | 75.86 MB/s |
Bun v1.1.27 | gzip | 32.69 MB/s | 14.91 MB/s |
Node v22.5.1 | gzip | 18.46 MB/s | 31.10 MB/s |
Bun v1.1.26 | gzip | 15.29 MB/s | 10.11 MB/s |
Bun v1.1.27 | inflate | 87.79 MB/s | 102.86 MB/s |
Bun v1.1.26 | inflate | 50.72 MB/s | 43.83 MB/s |
Node v22.5.1 | inflate | 26.07 MB/s | 74.64 MB/s |
Bun v1.1.27 | inflateRaw | 87.68 MB/s | 101.78 MB/s |
Bun v1.1.26 | inflateRaw | 53.89 MB/s | 43.13 MB/s |
Node v22.5.1 | inflateRaw | 33.35 MB/s | 75.02 MB/s |
透過 Linux x64 Hetzner 伺服器上的第三方 zlib 效能基準測試。
Bun 中 node:zlib
的最佳化還有更多工作要做,但這是一個好的開始。
非常感謝 @nektro 實作此功能。
新指令:bun pm pack
在 Bun 的下一個版本中
— Bun (@bunjavascript) 2024 年 9 月 7 日
bun pm pack 會建立一個 npm 套件的 tarball,用於發佈或在本機安裝 pic.twitter.com/RdXdyzI3He
bun pm pack
設計為 npm pack
的直接替代品。
Bun.serve()
(HTTP 伺服器) 的新功能
此版本為我們的快速 HTTP 伺服器 Bun.serve()
引入了可靠性和生活品質的改進。
靜態路由
現在您可以傳遞 static
選項,為路徑提供靜態 Response
物件。
Bun.serve({
static: {
"/api/health-check": new Response("🟢"),
"/old-link": Response.redirect("/new-link", 301),
"/api/version": Response.json(
{
app: require("./package.json").version,
bun: Bun.version,
},
{
headers: {
"X-Powered-By": "bun",
},
},
),
},
async fetch(req) {
return new Response("Dynamic!");
},
});
request.clone()
和 response.clone()
中支援 ReadableStream
現在透過 request.clone()
和 response.clone()
支援複製串流 Request
或 Response
。
從 Bun.serve
複製請求
Bun.serve({
async fetch(req, server) {
const cloned = req.clone();
await req.json();
// Previously, this would be empty.
await cloned.json();
// ... rest of the code
},
});
從 fetch
複製 Response
const response = await fetch("https://example.com");
const cloned = response.clone();
console.log(await response.text());
console.log(await cloned.text());
先前,僅當將字串、ArrayBuffer 或 Blob 傳遞給 Response
建構函式時,才支援靜態回應。
ReadableStream 中的 “cancel” 方法
當請求中止時,Bun 現在會呼叫 ReadableStream
中的 cancel
方法。
import { serve } from "bun";
serve({
async fetch(req, server) {
req.signal.addEventListener("abort", () => {
// Previously, AbortSignal was the only way to detect if a request was aborted.
console.log("Request aborted");
});
return new Response(
new ReadableStream({
async pull(controller) {
controller.enqueue("Hello World");
await Bun.sleep(1000);
},
cancel() {
// New! Called when the request is aborted.
console.log("Stream cancelled");
},
}),
);
},
});
每個請求的逾時
新的 server.timeout(request: Request, seconds: number)
方法允許您為每個特定的 HTTP 請求設定逾時。
為請求設定 60 秒逾時
Bun.serve({
async fetch(req, server) {
server.timeout(req, 60); // 60 seconds
await req.formData();
return new Response("Slow response");
},
});
感謝 @cirospaciari 實作此功能。
更快的緩衝串流
此版本我們不只為 Bun.serve()
新增了功能。我們也使其速度更快。
在 Bun 的下一個版本中
— Jarred Sumner (@jarredsumner) 2024 年 9 月 3 日
在存取 “.body” 後,request.json() 和類似方法中的快速路徑現在可以運作了
新:65,000 req/s
先前:29,000 req/s pic.twitter.com/2EqYyCoq4G
新的 CLI 旗標:--max-http-header-size
傳遞 --max-http-header-size
會設定 HTTP 請求標頭緩衝區的大小。
https://github.com/oven-sh/bun/pull/13577
已修正:server.requestIP
在 await
之後
先前,在回呼或呼叫 await
之後使用 server.requestIP
會遺失請求中繼資料。此問題已修正。
Bun.serve({
port: 3000,
async fetch(req, server) {
console.log(server.requestIP(req));
// { address: '127.0.0.1', family: 'IPv4', ... }
await req.formData();
console.log(server.requestIP(req));
// now: { address: '127.0.0.1', family: 'IPv4', ... }
// before: undefined
},
});
已修正:在已關閉的 WebSocket 上 ws.publish
在 Bun.serve
中,在 websocket 上呼叫 .publish
會向所有用戶端傳送訊息,除了 websocket 本身。在 close
處理常式中使用此功能時,WebSocket 已關閉,且無法傳送訊息。此問題現在已修正。
感謝 @cirospaciari 修正此問題。
已修正:存取請求主體和緩衝方法時的記憶體洩漏
已修正以下程式碼中的記憶體洩漏
Bun.serve({
async fetch(req) {
if (req.body) {
await req.json();
}
// ... rest of the code
},
});
當存取 Request
主體的 ReadableStream
時,在某些情況下,諸如 req.json
之類的緩衝方法可能會使用不同的實作,並且在這些情況下,Request
物件會錯誤地持有對 req.json
傳回的 Promise
的強參考,導致記憶體洩漏。
在為串流新增 clone() 支援時,我們修改了 Request
和 Response
的實作,以修正此問題和類似問題。
bun outdated
過濾
bun outdated
現在具有 --filter
,可讓您選擇要稽核哪些工作區以檢查過時的套件。
# Path patterns:
# Matches all workspaces in `./packages`
bun outdated --filter="./packages/*"
# Name patterns:
# All workspaces with names starting with `pkg`
bun outdated --filter="pkg*"
# All workspaces excluding `pkg1`
bun outdated --filter="*" --filter="!pkg1"
此外,位置引數會過濾依賴項清單,如果您只想檢查特定套件的更新,這會很有幫助。
# All dependencies starting with `is-` (could display `is-even`, `is-odd`, ...)
bun outdated "is-*"
# All dependencies from a particular scope
bun outdated "@discordjs/*"
# With `--filter`. Matches all outdated `jquery` dependencies in all workspaces.
bun outdated jquery --filter="*"
bun run
Ctrl + C 行為已修正
bun run
未將 POSIX 訊號從 bun
程序傳播到子程序(僅從子程序 -> 父程序)。這在某些情況下導致了奇怪的錯誤,例如 CTRL + C 無法退出子程序,直到稍後從斷開連線的終端機讀取 stdin 時發生 I/O 錯誤。這在視覺上表現為當您按下 ↑ 向上鍵時,出現 ^[[A
字元,而不是先前的指令。
此問題已修正。
在 Bun 的下一個版本中
— Jarred Sumner (@jarredsumner) 2024 年 9 月 6 日
有時會印出 ^[[A 的錯誤已修正
1. bun run <package.json script>
2. Ctrl + C
3. ↑ 向上 pic.twitter.com/7YlR2knMLh
感謝 @xales 偵錯此問題。
在 --watch
和 --hot
中監看任意檔案類型
Bun 的內建監看和熱重載現在支援監看任意檔案類型。
若要監看檔案,請匯入它。
import "./tailwind.css";
// ... rest of my app
Bun 的監看器依賴模組圖來判斷哪些檔案會觸發重新載入。這減少了不必要的重新載入,縮短了您的迭代週期時間。
先前,僅監看 JavaScript、TypeScript、JSON、TOML 和 .txt 檔案。現在,Bun 將監看匯入的任何檔案,無論檔案副檔名為何。
已修正:預設 idleTimeout
不再於 node:http 中設定
在 Bun 1.1.26 中,預設的 idleTimeout
為 10 秒,這是一個重大變更,因為之前的版本具有無限逾時。idleTimeout
的預設值現在為 0
,這會停用逾時。
Node.js 相容性改進
此版本還包含許多 Node.js 相容性改進。
已修正:從 N-API 擲回例外時當機
已修正當擲回例外時,N-API 中導致當機的錯誤。
已修正:存取堆積分配的 JSValue 時,N-API 中當機
JavaScriptCore 和 V8 是不同的引擎,它們使用不同的垃圾回收方法。JavaScriptCore 掃描堆疊。V8 依賴句柄作用域。
先前,Bun 未實作句柄作用域。這導致 DuckDB 等 N-API 套件在堆積分配 napi 值時未在堆疊記憶體中參考它們,從而導致當機。垃圾收集器看不到它們,並過早清理記憶體。
感謝 @190n 實作句柄作用域。
已修正:影響 Next.js 中介軟體的當機
已修正當在 node:vm
內部使用擴充內建類別(如 URL
或 Response
)的類別時,node:vm
中的當機。此當機可在 Next.js 中介軟體中重現。
已修正:某些 Buffer
方法中缺少 ERR_INVALID_ARG_TYPE
在 Buffer.isAscii
和 Buffer.isUtf8
中,當給定無效引數時擲回的錯誤現在正確地包含 code: "ERR_INVALID_ARG_TYPE"
。
已修正:new URL
中缺少 ERR_INVALID_URL
為了與 Node.js 匹配,當給定無效 URL 時,new URL
擲回的錯誤現在包含 code: "ERR_INVALID_URL"
已修正:空訊息的 AES-GCM
加密
感謝 @wpaulino,空訊息現在可以在 AES-GCM
加密中正確地往返。
已修正:util.promisify
與 crypto.generateKeyPair
感謝 @wpaulino,在 crypto.generateKeyPair
上呼叫 util.promisify
現在將傳回正確的 promise 化函數。
已修正:處理 Buffer
中的記憶體不足錯誤
當將大型字串轉換為 Buffer
時,Bun 現在會透過擲回 OutOfMemoryError
而不是當機來處理記憶體不足錯誤。
已修正:node:tls
接受 TLS socket 的任意串流。已修正 mssql
套件
node:tls
中的 tls.connect
函數接受 socket
選項。這可讓您將任何 net.Socket
升級到 TLS。但是,此參數實際上可以是任何任意 stream.Duplex
,Bun 先前不支持此參數,因為它依賴底層網路連線來更有效率地進行 TLS。
這解決了使用 mssql
套件時擲回 Error: socket must be an instance of net.Socket
的問題。
已修正:node:http
agent 被忽略
在某些情況下,node:http
agent 未被使用。此問題已修正。
感謝 @nektro
已修正:node:http
setTimeout & server.setTimeout 被忽略
隨著 server.timeout
現在已實作,我們也在 node:http
中新增了對 server.setTimeout
和 request.setTimeout
的支援。
感謝 @cirospaciari 修正此問題。
已修正:node:vm
不一致性
已修正 node:vm
中的各種細微錯誤
vm.runInThisContext
現在在全球環境中運作script.runInNewContext
現在在其自身的環境中運作script.runInThisContext
和vm.runInThisContext
不將環境作為引數vm.runInThisContext
、vm.runInContext
和vm.runInContext
將字串作為選項引數。
感謝 @SunsetTechuila 修正這些問題!
已修正:缺少 net.Socket.destroySoon
先前,node:net
中的此方法未定義。現在已修正。
fetch 可靠性改進
Windows 上 fetch() 中的 Proxy 現在運作更佳
在 Windows 上,使用 Proxy 搭配 fetch
通常會導致擲回 error: Syscall
。
感謝 @cirospaciari,此問題已解決。
已修正:FormData
或 URLSearchParams
主體的記憶體洩漏
在 Bun v1.1.25 中,引入了一個回歸錯誤,其中在 fetch()
請求的主體中傳送 FormData
和 URLSearchParams
會導致記憶體洩漏。此回歸錯誤現在已修正。
更多修正
已修正:讀取大型檔案 Bun.file
被截斷
當將超過 4gb 的檔案讀取到單個 ArrayBuffer
時,緩衝區會被截斷為 4gb。此問題現在已修正。
已修正:在某些終端機中清除螢幕
用於清除終端機螢幕的 ANSI 逸出碼已從 \x1b[H\x1b[2J
變更為 \x1B[2J\x1B[3J\x1B[H
,這與更多終端機相容。最值得注意的是,這修正了 Visual Studio Code 的終端機,在此變更之前,該終端機未完全清除。
感謝 @jakebailey 修正此問題。
已修正:處理 Bun.escapeHTML
中的記憶體不足錯誤
當給予 Bun.escapeHTML
足夠大的字串時,它現在將擲回 OutOfMemoryError
而不是當機。
Bun.deepEquals
對於 Map
和 Set
的效能改進
在 Bun v1.1.19 的 WebKit 升級之後,Map
和 Set
的實作發生了變化,以至於我們不得不在 Bun.deepEquals
中移除它們的快速路徑。感謝 @wpaulino,新增了一個新的快速路徑,它比先前的位置更好。
此外,快速路徑涵蓋了擴充 Map
或 Set
的自訂類別,使它們在 Bun.deepEquals
中的效能與基底類別本身幾乎沒有區別。
已修正:Windows 上 Failed to link package: EBUSY
在 bun install 中,修復了在套件二進制檔案開啟時更新它們的問題
已修正:LCOV 報告器正確回報未命中行數
Bun 的 LCOV 報告器先前有時會回報 100%
行覆蓋率,即使並非總是如此。現在已修正,感謝 @fmorency。
已修正:bun add -g
安裝後訊息
當安裝具有封鎖安裝後腳本的全域套件時,訊息現在將包含正確的指令
$ bun install -g @delance/runtime
bun add v1.1.27
installed @delance/runtime@2024.8.103 with binaries:
- delance-langserver
68 packages installed [1.98s]
-Blocked 1 postinstall. Run `bun pm untrusted` for details.
+Blocked 1 postinstall. Run `bun pm -g untrusted` for details.
感謝 @RiskyMH 修復此問題
已修正:Bun.build
中的競爭條件
導致 Bun.build
Promise 掛起的競爭條件已被修復。如果您在短時間內將許多 Bun.build
呼叫排隊,可能會導致此問題。
已修正:bun shell 未保持父程序存活
已修復以下程式碼會過早退出的錯誤,且不會印出 "never reached!!! why!!"。
import { $ } from "bun";
console.log("before shell");
(async function () {
await `echo hi`;
console.log("never reached!!! why!!");
})();