Bun 提供了一种名为**隔离安装**的替代包安装策略,它创建了类似于 pnpm 方法的严格依赖隔离。这种模式可以防止幽灵依赖,并确保可复现的确定性构建。
什么是隔离安装?
隔离安装创建了一种非提升的依赖结构,其中包只能访问其显式声明的依赖。这与 npm 和 Yarn 使用的传统“提升”安装策略不同,后者将依赖平铺到共享的 `node_modules` 目录中。
主要优点
- 防止幽灵依赖 — 包不会意外导入未声明的依赖
- 确定性解析 — 无论安装了什么,依赖树都是相同的
- 更适合 monorepo — 工作区隔离防止包之间的交叉污染
- 可复现构建 — 在不同环境中提供更可预测的解析行为
使用隔离安装
命令行
使用 `--linker` 标志指定安装策略
# Use isolated installs
bun install --linker isolated
# Use traditional hoisted installs
bun install --linker hoisted
配置文件
在 `bunfig.toml` 中设置默认的链接器策略
[install]
linker = "isolated"
默认行为
- 工作区:Bun 默认使用**隔离**安装,以防止与提升相关的错误
- 单一项目:Bun 默认使用**提升**安装
要覆盖默认值,请使用 `--linker hoisted` 或 `--linker isolated`,或在配置文件中设置。
隔离安装的工作原理
目录结构
隔离安装不是提升依赖,而是创建两层结构
node_modules/
├── .bun/ # Central package store
│ ├── package@1.0.0/ # Versioned package installations
│ │ └── node_modules/
│ │ └── package/ # Actual package files
│ ├── @scope+package@2.1.0/ # Scoped packages (+ replaces /)
│ │ └── node_modules/
│ │ └── @scope/
│ │ └── package/
│ └── ...
└── package-name -> .bun/package@1.0.0/node_modules/package # Symlinks
解析算法
- 中央存储 — 所有包都安装在 `node_modules/.bun/package@version/` 目录中
- 符号链接 — 顶层 `node_modules` 包含指向中央存储的符号链接
- 对等解析 — 复杂的对等依赖创建专门的目录名
- 去重 — 具有相同包 ID 和对等依赖集的包是共享的
工作区处理
在 monorepo 中,工作区依赖会得到特殊处理
- 工作区包 — 直接符号链接到其源目录,而不是存储
- 工作区依赖 — 可以访问 monorepo 中的其他工作区包
- 外部依赖 — 在隔离存储中安装并正确隔离
与提升安装的比较
方面 | 提升 (npm/Yarn) | 隔离 (pnpm-like) |
---|---|---|
依赖访问 | 包可以访问任何提升的依赖 | 包只能看到声明的依赖 |
幽灵依赖 | ❌ 可能 | ✅ 阻止 |
磁盘使用 | ✅ 更低 (共享安装) | ✅ 类似 (使用符号链接) |
确定性 | ❌ 确定性较低 | ✅ 确定性更高 |
Node.js 兼容性 | ✅ 标准行为 | ✅ 通过符号链接兼容 |
最适合 | 单一项目,遗留代码 | Monorepo,严格的依赖管理 |
高级功能
对等依赖处理
隔离安装通过复杂的解析处理对等依赖
# Package with peer dependencies creates specialized paths
node_modules/.bun/package@1.0.0_react@18.2.0/
目录名同时编码包版本及其对等依赖版本,确保每个唯一的组合都有自己的安装。
后端策略
Bun 使用不同的文件操作策略以提高性能
- Clonefile (macOS) — 写时复制文件系统克隆,以实现最大效率
- Hardlink (Linux/Windows) — 硬链接以节省磁盘空间
- Copyfile (回退) — 当其他方法不可用时进行完整文件复制
调试隔离安装
启用详细日志记录以了解安装过程
bun install --linker isolated --verbose
这显示了
- 存储条目创建
- 符号链接操作
- 对等依赖解析
- 去重决策
故障排除
兼容性问题
某些包可能无法与隔离安装正确配合使用,原因如下:
- 硬编码路径 — 假设扁平 `node_modules` 结构的包
- 动态导入 — 不遵循 Node.js 解析的运行时导入
- 构建工具 — 直接扫描 `node_modules` 的工具
如果您遇到问题,可以
为特定项目**切换到提升模式**
bun install --linker hoisted
**报告兼容性问题**以帮助改进隔离安装支持
性能考量
- 安装时间 — 由于符号链接操作,可能会稍慢
- 磁盘使用 — 与提升安装类似 (使用符号链接,而不是文件复制)
- 内存使用 — 由于复杂的对等解析,安装期间内存使用量更高
迁移指南
从 npm/Yarn 迁移
# Remove existing node_modules and lockfiles
rm -rf node_modules package-lock.json yarn.lock
# Install with isolated linker
bun install --linker isolated
从 pnpm 迁移
隔离安装在概念上与 pnpm 类似,因此迁移应该很简单
# Remove pnpm files
rm -rf node_modules pnpm-lock.yaml
# Install with Bun's isolated linker
bun install --linker isolated
主要区别在于 Bun 在 `node_modules` 中使用符号链接,而 pnpm 使用带有符号链接的全局存储。
何时使用隔离安装
隔离安装是工作区的默认设置。 您可能希望在以下情况下为单一项目明确启用它们:
- 需要严格的依赖管理
- 防止幽灵依赖很重要
- 构建需要确定性依赖的库
在以下情况下切换到提升安装 (包括工作区):
- 使用假设扁平 `node_modules` 的遗留代码
- 需要与现有构建工具兼容
- 在符号链接支持不佳的环境中工作
- 您更喜欢更简单的传统 npm 行为
相关文档
- 包管理器 > 工作区 — Monorepo 工作区管理
- 包管理器 > 锁定文件 — 了解 Bun 的锁定文件格式
- CLI > install — 完整的 `bun install` 命令参考