Bun

Bun v0.5.7


Ashcon Partovi · 2023年2月24日

Bun v0.5.7 引入了 FormData 支援、git 依賴項和帶有 fetch()AbortSignalsetTimeout() 現在與 Node.js 更相容,bun wiptest 現在是 bun test — 具有美觀列印的差異!— 並改進了對 AWS Lambda 和 GitHub Actions 的支援。

# Install using curl
curl -fsSL https://bun.dev.org.tw/install | bash

# Install using npm
# npm install -g bun

# Upgrade
bun upgrade

FormData 支援

Bun 現在支援 FormData,這是一個標準的 Web API,用於處理表單欄位和多部分上傳中的檔案。您可以新增 string 作為欄位或 Blob 作為檔案。

const formData = new FormData();
formData.set("attachment-id", crypto.randomUUID());
formData.set("attachment", Bun.file("./package.json"));
const response = await fetch("https://example.com/upload", {
  method: "POST",
  body: formData,
});

您還可以從 RequestResponse 解析 FormData

export default {
  async fetch(request: Request): Promise<Response> {
    const formData = await request.formData();
    const file = formData.get("attachment");
    // ...
    return new Response(file);
  },
};

在 Bun 中,response.formData() 執行速度

  • 比 Node v19.6.0 快 25 倍
  • 比 Deno v1.30.3 快 4 倍
image

查看基準測試

Git 依賴項

Bun 現在在 package.json 中支援 git 依賴項。Bun 接受各種 git 依賴項格式,包括 githubgitgit+sshgit+https 以及更多。

{
  "dependencies": {
    "zod": "github:colinhacks/zod",
    "lodash": "git@github.com:lodash/lodash.git#4.17.21"
  }
}

您也可以使用 bun install 新增 git 依賴項。

bun install git@github.com:moment/moment.git

setTimeout() 的變更

Web 標準 setTimeout() 傳回一個 number,表示逾時 ID。Node.js 的 setTimeout() 實作傳回一個 Timeout 物件,該物件具有 ref()unref() 等方法,但可以強制轉換為 number

我們(不情願地)決定變更 Bun 的實作以符合 Node.js,因為有許多 npm 套件依賴於此舊版行為。

const timeout = setTimeout(() => {
  process.abort(); // this is not called, see `unref()` below
}, 1000);

timeout.unref();

// For compatibility, it still works as a number
const timeoutId = +timeout; // 1

我們也改進了 Timeout 物件的 console.log() 格式。

image

帶有 fetch()AbortSignal

您現在可以使用 AbortSignal 取消 fetch() 請求。這對於逾時或在收到回應之前需要取消請求時非常有用。

await fetch("https://example.com", {
  // Abort if the response is not received after 1 second
  signal: AbortSignal.timeout(1000),
});

從 HTTP 伺服器接收 Request 時,您也可以使用 AbortSignal

export default {
  async fetch(request: Request): Promise<Response> {
    request.signal.addEventListener("abort", () => {
      console.log("Client aborted the request");
    });
    // ...
    return new Response();
  },
};

bun wiptest 現在是 bun test

現在是 bun wiptest 升級為 bun test 的時候了。

美觀列印的差異

bun test 現在支援美觀列印的差異,這要歸功於 @dylan-conway 的實作和 @SuperAuguste 將 diff-match-patch 演算法移植到 Zig。

現在

error: expect(received).toEqual(expected)

  {
    abc: 123,
+   def: 456
-   def: 789
  }

- Expected  - 1
+ Received  + 1

之前

error: Expected values to be equal:
	Expected: {
  abc: 123,
  def: 789
}
	Received: {
  abc: 123,
  def: 456
}

jest 全域變數的自動匯入

bun test 現在自動匯入 test()expect()。這也適用於其他 Jest 全域變數,包括:describebeforeAllafterAll 等。

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

test("that it auto-imports expect()", () => {
  expect({
    abc: 123,
    def: 456,
  }).toEqual({
    abc: 123,
    def: 789,
  });
});

我們仍然建議您從 bun:test 匯入,但如果您有使用 Jest 的現有測試,您可能會依賴其全域變數。

Set 的新方法

Set 類別現在具有更多內建方法,這要歸功於 WebKit 的 @kmiller68

const a = new Set([1, 2, 3]);
const b = new Set([1, 3, 4, 5]);
const c = new Set([1, 3]);

console.log(a.union(b)); // [1, 2, 3, 4, 5]
console.log(a.intersection(b)); // [1, 3]
console.log(a.difference(b)); // [2]
console.log(a.symmetricDifference(b)); // [2, 4, 5]

AWS Lambda 支援

Bun 現在可以使用 自訂層執行 AWS Lambda。

當圖層偵測到事件是 HTTP 請求時,它會將其轉換為標準的 Request。這表示您可以使用 bun run 在本機測試您的 Lambda,而無需任何程式碼變更。

export default {
  async fetch(request: Request): Promise<Response> {
    console.log(request.headers.get("x-amzn-function-arn"));
    // ...
    return new Response("Hello from Lambda!", {
      status: 200,
      headers: {
        "Content-Type": "text/plain",
      },
    });
  },
};

