Skip to content

import Install from "/snippets/cli/install.mdx";

基本用法

bash
bun install react
bun install react@19.1.1 # 特定版本
bun install react@latest # 特定標簽

bun CLI 包含一個與 Node.js 兼容的包管理器,旨在成為 npmyarnpnpm 的更快替代品。它是一個獨立工具,可以在現有 Node.js 項目中工作;如果你的項目有 package.jsonbun install 可以幫助你加快工作流。

NOTE

⚡️ 快 25 倍 — 在任何 Node.js 項目中從 npm install 切換到 bun install,使你的安裝速度提高 25 倍。

Bun 安裝速度比較

對於 Linux 用戶

推薦的最低 Linux 內核版本是 5.6。如果你使用的是 Linux 內核 5.1 - 5.5,bun install 可以工作,但由於缺乏對 io_uring 的 connect() 操作的支持,HTTP 請求會很慢。

如果你使用的是 Ubuntu 20.04,以下是安裝 更新內核 的方法:

bash
# 如果返回的版本 >= 5.6,則無需執行任何操作
uname -r

# 安裝官方 Ubuntu 硬件啟用內核
sudo apt install --install-recommends linux-generic-hwe-20.04

要安裝項目的所有依賴:

bash
bun install

運行 bun install 將:

  • 安裝 所有 dependenciesdevDependenciesoptionalDependencies。Bun 默認將安裝 peerDependencies
  • 運行 你的項目的 {pre|post}install{pre|post}prepare 腳本。出於安全原因,Bun 不執行 已安裝依賴的生命周期腳本。
  • 寫入 bun.lock 鎖文件到項目根目錄。

日志

要修改日志詳細程度:

bash
bun install --verbose # 調試日志
bun install --silent  # 無日志

生命周期腳本

與其他 npm 客戶端不同,Bun 不為已安裝依賴執行任意的生命周期腳本(如 postinstall)。執行任意腳本代表潛在的安全風險。

要告訴 Bun 允許特定包的生命周期腳本,請將包添加到 package.json 中的 trustedDependencies

json
{
  "name": "my-app",
  "version": "1.0.0",
  "trustedDependencies": ["my-trusted-package"] 
}

然後重新安裝包。Bun 將讀取此字段並為 my-trusted-package 運行生命周期腳本。

生命周期腳本將在安裝期間並行運行。要調整最大並發腳本數,請使用 --concurrent-scripts 標志。默認值是報告 cpu 數量或 GOMAXPROCS 的兩倍。

bash
bun install --concurrent-scripts 5

Bun 自動優化流行包(如 esbuildsharp 等)的 postinstall 腳本,通過確定需要運行哪些腳本。要禁用這些優化:

bash
BUN_FEATURE_FLAG_DISABLE_NATIVE_DEPENDENCY_LINKER=1 bun install
BUN_FEATURE_FLAG_DISABLE_IGNORE_SCRIPTS=1 bun install

工作區

Bun 支持 package.json 中的 "workspaces"。完整文檔請參閱 包管理器 > 工作區

json
{
  "name": "my-app",
  "version": "1.0.0",
  "workspaces": ["packages/*"], 
  "dependencies": {
    "preact": "^10.5.13"
  }
}

為特定包安裝依賴

在 monorepo 中,你可以使用 --filter 標志為包的子集安裝依賴。

bash
# 為除 `pkg-c` 外的所有工作區安裝依賴
bun install --filter '!pkg-c'

# 僅為 `./packages/pkg-a` 中的 `pkg-a` 安裝依賴
bun install --filter './packages/pkg-a'

有關使用 bun install 過濾的更多信息,請參閱 包管理器 > 過濾


覆蓋和解析

Bun 在 package.json 中支持 npm 的 "overrides" 和 Yarn 的 "resolutions"。這些是指定_元依賴_(你依賴的依賴)版本范圍的機制。完整文檔請參閱 包管理器 > 覆蓋和解析

json
{
  "name": "my-app",
  "dependencies": {
    "foo": "^2.0.0"
  },
  "overrides": { 
    "bar": "~4.4.0"
  } 
}

全局包

要全局安裝包,請使用 -g/--global 標志。通常這用於安裝命令行工具。

bash
bun install --global cowsay # 或 `bun install -g cowsay`
cowsay "Bun!"
txt
 ______
< Bun! >
 ------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

生產模式

要在生產模式下安裝(即不帶 devDependenciesoptionalDependencies):

bash
bun install --production

對於可重現的安裝,請使用 --frozen-lockfile。這將安裝鎖文件中指定的每個包的確切版本。如果你的 package.jsonbun.lock 不一致,Bun 將報錯退出。鎖文件將不會更新。

bash
bun install --frozen-lockfile

