Bun

Bun v1.0.13


Jarred Sumner · 2023 年 11 月 18 日

Bun v1.0.13 修復了 6 個錯誤(解決了 317 個 👍 表情符號反應),新增了對 "node:http2" 模組的支援(解除封鎖 Bun 中的 gRPC)。Vite 5 和 Rollup 4 現在可以運作了。實作了 process.report.getReport(),改進了對 ES5 with 陳述式的支援,修復了 bun install 中的回歸錯誤,並修復了列印例外時的崩潰問題。

Bun 是一個極速的 JavaScript 執行時、打包器、轉譯器和套件管理器,集所有功能於一身。如果您錯過了,以下是 Bun 最近的一些變更

  • v1.0.8 - 修復了 138 個錯誤(解決了 257 個 👍 表情符號反應),使 require() 使用的記憶體減少 30%,新增了模組模擬到 bun test,修復了更多 bun install 錯誤
  • v1.0.9 - 修復了 glibc 符號版本錯誤、非法指令錯誤、Bun.spawn 錯誤、對等相依性安裝的邊緣案例,以及 JSX 轉譯器錯誤修復
  • v1.0.10 - 修復了 14 個錯誤(解決了 102 個 👍 表情符號反應),node:http 速度提升 14%,Bun for Linux ARM64 的穩定性改進,bun install 錯誤修復,以及 node:http 錯誤修復
  • v1.0.11 - 修復了 5 個錯誤,新增了 Bun.semver,修復了 bun install 中的一個錯誤,並修復了影響 astro@google-cloud/storage 的錯誤
  • v1.0.12 - 新增了用於評估腳本的 bun -e、用於載入環境變數的 bun --env-fileserver.urlimport.meta.envexpect.unreachable()、改進的 CLI 說明輸出,以及更多

若要安裝 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

http2 用戶端支援

您現在可以在 Bun 中使用 node:http2 模組的用戶端函式了!

import { connect } from "node:http2";
const client = connect("https://example.com");

const req = client.request({ ":path": "/" });

req.on("response", (headers, flags) => {
  for (const name in headers) {
    console.log(`${name}: ${headers[name]}`);
  }
});

感謝 @cirospaciari

gRPC 現在可以運作了

我們的 node:http2 實作解除了 Bun 中 gRPC.js 的封鎖。@grpc/grpc-js 是 Node.js 的熱門 gRPC 用戶端和伺服器函式庫。

import { loadPackageDefinition } from "@grpc/grpc-js";
import { join } from "path";

const protoPath = join(__dirname, "protos/helloworld.proto");
const packageDefinition = loadPackageDefinition(protoPath);

const client = new packageDefinition.helloworld.Greeter(
  "localhost:50051",
  credentials.createInsecure(),
);

client.sayHello({ name: "world" }, (err, response) => {
  console.log("Greeting:", response.message);
});

為了防止回歸錯誤,我們已將 grpc 的大部分測試套件移植到每次提交到 Bun 時執行。

感謝 @cirospaciari

Vite 5 和 Rollup 4 現在可以運作了

Bun 中有兩個錯誤阻止了 Vite 5 和 Rollup 4 開箱即用。這兩個錯誤都已在 Bun v1.0.13 中修復。

process.report.getReport() 現在已實作

Node.js API process.report.getReport 現在已在 Bun 中實作。原生附加元件經常使用它來取得目前的 libc 版本,以及 Linux 上是否正在使用 glibc 或 musl。

偵測 libc 這個特定的使用案例,是阻止 Rollup 4(Vite 5 依賴它)在 Bun 中運作的原因。現在 process.report.getReport() 已實作,Rollup 4 可以在 Bun 中運作了。

為了防止回歸錯誤,我們新增了一個整合測試,在每次提交時於 Bun 中執行 Rollup 4。

轉譯器錯誤,涉及 require 和三元運算子,已修復

修復了在呼叫 require() 的三元運算子中使用靜態已知的純常數時的轉譯器錯誤。此錯誤阻止了 Vite 5 在 Bun 中運作。感謝 @dylan-conway 的修復。

改進了對 ES5 with 陳述式的支援

在解構賦值的時代之前,with 陳述式是避免輸入長物件名稱的熱門方式。