對於非 HTTP 請求的事件,例如 S3 或 SQS 觸發器,事件將位於 Request 的正文中。

export default {
  async fetch(request: Request): Promise<Response> {
    const event = await request.json();
    // ...
    return new Response();
  },
};

GitHub Action 支援

新版本的 setup-bun GitHub Action 已發布,您也可以在 GitHub Marketplace 上找到它。感謝 @xHyroM 維護其初始版本。

- uses: oven-sh/setup-bun@v1
  with:
    bun-version: latest
- uses: oven-sh/setup-bun@v1
  with:
    bun-version: "0.5.7"

現在,隨著新增加的 git 依賴項支援,我們鼓勵您在 GitHub CI 中試用它,看看使用 bun install 可以節省多少時間。

steps:
  - uses: actions/checkout@v3
  - uses: actions/setup-node@v3
    with:
      node-version: 16
+ - uses: oven-sh/setup-bun@v1
+   with:
+     bun-version: latest
+  - run: bun install
-  - run: npm install

變更日誌

523b112@Jarred-Sumnerbun test 中新增了 jest 全域變數的自動匯入
#2029@alexlamsl 修正了 fs.createWriteStream() 過早退出的問題
995880a@Jarred-Sumner 啟用了更多 Set 方法
#2039@alexlamsl 修正了 peerDependencies 的「重複依賴項」錯誤
#2044@ekzhang 修正了 macOS 的不正確建置說明
#2041@jwhear 修正了 package.json 中存在 regex 時的語法錯誤
675529b@Jarred-Sumner 修正了 Buffer 無法賦值的錯誤
#2054@ThatOneBro 實作了 napi_fatal_exception
#2045@alexlamsl 修正了非安裝腳本執行期間 bun install 崩潰的問題
83473c6@Jarred-Sumnerrequire("module") 中定義了 globalPaths 的後備方案
#2057@michalwarda 修正了 server.listen() 未傳回伺服器的錯誤
bb2aaa3@Electroid 啟用了發行簽署
#2059@alexlamsl 實作了 git://github.com 依賴項
#2051@Jarred-Sumner 實作了 FormData
0db8cdf@Jarred-Sumner 修正了 fetch() 未傳送預設 Content-Type 標頭的問題
#2061@ThatOneBro 實作了 napi_get_value_bigint_words
#2062@michalwarda 允許在 Bun.serve() 中使用 { port: 0 } 來使用隨機端口
37186f4@Jarred-Sumner 改進了 FormDataconsole.log() 輸出
#2047@ekzhang 禁止在 fetch() 方法為 GET、HEAD 或 OPTIONS 時使用正文
#1798@ThatOneBro 匯出了 fs.ReadStreamfs.WriteStream
#2074@alexlamsl 改進了 package.json 的驗證
4dc6bf1@Jarred-Sumner 新增了 node:tlsnode:worker_threads 的變通方法
#2076@alexlamsl 修正了網路延遲的 .bin 腳本未安裝的錯誤
f19e3d6@Jarred-Sumner 新增了 node:async_hooks 的變通方法
#1971@Jarred-Sumner 實作了 WebCrypto 的 ED25519,感謝 @panva
0d7cea6@Jarred-Sumner 新增了 eval("__dirname") 的變通方法
1125728@Jarred-Sumner 修正了 napi_create_threadsafe_function 的錯誤
#2087@controversial 改進了在 macOS 上建置的文件
#2089@jwhear 修正了 writeFileSync({ flag: undefined }) 無法運作的問題
#2088@jwhear 實作了 Linux 的 os.machine()
#2086@Jarred-Sumner 支援了類似 yarn 的工作區
56b75db@Jarred-Sumner 實作了更快的 Buffer.byteLength("latin1")
#2095@alexlamsl 修正了 bun add 帶有大寫字母的套件的問題
#2096@jwhear 修正了 String.replace() 帶有非 ASCII 字元的問題
#2094@alexlamsl 支援了 git 依賴項
#2066@jwhear 修正了 fetch() 標頭中無效編碼導致崩潰的問題
1106c8e@Jarred-Sumner 修正了 fs 標誌的解析
#1378@sno2 實作了 macOS 的 os.machine()
#2104@MichaReiser 修正了 URL 列印方式的變更
c006a7f@Jarred-Sumner 在 NODE_ENV=production 時載入 .env.production
#2122@dylan-conway 將美觀字串差異器新增至 bun test
#2124@alexlamsl 支援了 git 依賴項
#2009@Electroid 實作了 AWS Lambda 上 Bun 的執行階段層
#2128@ThatOneBro 修正了 child_process.exec() 中的輸出
#2131@dylan-conwaybun wiptest 重新命名為 bun test
#2126@WebReflection 修正了 alpine Docker 映像中的 glibc 錯誤
#2135@colinhacks 改進了 bun-types 的各種型別
2a1558e@Jarred-Sumner 支援了 Node.js 風格的 setTimeout()
#2097@cirospaciari 支援了 fetch() 中的 AbortSignal