Bun
    Bun

Bun v1.1.37


Dylan Conway · 2024 年 11 月 26 日

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

此版本修正了 62 個錯誤(解決了 109 個 👍)。它在 VSCode 中引入了即時錯誤報告和測試執行器、self-referencing importrequire、package.json config 環境變數、改進的 CSS 解析器錯誤、Prisma 記憶體洩漏的修復、bun install 回歸問題、expect.toMatchSnapshot 引號逸出、影響 http2-wrappernode:net 回歸問題,以及其他幾個錯誤修正和改進。

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

VSCode 中的即時免除錯器錯誤報告

Bun for VSCode 現在當您在 VSCode 終端機中執行 bun 時,會在「問題」標籤中報告執行階段錯誤及其堆疊追蹤。這在未附加除錯器的情況下工作,無需設定,也無需暫停執行。沒有額外的設定,它就能直接運作。

開始使用

  1. 安裝 Bun for VSCode
  2. 在 VSCode 中開啟終端機
  3. 執行 bun test --watchbun run foo.ts 或任何其他腳本
  4. 在「問題」標籤中查看報告的錯誤

這與 TypeScript、ESLint 和 Biome 等工具有何不同?

執行階段錯誤沒有誤報,但它們只會在您執行程式碼時出現。

執行階段錯誤僅在錯誤阻止進一步執行時才會出現,例如未捕獲的例外、被拒絕的 Promise 或停止執行的測試失敗。您通常只會獲得總共 1 個錯誤,這與靜態分析工具不同,靜態分析工具在不執行任何程式碼的情況下報告許多錯誤。

我仍然可以使用 TypeScript、ESLint 或 Biome 嗎?

是的! 這與 TypeScript、ESLint 或 Biome 等靜態分析工具完美協同工作。它不會競爭或取代它們。

這會報告靜態分析工具無法捕獲的錯誤

  • 檔案系統錯誤,例如 ENOENT
  • 從解析無效 JSON 產生的語法錯誤
  • 例外,例如 TypeErrorRangeError

另一方面,這一次只會報告一個錯誤。它不是來自讀取您的程式碼,而是來自執行您的程式碼。

非常感謝 @alii 實作此功能。

Self-referencing import & require

Bun v1.1.37 在模組內新增了對 self-referencing import 的支援。這允許模組透過其 package.json 中的 exports 欄位,依名稱匯入自身。

給定模組 foo 的 package.json 和 foo.js

./package.json
./foo.js
./package.json
{
    "name": "foo",
    "exports": {
        ".": "./foo.js"
    }
}
./foo.js
import * as foo from 'foo';
export const bar = foo;

以下 index.js 中的程式碼將印出 true

./index.js
import * as foo from 'foo';
console.log(foo.bar === foo); // true

感謝 @SunsetTechuila 實作!

影響 Prisma 的記憶體洩漏已修正

napi_threadsafe_function 是一種結構,其他執行緒可以使用它來將呼叫函數的請求排入主 JavaScript 執行緒的佇列。這是必要的,因為 JavaScript 是單執行緒的,而且您無法從任何其他執行緒存取 JavaScript 引擎。先前版本的 Bun 從未釋放用於追蹤 threadsafe function 待處理呼叫的佇列,這表現為每個 Prisma 查詢 8 位元組的記憶體洩漏,因為每個查詢都會建立佇列大小為 1 的 threadsafe function。我們預期此變更也可能修復其他 Node-API 套件中的記憶體洩漏,但 Prisma 是最廣泛報告的洩漏。

Windows 上 shadcn & sv 中的崩潰已修正

Windows 上的崩潰問題已修正,常見於 shadcnsvpromptssolidui-clicreate-astro 等 CLI 套件中。錯誤存在於 C++ 中的 node:readline setRawMode,其中類型被錯誤地轉換為另一個類型。

感謝 @heimskr 的修正!

使用 bun runnpm_package_config_ 環境變數

