Bun

Bun v1.1.26


Jarred Sumner · 2024 年 8 月 24 日

Bun v1.1.26 版本來了!此版本修正了 9 個錯誤(解決了 652 個 👍)。bun outdated 會顯示過時的依賴套件。Bun.serve() 獲得了新的 idleTimeout 選項,用於設定 socket 超時,以及 subscriberCount(topic: string) 用於計算訂閱主題的 websocket 客戶端數量。bun test.only 會略過所有其他測試。修正了 async function 中的 expect.assertions(n)。現在保留了 CommonJS 模組中的 "use strict"。此外,還有更多 node.js 相容性改進和錯誤修正。

我們正在舊金山招聘系統工程師,一同打造 JavaScript 的未來!

安裝 Bun

curl
npm
powershell
scoop
brew
docker
curl
curl -fsSL https://bun.dev.org.tw/install | bash
npm
npm install -g bun
powershell
powershell -c "irm bun.sh/install.ps1|iex"
scoop
scoop install bun
brew
brew tap oven-sh/bun
brew install bun
docker
docker pull oven/bun
docker run --rm --init --ulimit memlock=-1:-1 oven/bun

升級 Bun

bun upgrade

bun outdated 顯示過時的依賴套件

bun outdated 是一個新的子命令,可顯示哪些依賴套件已過時。

bun outdated

Update 欄位顯示下一個符合語意版本控制的版本。Latest 欄位顯示來自 npm 註冊表的 latest 標籤版本。

這是 Bun 的 GitHub 儲存庫中最受歡迎的問題之一。非常感謝 @dylan-conway 實作此功能!

test.only 略過所有其他測試

先前,以下程式碼會執行前兩個測試,並略過第三個測試。這非常令人困惑!我們當時為什麼要這樣做!?

import { test, describe } from "bun:test";

test("i should not run!", () => {
  // previously: runs
  // now: does not run
  console.log("why am i running?");
});

// ... more tests in a much longer file ...

test.only("i should run!", () => {
  // runs
  console.log("yes only i should run");
});

test("I definitely should not run!", () => {
  // does not run
  console.log("i don't run");
});

這真的很令人沮喪,因為唯一的解決方法是使用 --only CLI 標誌。

bun test --only

現在,您不必這樣做了。bun test 會偵測到檔案中有 .only 測試,並略過所有沒有 .only 的測試。

當下一個模組開始載入測試時,檔案中 .only 測試的存在也會被重置。這表示 .only 只會影響當前檔案,而不會影響所有檔案。

Bun.serve() 中的 subscriberCount(topic: string)

Bun.serve() 的內建 WebSocket 伺服器現在支援 subscriberCount(topic: string),以取得訂閱主題的 websocket 客戶端數量。

import { serve } from "bun";

const server = serve({
  port: 3002,
  websocket: {
    open(ws) {
      const count = server.subscriberCount("chat");
      ws.subscribe("chat");
      ws.publish(`chat`, `🐰 #${count} joined the chat`);
    },
  },

  fetch(req, server) {
    return server.upgrade(req);
  },
});

Bun.serve() 中的 idleTimeout

您現在可以為 Bun.serve() 的內建 HTTP(s) 伺服器設定自訂閒置超時時間(以秒為單位)。

import { serve } from "bun";

const server = serve({
  async fetch(req) {
    await Bun.sleep(1000 * 60 * 2); // 2 minutes
    return new Response("Hello, it's been 2 minutes!");
  },
  // minutes:
  idleTimeout: 60 * 4, // 4 minutes
});

先前,這始終設定為 10 秒。預設值仍然是 10 秒,但在您需要更長或更短時間的情況下,您現在可以將其設定為不同的值。

此選項先前僅適用於連線的 WebSocket 客戶端,現在也適用於常規 HTTP(s) 請求。

感謝 @cirospaciari 實作此功能!

已修正:async function 中的 expect.assertions(n)

expect.assertions(n: number) 現在在 async function 中可以如預期般運作。

以下原本應該失敗的測試先前不會失敗。

