Bun

Bun v0.2.0


Jarred Sumner · 2022 年 10 月 13 日

升級方式

bun upgrade

安裝方式

curl https://bun.dev.org.tw/install | bash

若您在升級時遇到任何問題

Bun v0.2.0 版本介紹

https://user-images.githubusercontent.com/709451/195575815-96df744a-1073-4292-b24d-5ba76c20b942.png

新功能

  • bun --hot 為 Bun 的 JavaScript 執行環境帶來熱重載與零停機重新啟動
  • Bun.spawnBun.spawnSync (程序衍生 API)
  • Request.body - 使用 ReadableStream 的傳入 HTTP 請求主體串流
  • Bun.serve (HTTP 伺服器) 和 fetch() (HTTP 客戶端) 的大量錯誤修復與可靠性改進
  • 重寫 setTimeoutsetInterval 以獲得更佳的效能和可靠性
  • Bun.serve 以及任何使用 Response 物件的記憶體使用量降低 2.7 倍以上
  • package.json 中的 "imports" ("#foo" 引入) 現在已可運作 https://github.com/oven-sh/bun/commit/21770eb0f31a43b3d6127ab957e271d029d6bc1b
  • 使用 HTTP 伺服器、Websocket 等時,"bun:test" 的速度提升約 300 倍 https://github.com/oven-sh/bun/commit/524e48a81dfc6106ffcdd07b6fd035000b03146c
  • 使用 Bun.file(path).writer() 增量寫入檔案
  • 字串的 Array.prototype.indexOf 速度提升 30% (感謝 @Constellation)
  • Array.prototype.map 速度提升 37% (感謝 @Constellation)
  • String.prototype.substring 速度提升 1.4 倍 - 4 倍 (感謝 @Constellation)
  • String.prototype.replace 速度提升 2.8 倍 (感謝 @Constellation)
  • new Blob(["hello world"]) 在 Bun 中的速度比 Node 快 75 倍 - https://github.com/oven-sh/bun/commit/2c1926993bc4d94f9e7bc4d171217a707efd385c

重大變更

  • bun runbun CLI 參數解析已變更,因此在 bun run <檔案或腳本>bun <檔案> 之後的任何內容都會逐字傳遞。這修正了在 Bun 作為執行環境以及用作 package.json "scripts" 執行器時,CLI 參數解析中的多個錯誤。
# before, server.js wouldn't see the --port argument
bun run server.js --port 3000
  • process.version 現在回報偽造的 Node.js 版本,而非 Bun 的版本。這是為了與許多檢查 Node.js 版本以啟用/停用功能的 npm 套件相容。若要取得 Bun 的版本,請使用 Bun.versionprocess.versions.bun

  • Bun.serve().hostname 應傳回主機名稱而非來源 (origin)。這是一項重大變更,因為它會影響如果您之前使用過此 getter,URL 的列印方式。https://github.com/oven-sh/bun/commit/e15fb6b9b220510df049e782d4f2f6eb3150d069

bun --hot:伺服器上的熱重載

bun --hot 可讓您立即看到程式碼變更,而無需重新啟動伺服器。與 nodemon 等常見的檔案監看程式不同,bun --hot 會保留應用程式的部分狀態,表示進行中的 HTTP 請求不會中斷。

refresh speed comparison
左邊是 Bun,右邊是 Nodemon

搭配 Bun 的 HTTP 伺服器使用 (自動)

// The global object is preserved across code reloads
// You can use it to store state, for now until Bun implements import.meta.hot.
const reloadCount = globalThis.reloadCount || 0;
globalThis.reloadCount = reloadCount + 1;

export default {
  fetch(req: Request) {
    return new Response(`Code reloaded ${reloadCount} times`, {
      headers: { "content-type": "text/plain" },
    });
  },
};

然後,執行

bun --hot server.ts

您也可以使用 bun run

bun run --hot server.ts

如需更多資訊,請參閱 Bun readme 中的 bun --hot 章節。

Bun.spawn 在 Bun 中衍生程序

Bun.spawn 可在 Bun 中有效率地衍生新程序。

