Bun 是一個速度極快的 JavaScript 執行環境、打包器、轉譯器和套件管理器 — 功能All in one。
Bun v1.0.31 修復了 54 個錯誤(解決了 113 個 👍 反應),引入了 bun --print
、<stdin> | bun run -
、bun add --trust
、具有 Unix socket 的 fetch()
,修正了 macOS 二進制檔案大小回歸問題,修復了舊版 Linux 上 spawn() 中 CPU 使用率過高的錯誤,新增了 util.styleText
、Node.js 相容性改進、bun install 錯誤修復以及 bunx 錯誤修復。
先前的版本
v1.0.30
修復了 27 個錯誤(解決了 103 個 👍 反應),修正了 Bun.serve() 的 8 倍效能回歸問題,為bun build
和 Bun 的執行環境新增了--conditions
標誌,在 Bun 的測試執行器中新增了對expect.assertions()
和expect.hasAssertions()
的支援,修復了崩潰問題並改進了 Node.js 相容性。v1.0.29
修復了 8 個錯誤。Bun.stringWidth(a) 是 'string-width' 這個熱門套件的極速替代方案,速度快約 6,756 倍。bunx 更頻繁地檢查更新。在 bun:test 中新增了 expect().toBeOneOf()。修復了影響 Prisma 的記憶體洩漏問題。Shell 現在支援進階重新導向,例如 '2>&1'、'&>'。提升了 bunx、bun install、WebSocket client 和 Bun Shell 的可靠性v1.0.28
修復了 6 個錯誤(解決了 26 個 👍 反應)。修復了影響 Prisma 和 Astro、node:events
、node:readline
和node:http2
的錯誤。修復了 Bun Shell 中涉及 stdin 重新導向的錯誤,以及bun:test
中test.each
和describe.only
的錯誤。
安裝 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 --print
現在您可以使用 bun --print
來評估提供的程式碼,並使用 console.log
印出結果。它與 node --print
相同,只是它支援最上層 await、ESM、CommonJS、TypeScript 和 JSX。
Bun 也會等待懸而未決的 promise,因此您不需要在程式碼中附加 await
。
作為參考,以下是使用 node --print
的等效輸出
我們實作此功能的原因是許多 npm 套件都有呼叫 node --print
的 postinstall
腳本,我們不希望在您未安裝 Node.js 的情況下,bun install
發生任何問題。
感謝 @dylan-conway 實作此功能!
新增功能:從 stdin 執行程式碼
現在您可以使用 bun run -
將 stdin 導入 Bun。這對於從檔案或腳本執行程式碼非常有用。
cat file.js | bun run -
bun run - < file.js
與 Bun 中通常一樣,這適用於最上層 await、ESM、CommonJS、TypeScript 和 JSX。
感謝 @nektro 新增此功能!
新增功能:bun add --trust <套件>
我們改進了 Bun 處理 package.json 中 trustedDependencies
的方式。預設情況下,Bun 不會為不受信任的套件執行 postinstall
腳本。這是一項安全功能,可防止惡意程式碼在您的機器上執行。
當您首次新增套件時,如果該套件有 postinstall
腳本未執行,Bun 會告知您。
bun add v1.0.31
Saved lockfile
installed @biomejs/biome@1.6.1 with binaries:
- biome
1 package installed [55.00ms]
Blocked 1 postinstall. Run `bun pm untrusted` for details.
新增功能:bun pm untrusted
如果您想查看哪些腳本被封鎖,可以執行 bun pm untrusted
。
bun pm untrusted v1.0.31
./node_modules/@biomejs/biome @1.6.1
» [postinstall]: node scripts/postinstall.js
These dependencies had their lifecycle scripts blocked during install.
If you trust them and wish to run their scripts, use `bun pm trust`.
新增功能:bun pm trust
如果您信任該套件,可以執行 bun pm trust [套件]
。如果您想信任每個套件,也可以執行 bun pm trust --all
。
bun pm trust v1.0.31
./node_modules/@biomejs/biome @1.6.1
✓ [postinstall]: node scripts/postinstall.js
1 script ran across 1 package [71.00ms]
最受歡迎的套件預設已受信任。您可以執行 bun pm default-trusted
來查看受信任套件的列表。
如果您已經知道要信任某個依賴項,可以使用 bun add --trust [套件]
來新增它。這會將該套件及其遞移依賴項新增到您的 trustedDependencies
列表中,因此您無需為該套件執行 bun pm trust
。
{
"dependencies": {
"@biomejs/biome": "1.6.1"
},
"trustedDependencies": [
"@biomejs/biome"
]
}
感謝 @dylan-conway 改進此功能!
新增功能:fetch()
中的 Unix socket
Bun 現在支援透過 Unix socket 發送 HTTP 請求。
const response = await fetch("https://127.0.0.1/info", {
// a file path to a Unix socket
unix: "/var/run/docker.sock",
});
const { ID } = await response.json();
console.log("Docker ID:", ID);
這表示您可以將 fetch()
請求發送到使用 HTTP 通訊但使用 Unix socket 通訊的服務,例如 Docker daemon。
此功能適用於 fetch
和 node:http
。
通常,unix socket 的檔案路徑限制約為 108 個字元,但在 Linux 上,我們新增了一個變通方法來支援更長的路徑。
抽象網域 socket 在 fetch()
中
我們也新增了對稱為「抽象網域 socket」的晦澀 Linux 功能的支援。
與 Unix socket 不同,抽象 socket 不存在於檔案系統上,並且在兩端都關閉時會自動清除。它們在一個程序可能不與父程序共享檔案系統權限的環境中很有用。
import { $, serve } from "bun";
const unix = "\0much-abstract-very-domain";
const server = serve({
unix,
fetch(req) {
return new Response("hello from abstract socket!");
},
});
// abstract domain sockets don't exist in the filesystem
// and they don't run on a port
await $`rm -rf ${unix.slice(1)}`;
// but we can still make requests to them
await $`curl --abstract-unix-socket ${unix.slice(1)} http://anything/hello`;
await fetch(`http://a:1234/b`, { unix });
server.stop();
抽象 socket 適用於 fetch()
、Bun.serve()
和 node:http
中的 socketPath
。
已修復:舊版 Linux 核心上的 Bun.spawn() 100% CPU 使用率錯誤
正確產生程序並監控它們何時退出非常複雜。
對於 Linux,Bun 有兩種實作方式來監控產生的程序何時退出
- 使用
pidfd_open(2)
,它已完全新增到 v5.10(2020 年 12 月)的 Linux 核心中。pidfd 是監控程序何時退出的最有效方法,因為它可以與 epoll 或 io_uring 一起使用,就像其他檔案描述符一樣。 - 使用
SIGCHLD
的回退實作,所有 Linux 核心都支援此實作
在虛擬碼中,回退實作過去看起來像這樣
// in a dedicated thread:
while (true) {
for (const pid of pids) {
if (wait4(pid, WNOHANG, ...) === pid) {
pids.delete(pid);
tellBunThatProcessExited(pid);
}
}
sleepUntilNewPidsOrAnyProcessExits(eventfd, signalfd);
}
有一個錯誤,當應該休眠時,sleepUntilNewPidsOrAnyProcessExits
的等效項會立即解析,導致 Bun 在此執行緒上消耗 100% CPU。
此錯誤有兩個原因
- 我們未在底層
eventfd
上呼叫read()
,導致它始終準備好讀取(因此永遠不會休眠) SIGCHLD
的訊號處理常式未正確安裝,導致執行緒永遠不會收到訊號
第一個錯誤阻止了第二個錯誤被注意到。由於它從未休眠,因此永遠不需要喚醒來處理訊號。
為了防止將來發生回歸,我們新增了一個測試,用於檢查產生 sleep infinity
並在 1 秒後終止子程序時的 CPU 使用率。如果 CPU 時間超過 1/2 秒,則測試失敗。
已修復:舊版 Linux 核心上 Bun.spawn() 中遺失 resourceUsage 統計資訊
Bun 支援追蹤產生的程序消耗多少記憶體、CPU 時間和更多統計資訊。在舊版 Linux 核心上的回退實作中,我們無法追蹤這些統計資訊。現在我們可以了。
const proc = Bun.spawn({
cmd: ["sleep", "1"],
});
await proc.exited;
console.log(proc.resourceUsage);
// Before: all 0s
已修復:macOS 上 bun 可執行檔案大小回歸問題
在 Bun v1.0.28(上個月)中,我們新增了 Bun.stringWidth
,它使用了 ICU 國際化程式庫中的更多函式。Bun 建置程序中的一個錯誤導致將整個 ICU 程式庫靜態連結到 macOS 上的 Bun 可執行檔案中。這使 Bun 可執行檔案的大小增加了 32.7 MB。
macOS 上的大小 | Bun 版本 |
---|---|
47.8 MB | Bun v1.0.31 |
80.4 MB | Bun v1.0.30 |
80.4 MB | Bun v1.0.29 |
47.7 MB | Bun v1.0.28 |
此回歸問題已修復,我們將新增監控以防止再次發生。
Node.js 相容性改進
新增功能:util.styleText()
Node.js 最近新增了 util.styleText()
API,可讓您使用 ANSI 逸出碼設定文字樣式。我們已將其新增到 Bun 中。
import { styleText } from "node:util";
console.log(styleText("red", "This is a failure!"));
console.log(styleText("yellow", "This is a warning!"));
console.log(styleText("green", "This is a success!"));
上面的程式碼將印出以下輸出
This is a failure!
This is a warning!
This is a success!
感謝 @paperclover 致力於此功能!
新增功能:node:http
中的 socketPath
選項
我們新增了對 node:http
中 socketPath
選項的支援。這可讓您使用 Unix socket 或抽象網域 socket 發送 HTTP 請求。
import { request } from "node:http";
request(
{
socketPath: "/var/run/docker.sock",
path: "/info",
},
(res) => {
let data = "";
res.on("data", (chunk) => (data += chunk));
res.on("end", () => console.log(JSON.parse(data)));
},
);
新增功能:domainToASCII
和 domainToUnicode
我們新增了對 url.domainToASCII
和 url.domainToUnicode
API 的支援。這些是舊版 Node.js API,可用於在網域名稱的 ASCII 和 Unicode 表示法之間進行轉換。
import { domainToASCII, domainToUnicode } from "node:url";
console.log(domainToASCII("www.🍕.com")); // => www.xn--xj8h.com
console.log(domainToUnicode("www.xn--xj8h.com")); // => www.🍕.com
感謝 @nektro 新增這些 API!
已修復:child_process
可能會提早逾時
我們修復了一個錯誤,其中在定義逾時時,產生的 child_process
會提早逾時。這不會影響未定義逾時的程式碼。
import { spawn } from "node:child_process";
const start = performance.now();
await new Promise((resolve, reject) => {
const child = spawn("sleep", ["1000"], { timeout: 1000 });
child.on("error", reject);
child.on("exit", resolve);
});
const duration = performance.now() - start;
console.log(duration); // ~10ms instead of ~1000ms
感謝 @Electroid 修復此錯誤!
已修復:node:http
中未觸發 socket
事件
我們修復了一個錯誤,其中當用戶端連線到伺服器時,node:http
中不會觸發 socket
事件。
import { request } from "http";
const request = request("https://127.0.0.1:8080");
await new Promise((resolve, reject) => {
request.on("error", reject);
request.on("socket", function onSocket(socket) {
request.destroy();
console.log(socket);
resolve();
});
});
已修復:使用無效引數呼叫 Bun.serve()
時崩潰
我們修復了一個錯誤,其中在某些情況下,如果 Bun.serve()
選項無效,Bun.serve()
會崩潰。它應該改為擲回錯誤。
感謝 @paperclover 修復此錯誤!
已修復:在測試外部使用 expect()
時崩潰
我們修復了一個錯誤,其中如果在使用非同步解析器的 expect()
在測試外部呼叫,則會崩潰。
import { expect } from "bun:test";
expect(Bun.sleep(1000)).resolves.toBeTruthy();
感謝 @paperclover 修復此錯誤!
已修復:fetch() 收到無效的 Location
標頭時可能崩潰
如果 fetch()
收到的 Location
標頭指向無效的 URL,Bun 可能會崩潰。現在已修復此問題。
感謝 @nektro 修復此錯誤!
已實作:URLSearchParams.delete
和 URLSearchParams.has
的第二個引數
URLSearchParams.prototype.delete
和 URLSearchParams.prototype.has
方法支援第二個 "value"
引數。這可讓您刪除或檢查 URLSearchParams 中的特定值。
const params = new URLSearchParams("a=1&a=2&b=3");
params.delete("a", 1);
params.delete("b", undefined);
params + ""; // => actual='' expected='a=2'
此功能是 Web Platform 最近新增的功能,我們已將其新增到 Bun 中。
已修復:當 NODE_ENV=test
時,.test.env
未載入
我們發現一個錯誤,當 NODE_ENV=test
且存在 .production.env
檔案時,.test.env
檔案不會載入。感謝 @nektro,此問題已修復。
已修復:未緩衝錯誤到 stderr
我們發現一個效能錯誤,其中 Bun 在將堆疊追蹤印到 stderr 時不會緩衝寫入。現在已修復此問題。
bun install 錯誤修復
已修復:bunx
的各種錯誤
我們也修復了 bunx
的各種錯誤
bunx --bun
有時會忽略--bun
標誌,具體取決於標誌順序。bun x --bun
會將--bun
標誌轉發到腳本,而不是 Bun。bun --bun create
會崩潰且無法正常運作。bunx <github>
有時會掛起。
感謝 @paperclover 修復這些錯誤!
已修復:node-gyp
有時不會執行
已修復一個錯誤,其中當 package.json 同時具有 postinstall
腳本和 bindings.gyp
檔案時,bun install
不會執行生命週期腳本。此錯誤影響了 node-pty
和其他套件。
感謝 @dylan-conway 修復此錯誤!
已修復:bun pm cache rm
現在會移除 bunx 快取
先前,bun pm cache rm
不會移除 bunx
的 node_modules
快取。此問題已修復。
內部:I/O 架構變更
在此版本中,我們重新實作了 Bun 如何
- 產生程序
- 讀取檔案(串流)
- 寫入檔案(串流)
這些新的實作在防止讀取/寫入封鎖主執行緒方面做得更好,而無需付出將所有 I/O 移至執行緒池的成本。峰值記憶體使用量應該更低,尤其是在使用 node:stream
和 node:fs
時。
如果您在使用 Bun.file(path).stream()、fs.createReadStream
、fs.createWriteStream
或 Bun.spawn()
時發現任何錯誤,請回報。
Windows 支援即將推出
我們即將在 Bun v1.1 中推出 Windows 支援。一旦 Windows 版 Bun 通過 95% 的 Bun 測試套件,我們將宣布發布日期。
Windows 版 Bun 目前通過了 92.51% 的 Bun 測試套件
— Bun (@bunjavascript) 2024 年 3 月 12 日
████████████░ 92.51%