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整理维护