import { spawn } from "bun";

const { stdout } = await spawn(["echo", "hello world"]);
console.log(
  await new Response(
    // stdout is a ReadableStream
    stdout,
  ).text(),
); // "hello world"

Bun.spawn 非常彈性。stdin 可以是 ResponseBlobRequestArrayBufferArrayBufferViewBun.file"pipe" 或數字。

import { spawn } from "bun";

const { stdout } = spawn({
  cmd: ["esbuild"],
  // using fetch()
  stdin: await fetch(
    "https://raw.githubusercontent.com/oven-sh/bun/main/examples/hashing.js",
  ),
});

const text = await new Response(
  // stdout is a ReadableStream here
  stdout,
).text();
console.log(text.slice(0, 128), "..."); // const input = "hel...

當使用 "pipe" 時,stdoutstderr 會傳回 ReadableStream

Request.bodyResponse.body 傳回 ReadableStream

這修正了 https://github.com/oven-sh/bun/issues/530

您現在可以將 RequestResponse 物件的主體讀取為 ReadableStream

ReadableStream 現在支援非同步迭代器

現在可以運作了

const body = new Response(["hello"]).body;
const chunks = [];
for await (const chunk of body) {
  chunks.push(chunk);
}

先前,您必須像這樣呼叫 getReader()

const reader = body.getReader();
const chunks = [];
while (true) {
  const { done, value } = await reader.read();
  if (done) {
    break;
  }
  chunks.push(value);
}

HTTP 請求主體串流

Bun.serve 現在支援串流請求主體。這對於大型檔案上傳非常有用。

import { serve } from "bun";

serve({
  async fetch(req) {
    // body is a ReadableStream
    const body: ReadableStream = req.body;

    const id = `upload.${Date.now()}.txt`;
    const writer = Bun.file(id).writer();
    for await (const chunk of body) {
      writer.write(chunk);
    }
    const wrote = await writer.close();

    return Response.json({ wrote, id, type: req.headers.get("Content-Type") });
  },
});

package.json 中的 "imports" 支援

此版本新增了對 package.json 中 imports 欄位的支援

image

降低 Bun.serve() 的記憶體使用量

Bun 未正確地向 JavaScriptCore 回報 RequestResponseBlob 物件的記憶體使用量,導致垃圾回收器不知道 HTTP 回應/請求實際使用的記憶體量。

image

bun:test 效能改進

bun:test 中的事件迴圈錯誤導致程序閒置了一段時間。現在 Bun 自己的 HTTP 伺服器測試執行速度快了 10 倍以上。

image