import { test, expect } from "bun:test";

test("this test should NOT pass", async () => {
  expect.assertions(1);
  await Bun.sleep(2);

  // the assertion is commented out.
  // so this test should always fail.
  // expect(1).toBe(1);
});

現在,測試將會失敗

bun test
bun test v1.1.26

passy.test.ts:
AssertionError: expected 1 assertions, but test ended with 0 assertions
✗ this test should NOT pass [3.57ms]

 0 pass
 1 fail
Ran 1 tests across 1 files. [8.00ms]

expect().toThrow() 支援非對稱匹配器

您現在可以將 expect().toThrow() 與非對稱匹配器(如 expect.objectContaining())一起使用

import { test, expect } from "bun:test";

test("this test should NOT pass", () => {
  expect(() => {
    const error = new Error("oh no!");
    error.code = "ERR_OH_NO";
    throw error;
  }).toThrow(expect.objectContaining({ message: "oh no!", code: "ERR_OH_NO" }));
});

已修正:測試中未呼叫 done 回呼導致掛起

先前,在許多情況下,在 test 中使用 done 回呼會在未呼叫時導致測試無限期掛起。

例如,此測試會失敗,然後永遠掛起

import { test, expect } from "bun:test";

test("this test should NOT hang", (done) => {
  process.nextTick(() => {
    throw new Error("oh no!");
    done();
  });
});

有人可能會爭辯說:「從未呼叫 done 回呼!它永遠掛起是合乎邏輯的!」但事實並非如此。測試已經失敗。它有一個未捕獲的異常。因此,測試不需要永遠掛起(或超時)。一旦所有微任務都已耗盡且任務佇列為空,它就可以立即失敗。

換句話說,測試將在所有其他已知工作完成後繼續執行,而不是在拋出異常後等待呼叫 done 回呼。

已修正:mock().mockName() 未傳回 this

Bun 測試執行器中的 mock() 函數現在傳回 this。這是為了使行為與 jest 一致,以便可以將為 jest 撰寫的現有測試移植到 Bun。

Node.js 相容性改進

已修正:在執行時期保留 CommonJS 模組中的頂層 "use strict"

先前,Bun 會在執行時期從 CommonJS 模組中剝離頂層 "use strict" 指令。這原本是針對 ES 模組的,因為在這些情況下是不必要的,但對於 CommonJS 模組來說是必要的,現在已修正。

先前,以下程式碼在 Node.js 中會印出 "I am globalThis",而在 Bun 中會印出 "I am undefined"。

// Before:
"use strict";

function whoami() {
  return this;
}

const me = whoami();

if (me === globalThis) {
  console.log("I am globalThis!");
} else {
  console.log("I am undefined!");
}

exports.whoami = whoami;

現在,它在 Node.js 和 Bun 中都會印出 "I am globalThis"。

已修正:util.inherits 錯誤

已修正 util.inherits 使用 Object.create 而非 Object.setPrototypeOf 的錯誤。這導致 snowflake sdk 無法載入。

感謝 @dylan-conway 修正此錯誤!

已修正:特定情況下 crypto.randomValues() 崩潰

已修正 crypto.randomValues() 中罕見的 JIT 相關崩潰。

已修正:特定情況下 Buffer 中的崩潰

已修正執行 Node.js 測試套件時發現的 Buffer 中罕見的崩潰。

已修正:在某些 Web API 中傳回 ERR_INVALID_THIS 程式碼

Node.js 的測試套件預期某些 Web API 會傳回帶有 ERR_INVALID_THIS code 屬性的錯誤。

為了相容性,Bun 現在會傳回帶有 ERR_INVALID_THIS 程式碼的這些錯誤。

已修正:dns.resolveSrv 混淆 weightpriority

已修正 dns.resolveSrvpriority 欄位被設定為 weight 欄位的錯誤,感謝 @cirospaciari

已修正:fetch() 中罕見的崩潰

已修正涉及 AbortSignal 的 fetch() 中罕見的崩潰,感謝 @cirospaciari

感謝 3 位貢獻者!