首页 / Bun 入门教程 / 包管理器对比与技巧

Bun 入门教程

包管理器对比与技巧

本教程共 34 篇 · 第 15 篇 · 更新于 2026-08-06

Bun包管理器npmyarnpnpm对比CI 加速bun ci命令速查

本节目标:

  • 客观了解 Bun 包管理器与 npm / yarn / pnpm 的关系与差异,重点是命令对应与兼容点。
  • 掌握 bun ci 在 CI 中做可复现安装的方法。
  • 拿到一份常用命令速查表bunfig.toml 持久化配置示例。
  • 了解从其它包管理器迁移、以及 bun pm 系列实用工具。

15.1 先说兼容性

Bun 的包管理器是为兼容 npm 生态而生的:它读取标准 package.json、解析 npm registry、支持 dependencies / devDependencies / optionalDependencies / peerDependencies,并自动迁移 npm、yarn、pnpm 的锁文件(见第 12 章)。这意味着在大多数既有 Node.js 项目里,你可以用 bun install 直接替换 npm install,无需改动业务代码。

需要强调的是:Bun 并非要”取代”或”否定”其它工具,而是提供了一种更快、且默认更安全的安装体验。下面以客观视角对比几个常被关心的点。

关注点npmyarn (v1)pnpmBun
锁文件package-lock.jsonyarn.lockpnpm-lock.yamlbun.lock(文本 JSONC,v1.2 起默认)
依赖隔离平铺平铺严格隔离可选(isolated / hoisted)
生命周期脚本默认执行默认执行默认执行默认不执行(需 trustedDependencies
一键运行 CLInpxyarn dlxpnpm dlxbunx
安装速度基准较快快(官方称最高约 25x 于 npm)
Note

“安装速度”受项目规模、网络、缓存状态影响很大,上面的倍数来自 Bun 官方文档的基准,仅供量级参考。不同工具各有适用场景,按团队习惯选择即可。

15.2 CI 中的可复现安装:bun ci

在 CI / CD 里,你通常希望严格按锁文件安装、一旦 package.json 与锁文件不一致就直接失败,而不是悄悄更新锁文件。Bun 提供了 bun ci

bun ci

它等价于 bun install --frozen-lockfile。前提是你已经把 bun.lock 提交到了版本库。在 GitHub Actions 中的典型用法:

# .github/workflows/ci.yml
name: ci
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: oven-sh/setup-bun@v2     # 官方 action 安装 bun
      - run: bun ci                    # 严格按锁文件安装
      - run: bun run build
Warning

若 CI 里用 bun ci 却没提交 bun.lock,安装会因锁文件缺失而失败。请确保锁文件随代码一起入库。

15.3 常见命令速查

把日常最常用的一批命令对照列出,方便从其它工具迁移:

# 安装
bun install                       # 安装全部依赖(≈ npm install)
bun install <pkg>                 # 添加依赖(≈ npm install <pkg>)
bun add <pkg>                     # 同上,语义更明确
bun add -d <pkg>                  # 开发依赖(≈ npm install -D)
bun add -g <pkg>                  # 全局安装(≈ npm install -g)
bun remove <pkg>                  # 移除依赖(≈ npm uninstall)
bunx <pkg>                        # 运行一次性 CLI(≈ npx)

# 安装变体
bun install --production          # 仅 dependencies(≈ npm ci --production 思路)
bun install --frozen-lockfile     # 严格按锁文件(≈ npm ci)
bun install --lockfile-only        # 只更新锁文件,不装 node_modules
bun install --dry-run             # 演习,不真正安装

# 可复现 / 校验
bun ci                            # 等价 bun install --frozen-lockfile

15.4 用 bunfig.toml 持久化配置

不想每次都在命令行加一堆标志?把常用安装行为写进 bunfig.toml[install] 段,项目级与用户级(~/.bunfig.toml)会被合并:

[install]
optional = true                  # 是否安装 optionalDependencies
dev = true                       # 是否安装 devDependencies
peer = true                      # 是否安装 peerDependencies
production = false               # 等价 --production
saveTextLockfile = true          # 等价 --save-text-lockfile(v1.2+ 默认即文本锁)
frozenLockfile = false           # 等价 --frozen-lockfile
dryRun = false                   # 等价 --dry-run
concurrentScripts = 16           # 生命周期脚本最大并发数
linker = "hoisted"               # 或 "isolated"
ignoreScripts = false            # 等价 --ignore-scripts(全局禁用生命周期脚本)
minimumReleaseAge = 259200       # 最小发布年龄(秒)
Tip

环境变量优先级高于 bunfig.toml。几个常用环境变量:BUN_CONFIG_REGISTRY(指定 registry,默认 https://registry.npmjs.org)、BUN_CONFIG_TOKEN(鉴权 token)、BUN_CONFIG_YARN_LOCKFILE(额外写 yarn.lock)、BUN_CONFIG_SKIP_SAVE_LOCKFILE(不写锁文件)。

15.5 从其它包管理器迁移

  • npm:直接把 package-lock.json 留在原地,运行 bun install,它会自动迁移并生成 bun.lock;原文件保留,核对后可删。
  • yarnyarn.lock(v1)会被自动迁移;如需额外保留一份 yarn 风格锁文件,用 bun install --yarn
  • pnpm:检测到 pnpm-lock.yaml 且无 bun.lock 时自动迁移,还会把 pnpm-workspace.yaml 里的 workspaces、catalogs、overridespatchedDependencies 搬到 package.json;要求 pnpm 锁文件版本 ≥ 7。迁移后 pnpm-lock.yaml / pnpm-workspace.yaml 可手动删除。
Note

迁移只在 bun.lock 不存在时触发,且没有”退出”开关。如果你只是想试试 Bun 而不想改原锁文件,建议先在新分支或临时目录验证。

15.6 bun pm 实用工具集

bun pm 是一组包管理相关的实用命令,日常排查很顺手:

bun pm ls                 # 列出已安装依赖及其解析版本(别名 bun list)
bun pm ls --all           # 含所有深层依赖
bun pm ls --trusted       # 只列被允许运行生命周期脚本的包
bun pm cache              # 打印全局缓存路径
bun pm cache rm           # 清空全局缓存
bun pm whoami             # 打印当前 npm 用户名(需已登录)
bun pm hash               # 打印当前锁文件哈希
bun pm trust <names>      # 为未信任依赖放行并写入 trustedDependencies
bun pm untrusted          # 列出被拦截了脚本的依赖
bun pm pack               # 打包当前工作区为 .tgz(≈ npm pack)
bun pm bin                # 打印本地 bin 目录;加 -g 打印全局 bin 目录
bun pm pkg get name       # 读取 package.json 字段(支持点/括号记法)
bun pm pkg set version=2.0.0   # 修改 package.json 字段

bun pm trustbun pm untrusted 特别适合排查”明明装了某原生包却没构建成功”的问题——先 untrusted 看哪些脚本被拦,再决定要不要 trust

15.7 CI 与 Docker 中的实践

把 Bun 接进流水线时,有三件事值得一开始就做对,能省掉后面大量莫名其妙的排查时间。

第一,锁定 Bun 版本。 不同版本的 Bun 在写入或归一化锁文件时可能存在细微差异。本地用一个版本、CI 又下载了另一个版本,是”冻结安装莫名失败”最常见的成因。在 GitHub Actions 里显式指定版本,同时在 package.json 里声明 packageManager,让协作者和其它工具也能看到预期版本:

- uses: oven-sh/setup-bun@v2
  with:
    bun-version: 1.3.14
- run: bun --version
- run: bun ci
{
  "packageManager": "bun@1.3.14"
}

升级 Bun 时,把版本号变更和锁文件更新放进同一个 pull request,这样评审的人能一眼看出两者的因果关系。

第二,Docker 里先拷贝清单、再安装依赖。 只把 package.jsonbun.lock 拷进镜像,装完依赖之后再拷源码,这样日常的源码改动不会让昂贵的安装层缓存失效:

FROM oven/bun:1.3.14 AS base
WORKDIR /app
COPY package.json bun.lock ./
RUN bun install --frozen-lockfile
COPY . .
RUN bun run build

工作区项目要额外当心:只拷根 package.json不够的,Bun 还需要读取各子包的清单才能校验锁文件是否一致,必须把它们一并拷进去。同时检查 .dockerignore,过宽的忽略规则可能把 bun.lock 或嵌套的 package.json 挡在构建上下文之外——这种情况报错信息会指向锁文件,但真正的原因在忽略规则里。

第三,缓存全局安装缓存目录。~/.bun/install/cache 在多次运行之间持久化,并用 bun pm hash 的输出作为缓存 key(见第 12 章),才能真正吃到热安装的速度红利。只缓存 node_modules 而不缓存全局缓存,效果会打折扣。

15.8 常见误区与排查清单

切换工具时常遇到几个雷区,这里集中说明:

  • “为什么装完某原生包却没生成二进制?” 多半是生命周期脚本被默认拦截了。先 bun pm untrusted 看哪些脚本被拦,再对需要的包执行 bun pm trust <name> 或写进 trustedDependencies
  • “CI 里 bun ci 直接报错失败” 检查两点:bun.lock 是否随代码入库、package.json 是否与锁文件一致。不一致时要么更新锁文件提交,要么修正 package.json
  • “迁移后原来的锁文件还在” 这是预期行为——Bun 会保留 package-lock.json / yarn.lock / pnpm-lock.yaml 不动,核对无误后你可以手动删除,不必担心被覆盖。
  • “改了本地依赖但引用方看不到” 多见于工作区场景,删掉 node_modules 重新 bun install 通常能修复链接关系。
  • “锁文件明明没动,CI 却报 lockfile had changes” 大概率是本地与 CI 的 Bun 版本不一致,或者有人手改了 package.json 的版本号却没重跑安装。正确的修法是在本地执行 bun install、检查 git diff -- package.json bun.lock 确认改动合理后提交新锁文件,而不是--frozen-lockfile 从 CI 里拿掉——那等于放任线上部署去挑选从未被评审、也从未被测试过的依赖版本。
  • “我没加 --frozen-lockfile,CI 为什么还是冻结了?” 这是预期行为。Bun 检测到 CI=true 时会自动启用冻结安装(见第 11 章)。确实需要在流水线里更新锁文件时,显式加 --no-frozen-lockfile
Tip

把 Bun 当”更快的 npm 替换”来用,是最平滑的起步方式:先只替换 bun install / bun add / bun remove,确认团队无碍后,再逐步引入 bun runbun testbunx 等能力,避免一次性大改带来的风险。

15.9 小结

  • Bun 的包管理器与 npm 生态高度兼容,可直接用于既有项目;它与 npm/yarn/pnpm 在锁文件、隔离策略、生命周期脚本默认值上各有差异,应客观选择。
  • CI 中用 bun ci(= bun install --frozen-lockfile)做严格可复现安装,记得提交 bun.lock
  • 常用安装/增删/运行命令与 npm 直接对应;把习惯配置写进 bunfig.toml 比每次敲 flag 更稳。
  • 从 npm/yarn/pnpm 迁移基本是”跑一次 bun install”;bun pm 系列工具便于日常排查与包管理操作。

至此,Bun 作为包管理器的一面已经讲完。从第 16 章起,我们会进入 Bun 作为**打包器(Bundler)**的能力,看看它如何把源码与资源打包成可部署的产物。