我們正在招募 C/C++ 和 Zig 工程師,一同打造 JavaScript 的未來! 加入我們的團隊 →
上週,我們在 Bun v0.6.0 中推出了全新的 JavaScript 打包器。
今天,我們發布了對 node:vm
的支援、node:tls
和 node:http
的改進 — 這修復了對 socket.io
和 mongodb
的支援、對 bun test
的改進 — 引入了 test.todo()
、測試逾時和更佳的預先載入,以及 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
介紹 node:vm
Bun 現在支援內建的 node:vm
模組。它可以用於執行程式碼,類似於 eval()
,但可以更精確地控制程式碼在哪個 globalThis
JavaScript 環境中執行。
import { runInContext } from "node:vm";
let context = {
foo: "bar",
baz: 123,
};
runInContext(`foo = "fizz"; delete baz;`, context);
console.log(context.foo); // "fizz"
console.log(context.baz); // undefined
您也可以使用 runInNewContext
在獨立的 JavaScript 環境中執行程式碼。
import { runInNewContext } from "node:vm";
runInNewContext(`globalThis.fetch = undefined;`);
console.log(globalThis.fetch); // [Function fetch]
感謝 @silversquirl 實作此功能!
node:tls
和 node:http
的修正
我們修正了許多關於 TLS 和 HTTP 的程式碼,例如 TLS 交握,因此您現在可以在 Bun 中使用 socket.io
和 mongodb
驗證。
在下一個 Bun 版本https://127.0.0.1/Pc0bps2VFV 中,伺服器可以運作了,而且在 Bun 中執行速度快了 2 倍。
— Jarred Sumner (@jarredsumner) 2023年5月21日
左:bun (40萬 訊息/秒)
右:node (20萬 訊息/秒) pic.twitter.com/9jW09NiGGc
感謝 @cirospaciari 致力於此!
bun test
的改善
test.todo()
您現在可以使用 test.todo()
來標記您稍後想要實作的測試。
expect().toBeCloseTo()
您也可以使用 expect().toBeCloseTo()
來比較兩個浮點數。
import { test, expect } from "bun:test";
test("toBeCloseTo()", () => {
expect(3 + 0.14).toBeCloseTo(3.14);
expect(3.14).toBeCloseTo(Math.PI, 2);
});
感謝 @blackmann 致力於這兩項功能!
測試逾時
您現在可以使用 test()
的第三個參數為您的測試設定逾時時間。
import { test } from "bun:test";
test("i took too long", async () => {
await Bun.sleep(100);
}, 50); // the last argument is a timeout in milliseconds
使用 --preload
的 Hook 支援
您現在可以搭配 --preload
標記使用 beforeAll
、beforeEach
、afterEach
和 afterAll
。
這讓您可以在所有檔案之前和之後執行程式碼,而不僅僅是目前的檔案。這對於需要在執行測試之前初始化的函式庫非常有用。
import { test, beforeAll, beforeEach, afterEach, afterAll } from "bun:test";
beforeEach(() => {
console.log("This runs before each test in every file");
});
美化列印的修正
我們也修正了一個錯誤,該錯誤會導致像這樣的程式碼在測試執行器中將值列印為 undefined
。
import { test, expect } from "bun:test";
test("wat", () => {
const left = {};
const right = {};
for (let i = 0; i < 2; i++) {
left[i] = i + 1;
right[i] = i + 2;
}
expect(left).toBe(right);
});
bun build
的修正
在 將 Bun.js 作為打包器使用 中強調的,當啟用多個入口點的
--minify
時發生的崩潰問題已獲修正。這是合併相鄰的頂層變數宣告時發生的競賽條件。已修正導致資產複製到不正確輸出路徑的錯誤。
已修正涉及範本字串不正確合併的最小化器錯誤。
已修正產生來源地圖時可能發生的競賽條件。
已修正允許產生的變數名稱以數字開頭的錯誤。
已修正儲存到磁碟後,建立
BuildArtifact
物件時可能發生的崩潰問題。已修正在日誌中的記憶體洩漏問題。
改善了在為瀏覽器建置時使用 Node.js 內建函式庫的錯誤訊息,建議使用者使用
--target
選項來指定node
或bun
。
fetch()
記憶體洩漏
已修正 fetch()
中發現的兩個記憶體洩漏問題。
- 回呼建立了對
Promise<Response>
物件的兩個強參考,這阻止了它被垃圾回收。 - 輸入驗證邏輯可能會建立一個強持有的
Promise<Response>
並立即丟棄它,而沒有釋放強參考。這阻止了Promise<Response>
被垃圾回收。
這令人尷尬,我們已改善記憶體洩漏測試的測試覆蓋率,以確保這種情況不再發生。以下是記憶體洩漏的圖表,由 @dimka3553 提供