有關 Bun 的鎖文件 bun.lock 的更多信息,請參閱 包管理器 > 鎖文件


省略依賴

要省略 dev、peer 或 optional 依賴,請使用 --omit 標志。

bash
# 從安裝中排除 "devDependencies"。這將應用於根包和工作區(如果存在)。
# 傳遞依賴將不會有 "devDependencies"。
bun install --omit dev

# 僅安裝 "dependencies" 中的依賴
bun install --omit=dev --omit=peer --omit=optional

預演

要執行預演(即不實際安裝任何內容):

bash
bun install --dry-run

非 npm 依賴

Bun 支持從 Git、GitHub 和本地或遠程托管的 tarballs 安裝依賴。完整文檔請參閱 包管理器 > Git、GitHub 和 tarball 依賴

json
{
  "dependencies": {
    "dayjs": "git+https://github.com/iamkun/dayjs.git",
    "lodash": "git+ssh://github.com/lodash/lodash.git#4.17.21",
    "moment": "git@github.com:moment/moment.git",
    "zod": "github:colinhacks/zod",
    "react": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
    "bun-types": "npm:@types/bun"
  }
}

安裝策略

Bun 支持兩種包安裝策略,用於確定依賴如何在 node_modules 中組織:

提升安裝

傳統的 npm/Yarn 方法,將依賴扁平化到共享的 node_modules 目錄中:

bash
bun install --linker hoisted

隔離安裝

類似 pnpm 的方法,創建嚴格的依賴隔離以防止幻象依賴:

bash
bun install --linker isolated

隔離安裝在 node_modules/.bun/ 中創建中央包存儲,並在頂層 node_modules 中使用符號鏈接。這確保包只能訪問其聲明的依賴。

默認策略

默認鏈接器策略取決於你是從頭開始還是有現有項目:

  • 新工作區/monorepoisolated(防止幻象依賴)
  • 新單包項目hoisted(傳統 npm 行為)
  • 現有項目(v1.3.2 之前創建)hoisted(保持向後兼容)

默認值由鎖文件中的 configVersion 字段控制。有關詳細解釋,請參閱 包管理器 > 隔離安裝


最小發布年齡

為了防止惡意包快速發布的供應鏈攻擊,你可以配置 npm 包的最小年齡要求。比指定閾值(以秒為單位)最近發布的包版本將在安裝期間被過濾掉。

bash
# 僅安裝至少 3 天前發布的包版本
bun add @types/bun --minimum-release-age 259200 # 秒

你也可以在 bunfig.toml 中配置:

toml
[install]
# 僅安裝至少 3 天前發布的包版本
minimumReleaseAge = 259200 # 秒

# 從年齡檢查中排除受信任的包
minimumReleaseAgeExcludes = ["@types/node", "typescript"]

當最小年齡過濾器激活時:

  • 僅影響新包解析 - bun.lock 中的現有包保持不變
  • 所有依賴(直接和傳遞)在解析時都會被過濾以滿足年齡要求
  • 當版本被年齡網關阻止時,穩定性檢查會檢測快速 bugfix 模式
    • 如果多個版本在年齡網關之外接近發布,它會擴展過濾器以跳過這些可能不穩定的版本,並選擇更舊、更成熟的版本
    • 在年齡網關後最多搜索 7 天,但如果仍然發現快速發布,則忽略穩定性檢查
    • 精確版本請求(如 package@1.1.1)仍然遵循年齡網關,但繞過穩定性檢查
  • 沒有 time 字段的版本被視為通過年齡檢查(npm 注冊表應始終提供時間戳)

有關更高級的安全掃描,包括與服務集成和自定義過濾,請參閱 包管理器 > 安全掃描器 API


配置

使用 bunfig.toml 配置 bun install

bun installbun removebun add 時,將在以下路徑中搜索 bunfig.toml

  1. $XDG_CONFIG_HOME/.bunfig.toml$HOME/.bunfig.toml
  2. ./bunfig.toml

如果兩者都找到,結果將合並在一起。

使用 bunfig.toml 配置是可選的。Bun 通常嘗試零配置,但這並不總是可能的。bun install 的默認行為可以在 bunfig.toml 中配置。默認值如下所示。

toml
[install]

# 是否安裝 optionalDependencies
optional = true

# 是否安裝 devDependencies
dev = true

# 是否安裝 peerDependencies
peer = true

# 等同於 `--production` 標志
production = false

# 等同於 `--save-text-lockfile` 標志
saveTextLockfile = false

# 等同於 `--frozen-lockfile` 標志
frozenLockfile = false

# 等同於 `--dry-run` 標志
dryRun = false

# 等同於 `--concurrent-scripts` 標志
concurrentScripts = 16 # (cpu 數量或 GOMAXPROCS) x2

