Bun

Bun v0.6.12


Jarred Sumner · 2023年6月30日

我們正在招募 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()
  • v0.6.9 - 更低的記憶體使用量以及支援非 ASCII 檔案名稱
  • v0.6.10 - fs.watch()bun install 錯誤修復、bun test 功能,以及改進的 CommonJS 支援
  • v0.6.11 - 解決 v0.6.10 的發布建置問題

此版本讓執行階段錯誤更容易閱讀,改善 Node.js 相容性,新增 await Bun.file(path).exists(),修復打包器錯誤,並稍微縮減了最小化器輸出大小。

安裝 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 的執行階段錯誤進行了一些改進

  • 修補了 JavaScriptCore,讓 Bun 可以用與 V8 相同的風格列印 Error.prototype.stack
  • 堆疊追蹤顯示較少的內部建構函式
  • console.error(error) 現在包含間接函式名稱,例如 let foo = function() {} 現在會顯示 foo 而不是 anonymous
  • Error.captureStackTrace(err)err.stack 屬性不再標記為唯讀(這是錯誤的)
  • Error.prototype.stack 現在會自動進行來源地圖 (sourcemapped)。

Bun 在執行階段轉譯每個檔案。在此版本之前,error.stack 會顯示轉譯後來源的堆疊,這不是很有用。現在,error.stack 會顯示原始來源的堆疊,並遵循為每個檔案產生的內部來源地圖。

console.log(error.stack) 之後的輸出

Error: hello!
    at hey (error.js:1:29)
    at module code (error.js:4:16)

console.log(error.stack) 之前的輸出

hey@error.js:1:29
module code@error.js:4:16
evaluate@[native code]
moduleEvaluation@[native code]
moduleEvaluation@[native code]
@[native code]
asyncFunctionResume@[native code]
promiseReactionJobWithoutPromise@[native code]
promiseReactionJob@[native code]

輸入

function hey() {
  return new Error("hello!").stack;
}
console.log(hey());

CommonJS <> ES 模組互通性的改進

當在執行階段使用 require 載入 ES 模組時,Bun 現在會插入 __esModule 註解,許多使用 Babel 轉譯的 npm 套件需要此註解才能正常運作。這修復了在 bun test 中使用 @mui/styled-engine 的錯誤。

package.json "module" 欄位不再用於 Bun 的執行階段

打包器在使用 ES 模組進行打包時,會優先使用 package.json 中的 "module" 欄位,而不是 "main" 欄位,但 Node.js 完全不使用 "module" 欄位。

先前,Bun 在執行階段使用 "module" 欄位(當 package.json "exports" 未使用時),類似於打包器的使用方式,但這導致某些套件在 Bun 中載入其程式碼的瀏覽器版本,而在 Node 中載入 Node.js 版本。

Bun 的打包器在為瀏覽器建置時繼續支援 "module" 欄位,但為了改善 Node.js 相容性,Bun 的執行階段不再使用 "module" 欄位。

SQLite3 全文檢索已啟用

Bun.file(path).exists()

Bun.file(path).exists() 是一個新的方法,它會傳回布林值,指出給定路徑上是否存在檔案。

import { file, write } from "bun";

console.log(await file("hello.txt").exists()); // false
await write("hello.txt", "hello world");
console.log(await file("hello.txt").exists()); // true

Node.js 相容性改進

node:http 和 node:stream 的多個錯誤修復已完成

Google Maps 可運作

@googlemaps/google-maps-services-js 套件現在可在 Bun 中運作,感謝 @dylan-conway 修復了我們 node:http 實作中的一個錯誤,該錯誤將不應標記為唯讀的屬性標記為唯讀。

import { Client } from "@googlemaps/google-maps-services-js";

const client = new Client({});

client
  .elevation({
    params: {
      locations: [{ lat: 45, lng: -110 }],
      key: "asdf",
    },
    timeout: 1000, // milliseconds
  })
  .then((r) => {
    console.log(r.data.results[0].elevation);
  })
  .catch((e) => {
    console.log(e.response.data.error_message);
  });

ytdl-core 現在可運作

ytdl-core 套件現在可在 Bun 中運作,感謝 @paperclover 修復了我們 node:httpnode:stream 實作中的幾個錯誤

import { createWriteStream } from "fs";
import ytdl from "ytdl-core";

ytdl("https://www.youtube.com/watch?v=dQw4w9WgXcQ").pipe(
  createWriteStream("secret-video-do-not-download.mp4"),
);

最小化器改進

Bun 的最小化器現在會將 obj["a"] 最小化為 obj.a,並將 obj["a"] = 1 最小化為 obj.a = 1

建置

bun build --minify ./input.js`

輸入

const obj = {};
obj["a"] = 1;

之後

const obj = {};
obj.a = 1;

之前

const obj = {};
obj["a"] = 1;

這為 vue 帶來了 0.02% 的套件大小縮減,並可能在執行階段稍微快一點(引擎實作計算屬性存取的方式與一般屬性存取不同)。

打包器錯誤修復

已修復一個錯誤,該錯誤會導致兩個連續檔案使用 CommonJS module.exports = require() 重新匯出另一個檔案時,產生無效的程式碼

// a.js
module.exports = require("./b");

// b.js
module.exports = require("./c");

// c.js
module.exports = {};
  • 在某些情況下,Bun 打包器中的 CommonJS -> ES 模組轉換會注入 exports.foo = undefined,這導致某些使用 Object 原型方法的套件拋出錯誤,並使程式碼膨脹。此問題已修復。

更多錯誤修復

  • 已修復一個破壞巨集的迴歸錯誤
  • dns/promises 中的 resolve6 匯出遺失
  • node:events 中的 errorMonitor 匯出遺失

變更記錄

請參閱 GitHub 上的變更記錄