例如,不用寫成

import { join } from "path";
join(__dirname, "foo");

您可以寫成

with (require("path")) {
  join(__dirname, "foo");
}

今天,許多開發人員會因為您使用 with 而對您生氣。但它是 JavaScript 的一部分,Bun 必須支援它。重要的是,人們依賴的熱門函式庫中使用了 with,而這些函式庫必須在 Bun 中運作。

使用 with 現在會使檔案變成 CommonJS

嚴格模式下不支援 with 陳述式。ES 模組僅限於嚴格模式。

先前,當您使用 with 而沒有任何其他 CommonJS 語法時,Bun 會拋出如下錯誤

SyntaxError: 'with' statements are not valid in strict mode.

現在,如果您使用 with,Bun 會自動將檔案轉換為 CommonJS

with (require("path")) {
  join(__dirname, "foo");
}

Bun.spawn 更好的錯誤訊息

先前,當目前的工作目錄不存在等錯誤發生時,Bun.spawn 會在 macOS 上靜默失敗

Bun.spawn({
  cwd: "/i/dont/exist!",
  cmd: ["ls"],
});

現在,它(正確地)會拋出錯誤

ENOENT: No such file or directory
   path: "/opt/homebrew/opt/coreutils/libexec/gnubin/ls"
 syscall: "posix_spawn"
   errno: -2

這要感謝 @Electroid 的修復。

為何會發生這種情況?

大多數 C 系統呼叫包裝函式會傳回 -1,然後期望開發人員檢查 errnoposix_spawn 有點不尋常。相反地,任何非零值都是錯誤,並且直接傳回 errno。我們當時正在檢查 errno,errno 回報一切正常,因此我們沒有拋出錯誤。

我們已新增一個測試來檢查 posix_spawn 是否會相應地拋出錯誤。

bun install 中的回歸錯誤已修復

已修復在某些情況下導致 bun install 中出現 "FileNotFound" 錯誤的回歸錯誤,感謝 @dylan-conway

對等相依性決定性問題已修復

有時一個錯誤會導致 bun install 非決定性地選擇要安裝哪個對等相依性版本。此錯誤已修復,感謝 @dylan-conway

已修復:The Stats.atime getter can only be used on instances of Stats

以下錯誤已修復

const { Stats } = require("node:fs");
const stat = Object.create(Stats.prototype);
stat.atime; // previously: threw "The Stats.atime getter can only be used on instances of Stats"

某些函式庫使用 Object.create(Stats.prototype) 建立 Stats 物件。先前,當您嘗試存取以此方式建立的 Stats 物件上的 atime 時(目前以類別實作),Bun 會拋出錯誤。現在,Bun 會傳回 undefined 而不是拋出錯誤,並允許設定欄位。

這解除了某些函式庫的封鎖。

已修復:node:http 中的 new Server

以下錯誤已修復

import { Server } from "http";
new Server({ key: "123" });

先前,這會拋出以下錯誤

TypeError: key argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile

此錯誤不正確。現在不再出錯。

感謝 @HK-SHAO 的修復。

已修復:napi_get_value_string_utf8 現在的行為與 Node.js 類似

Bun 的 napi_get_value_string_utf8 實作現在更接近 Node.js 的行為,感謝 @oguimbal

CommonJS 模組中配置的字串稍微減少

CommonJS 模組具有 requirerequire.resolve 函式。

在 Bun 中,這些函式是以 .bind 呼叫的原生碼等效形式實作的。繫結函式預設會變更名稱,但程式碼預期 require.name 傳回 "require",而 require.resolve.name 傳回 "resolve" - 因此我們必須手動設定名稱。

事實證明,我們手動設定名稱的方式導致每次載入任何 CommonJS 模組時,名稱都會成為新建立的字串。這兩個字串很小,但如果您載入數百個模組,就會累積起來。

require("discord.js");
const { heapStats } = require("bun:jsc");
const { strings } = heapStats().objectTypeCounts;

console.log(strings, "+ strings allocated");
之前之後
10,397 個字串9,628 個字串

載入 Discord.js 時,字串配置減少了 7.9%

這會對效能產生影響嗎?可能不會。但這是一個很好的清理。

感謝 9 位貢獻者!