# 安裝策略:"hoisted" 或 "isolated"
# 默認值取決於鎖文件 configVersion 和工作區:
# - configVersion = 1: 如果使用工作區則為 "isolated",否則為 "hoisted"
# - configVersion = 0: "hoisted"
linker = "hoisted"


# 最小年齡配置
minimumReleaseAge = 259200 # 秒
minimumReleaseAgeExcludes = ["@types/node", "typescript"]

使用環境變量配置

環境變量的優先級高於 bunfig.toml

名稱描述
BUN_CONFIG_REGISTRY設置 npm 注冊表(默認:https://registry.npmjs.org
BUN_CONFIG_TOKEN設置認證令牌(目前無作用)
BUN_CONFIG_YARN_LOCKFILE保存 Yarn v1 風格的 yarn.lock
BUN_CONFIG_LINK_NATIVE_BINS將 package.json 中的 bin 指向特定平台的依賴
BUN_CONFIG_SKIP_SAVE_LOCKFILE不保存鎖文件
BUN_CONFIG_SKIP_LOAD_LOCKFILE不加載鎖文件
BUN_CONFIG_SKIP_INSTALL_PACKAGES不安裝任何包

Bun 始終嘗試使用目標平台可用的最快安裝方法。在 macOS 上,那是 clonefile,在 Linux 上,那是 hardlink。你可以使用 --backend 標志更改使用的安裝方法。當不可用或出錯時,clonefilehardlink 會回退到特定平台的文件復制實現。

Bun 將來自 npm 的已安裝包存儲在 ~/.bun/install/cache/${name}@${version}。請注意,如果 semver 版本有 buildpre 標簽,它會被替換為該值的哈希值。這是為了減少長文件路徑錯誤的機會,但不幸的是使確定包在磁盤上的安裝位置變得復雜。

node_modules 文件夾存在時,在安裝之前,Bun 會檢查預期 node_modules 文件夾中的 package/package.json 中的 "name""version" 是否匹配預期的 nameversion。這就是它確定是否應該安裝的方式。它使用自定義 JSON 解析器,一旦找到 "name""version" 就會停止解析。

bun.lock 不存在或 package.json 已更改依賴時,tarballs 會在解析期間急切地下載和提取。

bun.lock 存在且 package.json 未更改時,Bun 會延遲下載缺失的依賴。如果具有匹配 nameversion 的包已經存在於 node_modules 中的預期位置,Bun 不會嘗試下載 tarball。

CI/CD

使用官方的 oven-sh/setup-bun 操作在 GitHub Actions 管道中安裝 bun

yaml
name: bun-types
jobs:
  build:
    name: build-app
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        uses: actions/checkout@v4
      - name: Install bun
        uses: oven-sh/setup-bun@v2
      - name: Install dependencies
        run: bun install
      - name: Build app
        run: bun run build

對於想要強制可重現構建的 CI/CD 環境,使用 bun ci 在 package.json 與鎖文件不同步時使構建失敗:

bash
bun ci

這等同於 bun install --frozen-lockfile。它從 bun.lock 安裝確切版本,如果 package.json 與鎖文件不匹配則失敗。要使用 bun cibun install --frozen-lockfile,你必須將 bun.lock 提交到版本控制。

不要運行 bun install,而是運行 bun ci

yaml
name: bun-types
jobs:
  build:
    name: build-app
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        uses: actions/checkout@v4
      - name: Install bun
        uses: oven-sh/setup-bun@v2
      - name: Install dependencies
        run: bun ci
      - name: Build app
        run: bun run build

特定平台的依賴?

bun 在鎖文件中存儲來自 npm 的標准化 cpuos 值,以及解析的包。它在運行時跳過下載、提取和安裝為當前目標禁用的包。這意味著即使最終安裝的包確實發生變化,鎖文件也不會在平台/架構之間變化。

--cpu--os 標志

你可以覆蓋包選擇的目標平台:

bash
bun install --cpu=x64 --os=linux

這將為指定平台安裝包,而不是當前系統。對於跨平台構建或為不同環境准備部署時很有用。

--cpu 的接受值arm64x64ia32ppc64s390x

--os 的接受值linuxdarwinwin32freebsdopenbsdsunosaix

Peer 依賴?

Peer 依賴的處理方式與 yarn 類似。bun install 將自動安裝 peer 依賴。如果依賴在 peerDependenciesMeta 中標記為 optional,將盡可能選擇現有依賴。

鎖文件

bun.lock 是 Bun 的鎖文件格式。請參閱 我們關於文本鎖文件的博客文章

在 Bun 1.2 之前,鎖文件是二進制的,稱為 bun.lockb。舊鎖文件可以通過運行 bun install --save-text-lockfile --frozen-lockfile --lockfile-only 升級到新格式,然後刪除 bun.lockb

緩存

要刪除緩存:

bash
bun pm cache rm
# 或
rm -rf ~/.bun/install/cache

特定平台的後端

bun install 根據平台使用不同的系統調用來安裝依賴。這是一種性能優化。你可以使用 --backend 標志強制使用特定後端。

hardlink 是 Linux 上的默認後端。基准測試表明它是 Linux 上最快的。

bash
rm -rf node_modules
bun install --backend hardlink

clonefile 是 macOS 上的默認後端。基准測試表明它是 macOS 上最快的。它僅適用於 macOS。

bash
rm -rf node_modules
bun install --backend clonefile

clonefile_each_dir 類似於 clonefile,只是它逐個目錄克隆每個文件。它僅適用於 macOS,並且往往比 clonefile 慢。與 clonefile 不同,這不會在一個系統調用中遞歸克隆子目錄。

bash
rm -rf node_modules
bun install --backend clonefile_each_dir

copyfile 是當上述任何一項失敗時使用的回退方案,也是最慢的。在 macOS 上,它使用 fcopyfile(),在 Linux 上它使用 copy_file_range()

bash
rm -rf node_modules
bun install --backend copyfile

symlink 通常僅用於 file: 依賴(最終也會用於 link:)。為防止無限循環,它會跳過符號鏈接 node_modules 文件夾。

如果你使用 --backend=symlink 安裝,Node.js 將無法解析依賴的 node_modules,除非每個依賴都有自己的 node_modules 文件夾,或者你向 nodebun 傳遞 --preserve-symlinks。請參閱 Node.js 關於 --preserve-symlinks 的文檔

bash
rm -rf node_modules
bun install --backend symlink
bun --preserve-symlinks ./my-file.js
node --preserve-symlinks ./my-file.js # https://nodejs.org/api/cli.html#--preserve-symlinks

npm 注冊表元數據

Bun 使用二進制格式緩存 NPM 注冊表響應。這比 JSON 加載更快,並且在磁盤上往往更小。 你將在 ~/.bun/install/cache/*.npm 中看到這些文件。文件名模式是 ${hash(packageName)}.npm。這是一個哈希值,因此不需要為作用域包創建額外的目錄。

Bun 對 Cache-Control 的使用忽略了 Age。這提高了性能,但意味著 bun 可能有大約 5 分鐘的延遲才能從 npm 接收最新的包版本元數據。

pnpm 遷移

Bun 會自動從 pnpm 遷移項目到 bun。當檢測到 pnpm-lock.yaml 文件且不存在 bun.lock 文件時,Bun 將在安裝期間自動將鎖文件遷移到 bun.lock。原始 pnpm-lock.yaml 文件保持不變。

bash
bun install

注意:遷移僅在 bun.lock 不存在時運行。目前沒有選擇退出 pnpm 遷移的標志。

遷移過程處理:

鎖文件遷移

  • pnpm-lock.yaml 轉換為 bun.lock 格式
  • 保留包版本和解析信息
  • 維護依賴關系和 peer 依賴
  • 處理帶有完整性哈希的補丁依賴

工作區配置

pnpm-workspace.yaml 文件存在時,Bun 將工作區設置遷移到你的根 package.json

yaml
packages:
  - "apps/*"
  - "packages/*"

catalog:
  react: ^18.0.0
  typescript: ^5.0.0

catalogs:
  build:
    webpack: ^5.0.0
    babel: ^7.0.0

工作區包列表和目錄被移動到 package.json 中的 workspaces 字段:

json
{
  "workspaces": {
    "packages": ["apps/*", "packages/*"],
    "catalog": {
      "react": "^18.0.0",
      "typescript": "^5.0.0"
    },
    "catalogs": {
      "build": {
        "webpack": "^5.0.0",
        "babel": "^7.0.0"
      }
    }
  }
}

目錄依賴

使用 pnpm 的 catalog: 協議的依賴被保留:

json
{
  "dependencies": {
    "react": "catalog:",
    "webpack": "catalog:build"
  }
}

配置遷移

以下 pnpm 配置從 pnpm-lock.yamlpnpm-workspace.yaml 遷移:

  • 覆蓋:從 pnpm.overrides 移動到 package.json 中的根級別 overrides
  • 補丁依賴:從 pnpm.patchedDependencies 移動到 package.json 中的根級別 patchedDependencies
  • 工作區覆蓋:從 pnpm-workspace.yaml 應用到根 package.json

要求

  • 需要 pnpm 鎖文件版本 7 或更高
  • 工作區包在其 package.json 中必須有 name 字段
  • 目錄定義中必須存在目錄引用的所有依賴

遷移後,你可以安全地刪除 pnpm-lock.yamlpnpm-workspace.yaml 文件。

Bun學習網由www.bunjs.com.cn整理維護