Bun

Bun v0.6.9


Jarred Sumner · 2023 年 6 月 13 日

我們正在招募 C/C++ 和 Zig 工程師,一同打造 JavaScript 的未來!加入我們的團隊 →

我們最近發布了 Bun 的許多變更,這裡為您整理了重點回顧,以防您錯過任何資訊

  • v0.6.0 - 推出 bun build,Bun 的全新 JavaScript 打包器。
  • v0.6.2 - 效能提升:JSON.parse 速度提升 20%,Proxyarguments 速度提升高達 2 倍。
  • v0.6.3 - 實作 node:vm,並大幅修正 node:httpnode:tls
  • v0.6.4 - 實作 require.cacheprocess.env.TZ,以及 bun test 速度提升 80%。
  • v0.6.5 - 原生支援 CommonJS 模組 (先前,Bun 會將 CJS 轉譯為 ESM),
  • v0.6.6 - bun test 改善,包含 Github Actions 支援、test.only()test.if()describe.skip(),以及 15 個以上的 expect() 比對器;同時也使用 fetch() 串流檔案上傳。
  • v0.6.7 - Node.js 相容性改善,以解除對 Discord.js、Prisma 和 Puppeteer 的阻礙
  • v0.6.8 - Bun.passwordbun test 中的函數模擬,以及 toMatchObject expect 比對器。外加 Bun.serve() 中實驗性的 inspector 模式。

此版本全面降低 Bun 的記憶體用量,並修正打包器/轉譯器、CommonJS 模組載入、bun runbun install 中的錯誤。

安裝 Bun

curl
npm
brew
docker
curl
curl -fsSL https://bun.dev.org.tw/install | bash
npm
npm install -g 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.serve() 使用更少的記憶體來傳送字串

Bun 現在在 Bun.serve() 中支援零複製字串 Response 主體。

我們也將此最佳化套用至 Bun.serve() 以外的 Response

先前,以下程式碼會複製 text 兩次

const text = await Bun.file("file.txt").text();

// Copy #1
const response = new Response(text);

// Copy #2
await response.text();

現在,它不會複製,為您節省記憶體。

冷啟動 bun install 使用減少 50% 的記憶體

我們現在在 bun install 中釋放更多記憶體,將冷啟動安裝的記憶體用量減少 50%。

在 Bun 執行階段中匯入模組使用更少的記憶體

我們修正了在 Bun 執行階段中匯入模組時發生的一些記憶體洩漏問題,並改善了我們與 JavaScriptCore 針對原始碼管理的綁定。

image

非 ASCII 檔名

先前,當匯入具有非 ASCII 檔名的檔案時,Bun 會拋出錯誤。

shell
👋.js
shell
bun run 👋.js

error: FileNotFound reading "/Users/jarred/Desktop/ð.js"
👋.js
console.log("hello!");

此錯誤是由列印錯誤和 Bun 的 JavaScriptCore 綁定在讀取匯入識別符名稱時的錯誤所造成。

bun test 中模擬的錯誤修正

mockResolvedValue 現在已在 bun test 中修正。先前,mockResolvedValuebun test 中似乎沒有任何作用。

使用 mockResolvedValue 的方式

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

test("hey", async () => {
  const fn = mock.mockResolvedValue(1);

  expect(fn()).toBeInstanceOf(Promise);

  const value = await fn();

  expect(value).toBe(1); // 1
});

傳回的 mock 物件缺少 .bind.apply.call.name.length 函數。此問題已修正。我們也進行了調整,讓模擬函數的 .name 會自動從原始函數複製過來。

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

test("hey", async () => {
  const hey = mock(function yo() {
    return 42;
  });

  expect(hey.name).toBe("yo");
});

CommonJS require() 中的當機錯誤已修正

此版本修正了當匯入許多 CommonJS 檔案,然後在不再使用這些檔案後執行垃圾回收時,可能會發生的當機問題

import "lodash/omit.js";
import "lodash/findIndex.js";
import "discord.js";

Bun.gc(true);

這是 CommonJS 模組載入器中的錯誤,未正確防止函數被垃圾回收。

node:crypto 中的記憶體洩漏已修正

此版本修正了 node:crypto 中的記憶體洩漏問題。以下程式碼每次呼叫會洩漏約 192 位元組。

const crypto = require("crypto");

function sha256(buf) {
  return crypto.createHash("sha256").update(buf).digest();
}

async function main() {
  for (var i = 1000000; i >= 0; i--) {
    const buf = Buffer.alloc(2046);
    const hash = sha256(buf);
    if (i % 1000 === 0) {
      await new Promise((r) => setTimeout(r, 20));
      global.gc ? global.gc() : Bun?.gc(true);
    }
  }
}

main();

修正後

修正前

Node.js,用於比較

更新日誌

#3277新增 --save 參數至 install,由 @kvakil 貢獻
#3292處理任何運算式中 require 的解包裝,由 @dylan-conway 貢獻
#3286readline 中的錯字,由 @paperclover 貢獻
#3290bun run 的引號跳脫問題的解決方案

檢視完整更新日誌