运行时包管理器打包器测试运行器代码检查格式化指南参考博客反馈

全局缓存

Bun 如何在全局缓存中存储和管理包

Bun 会将从注册表下载的每个软件包存储在全局缓存中,缓存路径为 ~/.bun/install/cache,或由 BUN_INSTALL_CACHE_DIR 环境变量设置的路径。软件包存储在名称类似 ${name}@${version} 的子目录中,因此 Bun 可以缓存同一软件包的多个版本。

配置缓存行为
bunfig.toml
[install.cache]
# 缓存使用的目录
dir = "~/.bun/install/cache"

# 为 true 时,不从全局缓存加载。
# 但 Bun 可能仍然会写入 node_modules/.cache
disable = false

# 为 true 时,总是从注册表解析最新版本
disableManifest = false

减少重复下载

安装软件包时,如果缓存中已有 package.json 指定范围内的某个版本,Bun 会使用缓存中的副本,而不是再次下载。

安装详情

如果 semver 版本带有预发布后缀(1.0.0-beta.0)或构建后缀(1.0.0+20220101),Bun 会将后缀替换为该值的哈希,以降低长文件路径导致错误的可能性。

当 node_modules 文件夹存在时,Bun 会在安装前检查 node_modules 是否包含所有预期的软件包及其对应版本。如果是,则 bun install 完成。Bun 使用自定义 JSON 解析器,在找到 "name" 和 "version" 后立即停止解析。

如果缺少软件包,或其版本与 package.json 不兼容,Bun 会在缓存中查找兼容的模块。如果缓存中有,则 Bun 会将其安装到 node_modules。否则,Bun 会从注册表下载软件包,然后进行安装。


快速复制

软件包下载到缓存后,Bun 仍需将这些文件复制到 node_modules。为此,它会使用最快的系统调用:在 Linux 和 Windows 上使用硬链接,在 macOS 上使用 clonefile。


节省磁盘空间

在 Linux 和 Windows 上,Bun 使用硬链接将模块“复制”到项目的 node_modules 目录中,因此软件包内容在磁盘上只存储一份。这大大减少了 node_modules 占用的磁盘空间。

macOS 上也是如此,但有一个例外。Bun 在 macOS 上使用写时复制的 clonefile:克隆不会占用额外的磁盘空间,但会计入驱动器的容量限制。由于只有在写入时才会进行复制,因此在一个项目中修改 node_modules/* 不会影响其他安装。

安装策略

使用 --backend 标志进行配置,Bun 的所有软件包管理命令都支持该标志。

  • hardlink:Linux 和 Windows 上的默认选项。
  • clonefile:macOS 上的默认选项。
  • clonefile_each_dir:与 clonefile 类似,但会按目录逐个克隆每个文件。仅适用于 macOS,且通常比 clonefile 慢。
  • copyfile:上述选项失败时使用的回退方案。这是最慢的选项。在 macOS 上,它使用 fcopyfile();在 Linux 上,它使用 copy_file_range()。
  • symlink:为每个文件创建符号链接,而不是复制文件。只有提升式安装会使用它:--backend=symlink 会将其应用于每个软件包(macOS 和 Linux;Windows 会忽略该标志);不使用该标志时,Bun 仅会将其用于项目目录之外的 file: 依赖项(例如 file:../foo)以及传递性 file: 依赖项。

如果使用 --backend=symlink 安装,Node.js 不会解析依赖项的 node_modules,除非每个依赖项都有自己的 node_modules 文件夹,或者你向 node 传递 --preserve-symlinks。请参阅 Node.js 关于 --preserve-symlinks 的文档。

terminal
bun install --backend symlink
node --preserve-symlinks ./foo.js

Bun 的运行时同样支持 --preserve-symlinks。