Bun.version
包含目前正在執行的 bun
CLI 版本的 字串
。
Bun.version;
// => "0.6.4"
Bun.revision
編譯用於建立目前 bun
CLI 的 Bun 的 git commit。
Bun.revision;
// => "f02561530fda1ee9396f51c8bc99b38716e38296"
Bun.env
process.env
的別名。
Bun.main
目前程式進入點的絕對路徑(使用 bun run
執行的檔案)。
Bun.main;
// /path/to/script.ts
這對於判斷腳本是否直接執行,而不是由其他腳本匯入,特別有用。
if (import.meta.path === Bun.main) {
// this script is being directly executed
} else {
// this file is being imported from another script
}
這類似於 Node.js 中的 require.main = module
技巧。
Bun.sleep()
Bun.sleep(ms: number)
傳回一個在給定毫秒數後解決的 Promise
。
console.log("hello");
await Bun.sleep(1000);
console.log("hello one second later!");
或者,傳遞一個 Date
物件以接收在該時間點解決的 Promise
。
const oneSecondInFuture = new Date(Date.now() + 1000);
console.log("hello");
await Bun.sleep(oneSecondInFuture);
console.log("hello one second later!");
Bun.sleepSync()
Bun.sleepSync(ms: number)
Bun.sleep
的同步封鎖版本。
console.log("hello");
Bun.sleepSync(1000); // blocks thread for one second
console.log("hello one second later!");
Bun.which()
Bun.which(bin: string)
傳回可執行檔的路徑,類似於在終端機中輸入 which
。
const ls = Bun.which("ls");
console.log(ls); // "/usr/bin/ls"
預設情況下,Bun 會查看目前的 PATH
環境變數以確定路徑。若要設定 PATH
const ls = Bun.which("ls", {
PATH: "/usr/local/bin:/usr/bin:/bin",
});
console.log(ls); // "/usr/bin/ls"
傳遞 cwd
選項以從特定目錄中解析可執行檔。
const ls = Bun.which("ls", {
cwd: "/tmp",
PATH: "",
});
console.log(ls); // null
Bun.peek()
Bun.peek(prom: Promise)
在沒有 await
或 .then
的情況下讀取 promise 的結果,但僅限於 promise 已完成或已拒絕的情況。
import { peek } from "bun";
const promise = Promise.resolve("hi");
// no await!
const result = peek(promise);
console.log(result); // "hi"
在效能敏感的程式碼中嘗試減少多餘的微刻度時,這一點很重要。這是一個進階 API,除非您知道自己在做什麼,否則您可能不應該使用它。
import { peek } from "bun";
import { expect, test } from "bun:test";
test("peek", () => {
const promise = Promise.resolve(true);
// no await necessary!
expect(peek(promise)).toBe(true);
// if we peek again, it returns the same value
const again = peek(promise);
expect(again).toBe(true);
// if we peek a non-promise, it returns the value
const value = peek(42);
expect(value).toBe(42);
// if we peek a pending promise, it returns the promise again
const pending = new Promise(() => {});
expect(peek(pending)).toBe(pending);
// If we peek a rejected promise, it:
// - returns the error
// - does not mark the promise as handled
const rejected = Promise.reject(
new Error("Successfully tested promise rejection"),
);
expect(peek(rejected).message).toBe("Successfully tested promise rejection");
});
peek.status
函式讓您可以在不解析 promise 的情況下讀取其狀態。
import { peek } from "bun";
import { expect, test } from "bun:test";
test("peek.status", () => {
const promise = Promise.resolve(true);
expect(peek.status(promise)).toBe("fulfilled");
const pending = new Promise(() => {});
expect(peek.status(pending)).toBe("pending");
const rejected = Promise.reject(new Error("oh nooo"));
expect(peek.status(rejected)).toBe("rejected");
});
Bun.openInEditor()
在您的預設編輯器中開啟一個檔案。Bun 會透過 $VISUAL
或 $EDITOR
環境變數自動偵測您的編輯器。
const currentFile = import.meta.url;
Bun.openInEditor(currentFile);
您可以透過 bunfig.toml
中的 debug.editor
設定來覆寫此設定。
[debug]
editor = "code"
或者使用 editor
參數指定一個編輯器。您也可以指定行號和欄位號。
Bun.openInEditor(import.meta.url, {
editor: "vscode", // or "subl"
line: 10,
column: 5,
});
Bun.ArrayBufferSink;
Bun.deepEquals()
遞迴檢查兩個物件是否相等。這在 bun:test
中的 expect().toEqual()
內部使用。
const foo = { a: 1, b: 2, c: { d: 3 } };
// true
Bun.deepEquals(foo, { a: 1, b: 2, c: { d: 3 } });
// false
Bun.deepEquals(foo, { a: 1, b: 2, c: { d: 4 } });
可以使用第三個布林參數來啟用「嚴格」模式。這在測試執行器中的 expect().toStrictEqual()
中使用。
const a = { entries: [1, 2] };
const b = { entries: [1, 2], extra: undefined };
Bun.deepEquals(a, b); // => true
Bun.deepEquals(a, b, true); // => false
在嚴格模式中,下列情況會被視為不相等
// undefined values
Bun.deepEquals({}, { a: undefined }, true); // false
// undefined in arrays
Bun.deepEquals(["asdf"], ["asdf", undefined], true); // false
// sparse arrays
Bun.deepEquals([, 1], [undefined, 1], true); // false
// object literals vs instances w/ same properties
class Foo {
a = 1;
}
Bun.deepEquals(new Foo(), { a: 1 }, true); // false
Bun.escapeHTML()
Bun.escapeHTML(value: string | object | number | boolean): string
從輸入字串中跳脫下列字元
"
變成"""
&
變成"&"
'
變成"'"
<
變成"<"
>
變成">"
此函式針對大型輸入進行最佳化。在 M1X 上,它會處理 480 MB/s - 20 GB/s,具體取決於要跳脫的資料量以及是否有非 ASCII 文字。非字串類型在跳脫之前會轉換為字串。
Bun.stringWidth()
~6,756 倍快的 string-width
替代方案
取得字串的欄位數,就像它在終端機中顯示的那樣。支援 ANSI 跳脫碼、表情符號和寬字元。
範例用法
Bun.stringWidth("hello"); // => 5
Bun.stringWidth("\u001b[31mhello\u001b[0m"); // => 5
Bun.stringWidth("\u001b[31mhello\u001b[0m", { countAnsiEscapeCodes: true }); // => 12
這對以下情況很有用
- 在終端機中對齊文字
- 快速檢查字串是否包含 ANSI 跳脫碼
- 在終端機中測量字串寬度
此 API 設計用於搭配知名的「string-width」套件,以便現有程式碼可以輕鬆移植到 Bun,反之亦然。
在此基準測試中,對於大於約 500 個字元的輸入,Bun.stringWidth
比 string-width
npm 套件快約 6,756 倍。非常感謝 sindresorhus 在 string-width
上的貢獻!
❯ bun string-width.mjs
cpu: 13th Gen Intel(R) Core(TM) i9-13900
runtime: bun 1.0.29 (x64-linux)
benchmark time (avg) (min … max) p75 p99 p995
------------------------------------------------------------------------------------- -----------------------------
Bun.stringWidth 500 chars ascii 37.09 ns/iter (36.77 ns … 41.11 ns) 37.07 ns 38.84 ns 38.99 ns
❯ node string-width.mjs
benchmark time (avg) (min … max) p75 p99 p995
------------------------------------------------------------------------------------- -----------------------------
npm/string-width 500 chars ascii 249,710 ns/iter (239,970 ns … 293,180 ns) 250,930 ns 276,700 ns 281,450 ns
為了讓 Bun.stringWidth
執行得更快,我們使用 Zig 實作,並採用最佳化的 SIMD 指令,考量 Latin1、UTF-16 和 UTF-8 編碼。它通過了 string-width
的測試。
檢視完整的基準測試
TypeScript 定義
namespace Bun {
export function stringWidth(
/**
* The string to measure
*/
input: string,
options?: {
/**
* If `true`, count ANSI escape codes as part of the string width. If `false`, ANSI escape codes are ignored when calculating the string width.
*
* @default false
*/
countAnsiEscapeCodes?: boolean;
/**
* When it's ambiugous and `true`, count emoji as 1 characters wide. If `false`, emoji are counted as 2 character wide.
*
* @default true
*/
ambiguousIsNarrow?: boolean;
},
): number;
}
Bun.fileURLToPath()
將 file://
URL 轉換為絕對路徑。
const path = Bun.fileURLToPath(new URL("file:///foo/bar.txt"));
console.log(path); // "/foo/bar.txt"
Bun.pathToFileURL()
將絕對路徑轉換為 file://
URL。
const url = Bun.pathToFileURL("/foo/bar.txt");
console.log(url); // "file:///foo/bar.txt"
Bun.gzipSync()
使用 zlib 的 GZIP 演算法壓縮 Uint8Array
。
const buf = Buffer.from("hello".repeat(100)); // Buffer extends Uint8Array
const compressed = Bun.gzipSync(buf);
buf; // => Uint8Array(500)
compressed; // => Uint8Array(30)
選擇性地將參數物件傳遞為第二個引數
zlib 壓縮選項
Bun.gunzipSync()
使用 zlib 的 GUNZIP 演算法解壓縮 Uint8Array
。
const buf = Buffer.from("hello".repeat(100)); // Buffer extends Uint8Array
const compressed = Bun.gzipSync(buf);
const dec = new TextDecoder();
const uncompressed = Bun.gunzipSync(compressed);
dec.decode(uncompressed);
// => "hellohellohello..."
Bun.deflateSync()
使用 zlib 的 DEFLATE 演算法壓縮 Uint8Array
。
const buf = Buffer.from("hello".repeat(100));
const compressed = Bun.deflateSync(buf);
buf; // => Uint8Array(25)
compressed; // => Uint8Array(10)
第二個引數支援與 Bun.gzipSync
相同的組態選項。
Bun.inflateSync()
使用 zlib 的 INFLATE 演算法解壓縮 Uint8Array
。
const buf = Buffer.from("hello".repeat(100));
const compressed = Bun.deflateSync(buf);
const dec = new TextDecoder();
const decompressed = Bun.inflateSync(compressed);
dec.decode(decompressed);
// => "hellohellohello..."
Bun.inspect()
將物件序列化成一個字串,其內容與 console.log
印出的內容完全相同。
const obj = { foo: "bar" };
const str = Bun.inspect(obj);
// => '{\nfoo: "bar" \n}'
const arr = new Uint8Array([1, 2, 3]);
const str = Bun.inspect(arr);
// => "Uint8Array(3) [ 1, 2, 3 ]"
Bun.inspect.custom
這是 Bun 用來實作 Bun.inspect
的符號。你可以覆寫它以自訂物件的列印方式。它與 Node.js 中的 util.inspect.custom
相同。
class Foo {
[Bun.inspect.custom]() {
return "foo";
}
}
const foo = new Foo();
console.log(foo); // => "foo"
Bun.nanoseconds()
傳回自目前的 bun
程序開始以來經過的奈秒數,以 number
型態表示。對於高精準度計時和效能測試很有用。
Bun.nanoseconds();
// => 7288958
Bun.readableStreamTo*()
Bun 實作了一組便利函式,用於非同步地消耗 ReadableStream
的主體並將其轉換成各種二進位格式。
const stream = (await fetch("https://bun.dev.org.tw")).body;
stream; // => ReadableStream
await Bun.readableStreamToArrayBuffer(stream);
// => ArrayBuffer
await Bun.readableStreamToBlob(stream);
// => Blob
await Bun.readableStreamToJSON(stream);
// => object
await Bun.readableStreamToText(stream);
// => string
// returns all chunks as an array
await Bun.readableStreamToArray(stream);
// => unknown[]
// returns all chunks as a FormData object (encoded as x-www-form-urlencoded)
await Bun.readableStreamToFormData(stream);
// returns all chunks as a FormData object (encoded as multipart/form-data)
await Bun.readableStreamToFormData(stream, multipartFormBoundary);
Bun.resolveSync()
使用 Bun 的內部模組解析演算法解析檔案路徑或模組指定符。第一個參數是要解析的路徑,第二個參數是「根目錄」。如果找不到符合的項目,則會擲回 Error
。
Bun.resolveSync("./foo.ts", "/path/to/project");
// => "/path/to/project/foo.ts"
Bun.resolveSync("zod", "/path/to/project");
// => "/path/to/project/node_modules/zod/index.ts"
若要相對於目前的工作目錄解析,請將 process.cwd()
或 "."
傳入作為根目錄。
Bun.resolveSync("./foo.ts", process.cwd());
Bun.resolveSync("./foo.ts", "/path/to/project");
若要相對於包含目前檔案的目錄解析,請傳入 import.meta.dir
。
Bun.resolveSync("./foo.ts", import.meta.dir);
serialize
& deserialize
in bun:jsc
若要將 JavaScript 值儲存到 ArrayBuffer 中並取回,請使用 "bun:jsc"
模組中的 serialize
和 deserialize
。
import { serialize, deserialize } from "bun:jsc";
const buf = serialize({ foo: "bar" });
const obj = deserialize(buf);
console.log(obj); // => { foo: "bar" }
在內部,structuredClone
和 postMessage
以相同的方式序列化和反序列化。這會將底層的 HTML Structured Clone Algorithm 以 ArrayBuffer 的形式公開給 JavaScript。