我們新增了對從 package.json 中的 config 欄位填入 npm_package_config_ 環境變數的支援。

給定 package.json

package.json
{
    "name": "env",
    "config": {
        "foo": "bar",
    },
    "scripts": {
        "echo": "echo $npm_package_config_foo"
    }
}

執行 bun run echo 將印出 bar

我們還為腳本名稱新增了 npm_lifecycle_event,為腳本值新增了 npm_lifecycle_script,以及為 bun runbun publishbun pm pack 新增了 npm_command 變數。

bun run:      npm_command=run-script
bun publish:  npm_command=publish
bun pm pack:  npm_command=pack

感謝 @nektro

改進的 CSS 解析器錯誤訊息

我們已變更 CSS 解析器中的錯誤訊息,使其更具描述性和更實用。例如,在 @import 之前宣告規則會產生

sh
red.css
bun build --experimental-css red.css

error: @import rules must come before any other rules except @charset and @layer
    at /path/to/red.css:5:8
red.css
div {
    color: red;
}

@import url('blue.css');

此版本中已改進此錯誤和許多其他錯誤。變更的片段

src/css/error.zig
return switch (this) {
-    .at_rule_invalid => |name| writer.print("at_rule_invalid: {s}", .{name}),
-    .unexpected_token => |token| writer.print("unexpected_token: {}", .{token}),
-    .selector_error => |err| writer.print("selector_error: {}", .{err}),
-    else => writer.print("{s}", .{@tagName(this)}),
+    .at_rule_body_invalid => writer.writeAll("Invalid at-rule body"),
+    .at_rule_prelude_invalid => writer.writeAll("Invalid at-rule prelude"),
+    .at_rule_invalid => |name| writer.print("Unknown at-rule @{s}", .{name}),
+    .end_of_input => writer.writeAll("Unexpected end of input"),
+    .invalid_declaration => writer.writeAll("Invalid declaration"),
+    .invalid_media_query => writer.writeAll("Invalid media query"),
+    .invalid_nesting => writer.writeAll("Invalid CSS nesting"),
+    .deprecated_nest_rule => writer.writeAll("The @nest rule is deprecated, use standard CSS nesting instead"),
+    .invalid_page_selector => writer.writeAll("Invalid @page selector"),
+    .invalid_value => writer.writeAll("Invalid value"),
+    .qualified_rule_invalid => writer.writeAll("Invalid qualified rule"),
+    .selector_error => |err| writer.print("Invalid selector. {s}", .{err}),
+    .unexpected_import_rule => writer.writeAll("@import rules must come before any other rules except @charset and @layer"),
+    .unexpected_namespace_rule => writer.writeAll("@namespace rules must come before any other rules except @charset, @import, and @layer"),
+    .unexpected_token => |token| writer.print("Unexpected token. {}", .{token}),
+    .maximum_nesting_depth => writer.writeAll("Maximum CSS nesting depth exceeded"),
};

感謝 @zackradisic

改進的 Bun.write 錯誤訊息

現在,當傳遞意外的引數時,Bun.write 會印出接收到的值。例如,將 BigInt 作為第一個引數傳遞將印出

bun --print "Bun.write(1n, 'hello stdout')"

TypeError: The "destination" argument must be of type path, file descriptor, or Blob. Received 1n
 code: "ERR_INVALID_ARG_TYPE"

      at /home/[eval]:1:5

Bun v1.1.37 (macOS arm64)

感謝 @nektro

performance.markResourceTiming stub

我們已 stubbed performance.markResourceTiming 以解除封鎖依賴它的套件。雖然該函數只會傳回 undefined,但它將不再在 @sveltejs/adapter-cloudflare 等套件中擲回執行階段錯誤。

如果檔案在 Windows 上過大,Bun.file 會擲回 OOM 錯誤

如果檔案大於 4GB,Bun.file 現在會在 Windows 上擲回 OOM 錯誤。先前,它會因斷言失敗而崩潰。感謝 @cirospaciari 的修正!