console.log()
的改善
引號不匹配
先前,console.log()
會為非 ASCII 屬性名稱列印不匹配的引號。現在已修正此問題。
{
'🐛 Bug with mismatched quotes": 'fixed'
}
設定深度限制
先前,console.log()
會列印無限量的巢狀物件,排除循環參考。這有時是不希望發生的,並且在列印足夠大的物件時會導致崩潰。此問題已透過深度限制 8 修正。
移除不必要的引號識別符
先前,Bun 會在 console.log
中不必要地引用物件鍵,這有點雜亂。在 Twitter 投票 90% 贊成移除引號後,我們就這麼做了。
在下一個 bun 版本中
— Jarred Sumner (@jarredsumner) 2023年5月19日
console.log(obj) 具有有效識別符的屬性鍵不再被引用 pic.twitter.com/w1uSCovyRM
WebSocket
的變更
publishToSelf
行為的破壞性變更
Bun 在其伺服器端 WebSocket
API 中支援 發布/訂閱。您可以使用 Server.publish()
或 ServerWebSocket.publish()
將訊息發送到每個連線的用戶端。
但是,我們在 ServerWebSocket.publish()
API 中犯了一個設計錯誤,因為它也會將訊息發送給自己 — 而典型的行為是排除自己。我們透過引入可選的 publishToSelf
選項來修補此錯誤,但預設行為仍然令人困惑,正如 各種 問題 所強調的那樣。
因此,我們不情願地修正了此行為,進行了破壞性變更,以符合開發人員的直覺。我們很少做出這種類型的決定,但當我們這樣做時,我們會確保有壓倒性的證據和回饋表明,維持現狀比任何潛在的破壞更有害。
const server = Bun.serve({
websocket: {
open(ws) {
ws.subscribe("topic");
// <= Bun v0.6.2
ws.publish("topic", "send to all clients, including `ws`");
// >= Bun v0.6.3
ws.publish("topic", "send to all clients, excluding `ws`");
},
},
fetch(request, server) {
if (server.upgrade(request)) {
return;
}
return new Response();
},
});
WebSocket
訊息中的 Buffer
支援
許多 npm 套件期望 Buffer
物件作為 WebSocket
訊息。Bun 現在允許您直接接收二進制 WebSocket 訊息的 "nodebuffer"
值,而不是要求您在傳遞到函式庫時自行重新建立 Buffer
物件。
const server = Bun.serve({
websocket: {
open(ws) {
ws.binaryType = "nodebuffer";
ws.send(Buffer.from("hello world"));
},
message(ws, message) {
console.log(Buffer.isBuffer(message)); // true
},
},
fetch(request, server) {
if (server.upgrade(request)) {
return;
}
return new Response("hello world");
},
});
const client = new WebSocket("ws://127.0.0.1:3000");
client.binaryType = "nodebuffer";
client.onmessage = ({ data }) => {
console.log(Buffer.isBuffer(data)); // true
};
更多錯誤修正
fs.writeFile({ flag: "a" })
現在會附加到檔案而不是覆寫它- 現在使用正確的資料指標和終結器提示呼叫 N-API 終結器
- 已修正一個在綁定函式內建立許多 Error 物件時可能發生的崩潰問題,感謝 @Constellation
- 在此版本中,設定 megamorphic 屬性值變得更快,感謝 @Constellation
變更日誌
2544742 | 修正了 BuildError 和 ResolveError 的記憶體洩漏,由 @Jarred-Sumner 貢獻 |
4f7198f | 修正了 fs.writeFile({ flag: "a" }) 的不正確行為,由 @Jarred-Sumner 貢獻 |
aacbef3 | 改善了無法解析節點內建函式庫時的錯誤訊息,由 @Jarred-Sumner 貢獻 |
#2939 | 修正了 utf8 屬性名稱的編碼不正確問題,由 @Jarred-Sumner 貢獻 |
#2937 | 修正了 String.raw 輸出不正確的錯誤,由 @dylan-conway 貢獻 |
#2870 | 實作了 expect().toBeCloseTo() ,由 @blackmann 貢獻 |
#2947 | 修正了使用多個入口點進行捆綁時的崩潰問題,由 @Jarred-Sumner 貢獻 |
#2949 | 修正了「數字分隔符號不允許在數字字面量的末尾」的問題,由 @Jarred-Sumner 貢獻 |
5bec025 | 修正了捆綁期間 cwd 無法寫入的問題,由 @Jarred-Sumner 貢獻 |
b76974a | 修正了 IncomingMessage.socket 無法寫入的錯誤,由 @Jarred-Sumner 貢獻 |
#2785 | 實作了 node:vm ,由 @silversquirl 貢獻 |
#2962 | 改善了 node-fetch polyfill 以包含更多導出,由 @Jarred-Sumner 貢獻 |