bun.js 一個新的JavaScript運行環境

介紹

Bun 是一個現代的JavaScript運行環境,如Node, Deno。主要特性如下:

  1. 啓動速度快。
  2. 更高的性能。
  3. 完整的工具(打包器、轉碼器、包管理)。

下面我們來橫向對比下框架所說的性能:

相同電腦下, 不同 js 運行環境的每秒操作數

更多具體的優點

  • 內置 fetchWebSocketReadableStream 等API

  • 可以在bun.js中使用npm包。支持ESM和CommonJS,但Bun內部使用ESM。

  • 在bun.js中,每個文件都是轉譯的。TypeScript & JSX就可以使用。

  • bun支持 "paths"、"jsxImportSource" 和更多來自tsconfig.json文件的內容。

  • 使用 Bun.write 提供的最快的系統調用來寫入、複製、管道、發送文件。

  • bun.js會自動從.env文件中加載環境變量。不再需要 require("dotenv").config()

  • bun內置了一個快速的 SQLite3 客戶端 bun:sqlite

  • bun.js實現了大部分的Node-API(N-API)。許多Node.js的本地模塊都能正常工作。

加載器

目前,bun實現了以下加載器:

Input Loader Output
.js JSX + JavaScript .js
.jsx JSX + JavaScript .js
.ts TypeScript + JavaScript .js
.tsx TypeScript + JSX + JavaScript .js
.mjs JavaScript .js
.cjs JavaScript .js
.mts TypeScript .js
.cts TypeScript .js
.toml TOML .js
.css CSS .css
.env Env N/A
.* file string

實現

Bun.js 使用的是 JavaScriptCore 引擎,
它的執行速度往往要比 V8 等更傳統引擎要快。

而他本身, 是由叫做 Zig 的語言編寫而成的, Zig 是一門新的系統級編程語言,相當於加強版 C 語言

配置

bunfig.toml 是 bun 的配置文件。

這裏給出一個例子:

# 默認框架
# 默認情況下,bun會尋找一個類似於`bun-framework-${framework}的npm包,然後是`${framework}`。
framework = "next"
logLevel = "debug"

# publicDir = "public"
# external = ["jquery"]

[macros]
# 像這樣重新映射的配置:
#     import {graphql} from 'react-relay';
# To:
#     import {graphql} from 'macro:bun-macro-relay';
react-relay = { "graphql" = "bun-macro-relay" }

[bundle]
saveTo = "node_modules.bun"
# Don't need this if `framework` is set, but showing it here as an example anyway
entryPoints = ["./app/index.ts"]

[bundle.packages]
# 如果設置了`framework',就不需要這個了,在這裏作爲一個例子展示一下。
"@bigapp/design-system" = true

[dev]
# dev 的啓動端口 3000-5000
port = 5000

[define]
# 環境變量
"process.env.bagel" = "'lox'"

[loaders]
# 如果文件後綴是 .bagel 則使用 JS 的解析器
".bagel" = "js"

[debug]
# 當導航到blob:或src:鏈接時,在你的編輯器中打開該文件
# 如果沒有,它會嘗試用$EDITOR或$VISUAL
# 如果仍然失敗,它會嘗試Visual Studio Code,然後是Sublime Text,然後是其他一些編輯器
# 這是由Bun.openInEditor()使用的
editor = "code"

# List of editors:
# - "subl", "sublime"
# - "vscode", "code"
# - "textmate", "mate"
# - "idea"
# - "webstorm"
# - "nvim", "neovim"
# - "vim","vi"
# - "emacs"
# - "atom"

使用

首先我們下載 cli

在終端執行如下指令即可進行下載:

curl https://bun.sh/install | bash

啓用服務

先嚐試實現類似於 node 的相關功能:

新建文件 http.js

export default {
  port: 3000,
  fetch(request) {
    return new Response("Welcome to Bun!");
  },
};

之後在終端執行:

bun run http.js

之後打開瀏覽器地址 http://localhost:3000/ 即可查看到對應頁面的返回 Welcome to Bun!

如果運行中有錯誤處理, 可以這樣判斷:

export default {
  fetch(req) {
    // if(...)
    throw new Error("woops!");
  },
  error(error: Error) {
    // 類似與 catch 到fetch 拋出的錯誤
    return new Response("Uh oh!!\n" + error.toString(), { status: 500 });
  },
}

創建項目

我們先嚐試使用它默認的 react 模板項目來創建:

bun create react ./app

運行指令之後的終端部分輸出:

之後便出現如下目錄:

在項目中, 通過指令 bun dev 即可運行

這就是他的官方 react 項目模板, 當然他還可以擴展:

bun create github-user/repo-name destination
bun create local-example-or-remote-example destination
bun create /absolute/path/to-template-folder destination
bun create https://github.com/github-user/repo-name destination
bun create github.com/github-user/repo-name destination

通過初始化本地路徑, github 地址, gitlab 地址來初始化項目

bun create 工作流程

當我們運行 bun create ${template} ${destination} 的時候會出現以下判斷

  1. 判斷遠程模板
    1. 請求 registry.npmjs.org 相關路徑, 下載tgz
    2. 解壓縮, 提取文件
  2. 如果是 GitHub
    1. 通過 GitHub API 下載
    2. 解析並提取文件
  3. 如果是本地模板
    1. 打開本地文件夾
    2. 清空已有名稱的文件
    3. 遞歸複製文件
    4. 解析 package, 執行 hook, 下載依賴, 初始化 git

包管理

bun 有他自己的包公里工具: bun install, 可以在 bunfig.toml配置文件中對其進行 registry, dev, cache 等配置

bun install 對等依賴的處理方式與 yarn 類似。不會自動安裝對等依賴,會嘗試選擇一個現有的依賴。

lock 文件

bun.lockbbun 的二進制 lock 文件格式, 至於爲什麼選擇二進制, 直接的原因就是爲了性能, 和更多的存儲

快速的原因

它對所有數據使用線性數組。包是由一個自動遞增的整數 ID 或者包名的哈希值引用的。超過8個字符的字符串會被去掉。
在保存在磁盤之前,lock 文件通過 garbage collection (GC)和遍歷包的樹形結構確定順序 ,再按依賴關係下載包。

腳本運行器

bun run是一個快速的 package.json 腳本運行器

bun run ${script-name} 運行相當於 npm run script-name 的內容。例如,bun run dev 運行 package.json 中的 dev 腳本。

bun 運行會自動從 .env 中加載環境變量到 shell/task 中。.env 文件的加載優先級與 bun 的其他部分相同:

  1. .env.local 最先加載
  2. if ($NODE_ENV === "production") .env.production else .env.development
  3. .env

如果有什麼問題,你可以運行 bun run env 來得到一個環境變量的列表。

問題

目前存在的問題

Zig 的問題

Zig 是一個較新(2016 年)的語言, 他的生態,安全性值得考慮

同時如果底層出現什麼問題, 會這門語言的人是非常少的, 就很容易卡主, 過於被動

Issue 的問題

目前存在了 284 個 Issue(2022.07.27), 有一些是特別重要且影響性能的

生態問題

很多常用的, 較爲重要的功能還未支持, 例如:

  • treeShaking
  • Source maps
  • Code splitting
  • CSS 壓縮

具體可查看 此處

總結

目前來說 bun 已經擁有的功能還不能滿足正常的生產需求, 我們只能在開發一些小工具的時候使用它來嚐嚐鮮

他的結構, 專門的下載器, TypeScript & JSX 的開箱即用, 內置的node API 等等目前看來是挺香的, 然後也同樣地存在我上面說的一些問題

bun 的餅是很大很圓, 但是未來能不能真正喫上, 就一起等着看吧

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章