index.js
const hugeFile = Bun.file('huge-file.txt'); // throws ENOMEM
console.log(hugeFile.size);

bun install 中的回歸問題已修正

在 v1.1.35 中減少 Bun 二進制檔案大小的部分工作是將 Bun 的套件管理器狀態移出二進制檔案的 BSS 區段,並在需要時在堆積中分配它。此變更在解析別名依賴項(例如 npm:zod@1.11.17)時,由於存取未定義的記憶體而導致崩潰。

此問題已在此版本中修正,感謝 @dylan-conway

expect.toMatchSnapshot 中引號和模板逸出問題已修正

expect.toMatchSnapshot 將字串化的測試名稱加上計數器和接收到的值寫入磁碟,兩者都在模板字串內。修復逸出問題的版本,其中反引號和 ${} 未正確逸出,導致快照在重新執行測試時無法比對。

index.test.ts
import { expect, test } from "bun:test";

test("snapshot `foo`", () => {
    const foo: string = "hello ${}!";
    expect(bar).toMatchSnapshot();
});

感謝 @pfgithub 的修正!

bun --hot 在進入點中使用單引號的問題已修正

先前,當進入點包含單引號時,bun --hot 會報告語法錯誤。

bun --hot "src/single'quote.ts"

現在,Bun 將如預期執行進入點,感謝 @pfgithub

修正了在沒有引數的情況下呼叫 WebSocket.ping

修復了一個錯誤,其中在沒有引數的情況下呼叫 WebSocket.ping 將無法傳送沒有 payload 的訊息。

import { WebSocketServer } from "ws";

const server = new WebSocketServer({ noServer: true });

server.on("connection", (ws) => {
  ws.ping(); // fixed
});

感謝 @cirospaciari 的修正!

列印 \uFFFF 中的回歸問題

我們的 JavaScript 印表機中的回歸問題導致 \uFFFF 列印不正確。此問題已修正,現在可以如預期般運作。

bun --print "'\uFFFF'.charCodeAt(1)"
# Previously:  57343
# Bun v1.1.37: NaN

感謝 @pfgithub

bun test 中不存在的絕對檔案路徑的非零傳回值

給定不存在的檔案的絕對檔案路徑,bun test 現在將以非零結束代碼以及模組解析錯誤結束。先前,會報告錯誤,但結束代碼為 0。

bun test /path/to/non-existent-file.test.ts

error: ModuleNotFound resolving "/path/to/non-existent-file.test.ts" (entry point)

node:net 回歸問題已修正

影響 http2-wrapper 套件的回歸問題已修正。原因是 node:net 內建模組中的變更,其中 TLSSocket._handle._parentWrap 未正確設定為 JSStreamSocket

修正在 watch 或 hot 模式下錯誤列印兩次的問題

使用 --watch--hot 執行腳本會將未處理的例外列印到主控台兩次。一個簡單的例子是

$ bun --watch --print "throw new Error('oops!')"
1 | throw new Error('oops')
          ^
error: oops!
      at /home/user/[eval]:1:7
1 | throw new Error('oops')
          ^
error: oops!
      at /home/user/[eval]:1:7

此問題已修正,現在只會列印一次,感謝 @alii

bun build 中以瀏覽器為目標使用 node:buffer

修復了在以 bun build 以瀏覽器為目標時,阻止從 node:buffer 匯入 Buffer 的錯誤。現有程式碼可以透過預設匯出存取 Buffer,但直接匯入 Buffer 會失敗。

import { Buffer } from "node:buffer";
const buf = Buffer.from("bun!");
console.log(buf.toString());
bun build --target browser --outfile out.js
# Previously:  error: No matching export in "../../../../../bun-vfs$$/node_modules/buffer/index.js" for import "Buffer"
# Bun v1.1.37: out.js  41.66 KB

感謝 14 位貢獻者!