錯誤修正:

  • 修正 console.log 處理循環參考的問題,由 @zhiyuang 於 https://github.com/oven-sh/bun/pull/1293
  • 修正巢狀模組 bin 可執行檔問題,由 @zhiyuang 於 https://github.com/oven-sh/bun/pull/1299
  • 修正在 npm 套件中 node_modules 已存在時的安裝錯誤,由 @zhiyuang 於 https://github.com/oven-sh/bun/pull/1301
  • 修正 fetch 回應重新導向,由 @zhiyuang 於 https://github.com/oven-sh/bun/pull/1303
  • 修正 .json() 的偶發性崩潰 https://github.com/oven-sh/bun/commit/dfefb05b10e57e01faab0d633fc9538a571a566f
  • 修正 Bun.serve() 中不正確的主機名稱邏輯 https://github.com/oven-sh/bun/commit/167948f5c3afc0a4dc482222e42bd255951084ff
  • 允許 .env 檔案多次定義相同的金鑰 https://github.com/oven-sh/bun/commit/e94e6d8d95061c8bdb07ce96bc836689f49aafdd
  • 修正在建立空陣列時崩潰的問題 https://github.com/oven-sh/bun/commit/16b1e84138056774684b5e769a20dabd787d069c
  • 修正 console.log 未列印空行的問題 https://github.com/oven-sh/bun/commit/b733125085a5746af121ce6d7b67eb45fb8e85e3
  • 修正 TS 程式碼有非預期的 ")" 時可能發生的崩潰 https://github.com/oven-sh/bun/commit/a8ab18bd50b3a98c65c6ce96bd75d87d7893df12
  • 支援所有雜湊函數和 node fs 函數中的所有 ArrayBufferView https://github.com/oven-sh/bun/commit/9d7bcac680c5f32d3fa89d9e47972957279a1a05
  • 修正 DotEnv Loader 忽略錯誤日誌級別 - https://github.com/oven-sh/bun/commit/906e97223a3dd95801bc0d12f62314719c554fd6
  • 修正遺失的 path/posix 和 path/win32 https://github.com/oven-sh/bun/commit/dbccfc2b26371c921f3b3a55b03e8bb4a103444f
  • 修正 `ReadableStream` 中取消在某些情況下無法運作的問題
  • 修正在 TextEncoder 中有時會發生的 rope 字串崩潰 https://github.com/oven-sh/bun/commit/6b7a0c1d3fde32b6e3ded85456d0721c34aa9219
  • bun:sqlite 修正 Database.deserialize 中的崩潰 https://github.com/oven-sh/bun/commit/9fd00727406b0170fa2d3bb43973ff8d78e7bb76
  • 當 tsconfig 指定 jsxFactory #1269 時 Bun 會發生 segfault
  • 無法將 EventEmitter 與 "require" 搭配使用,空物件而非類別 #1284
  • 嘗試呼叫載入的 .node 擴充功能時,"napi_wrap" 發生區段錯誤 #1286
  • 當將 assert 模組作為函數呼叫時,發生 "assert is not a function" 錯誤 #941

更多變更

  • Bun.which(bin):尋找命令的路徑

  • process 現在擴展了 EventEmitter

  • bun:test 輸出進行微調。現在包含 "expect calls"

    image
  • bun:test 將測試失敗列印在底部 - https://github.com/oven-sh/bun/commit/c57b32fa0cdeaf7f1490bd6af9c5248a92c71ea0

  • navigator.userAgentnavigator.hardwareConcurrency 現在是全域變數

  • require("tty").isatty 現在可運作

  • require("fs").rm 現在可運作

  • 實作 console.countconsole.countReset - https://github.com/oven-sh/bun/commit/4060afb7c70dd3ba037bd23c813c22032e2dabe5

    image

  • fetch() 的內部資料結構記憶體使用量減少 82% (9.8 KB -> 1.8 KB)

  • Bun.version 回報 Bun 的版本號碼

  • Bun.revision 回報 Bun 編譯時使用的 git commit SHA

所有 PR

  • 修正:將目的地新增至 Dockerfile 中的 ADD 命令,由 @DarthBenro008 於 https://github.com/oven-sh/bun/pull/1268
  • 測試:Promisify 基本測試,由 @albertpurnama 於 https://github.com/oven-sh/bun/pull/1018
  • 新增 bodyResponseRequest,由 @Jarred-Sumner 於 https://github.com/oven-sh/bun/pull/1255
  • 修正 console.log 處理循環參考的問題,由 @zhiyuang 於 https://github.com/oven-sh/bun/pull/1293
  • 文件(thread_pool):註解可讀性改進,由 @ryanrussell 於 https://github.com/oven-sh/bun/pull/1241
  • 修正巢狀模組 bin 可執行檔問題,由 @zhiyuang 於 https://github.com/oven-sh/bun/pull/1299
  • 修正在 npm 套件中 node_modules 已存在時的安裝錯誤,由 @zhiyuang 於 https://github.com/oven-sh/bun/pull/1301
  • 修正 fetch 回應重新導向,由 @zhiyuang 於 https://github.com/oven-sh/bun/pull/1303

新貢獻者

  • @DarthBenro008 在 https://github.com/oven-sh/bun/pull/1268 中做出了他們的首次貢獻
  • @albertpurnama 在 https://github.com/oven-sh/bun/pull/1018 中做出了他們的首次貢獻
  • @zhiyuang 在 https://github.com/oven-sh/bun/pull/1293 中做出了他們的首次貢獻

完整變更日誌