node_modules 目录,Bun 将放弃 Node.js 风格的模块解析,转而使用 Bun 模块解析算法。
在 Bun 风格的模块解析下,所有导入的包将在运行时自动安装到一个全局模块缓存中(与 bun install 使用的缓存相同)。
"foo" 并缓存它。下一次运行该脚本时,将使用缓存的版本。
版本解析
为确定安装哪个版本,Bun 遵循以下算法:- 检查项目根目录中是否存在
bun.lock文件。如果存在,则使用锁文件中指定的版本。 - 否则,向上遍历目录查找包含
"foo"作为依赖项的package.json。如果找到,则使用指定的语义版本或版本范围。 - 否则,使用
latest。
缓存行为
一旦确定了版本或版本范围,Bun 将:- 检查模块缓存中是否有兼容版本。如果存在,则使用它。
- 解析
latest时,Bun 会检查package@latest是否在最近 24 小时内 已下载并缓存。如果是,则使用它。 - 否则,从
npm注册表下载并安装合适的版本。
安装
包被安装并缓存到<cache>/<pkg>@<version>,因此同一包的多个版本可以同时缓存。此外,在 <cache>/<pkg>/<version> 下创建了一个符号链接,以更快地查找缓存中存在的某个包的所有版本。
版本说明符
您可以在导入语句中直接指定版本或版本范围,从而简化整个解析算法。优势
这种自动安装方式有以下几方面的优势:- 节省空间 — 每个依赖版本只存在于磁盘上的一个位置。相较于为每个项目冗余安装,这极大地节省了空间和时间。
- 便携性 — 为了共享简单脚本和代码片段,您的源文件是 自包含 的。无需将代码和配置文件一同打包成
zip。使用导入语句中的版本说明符,甚至不需要package.json。 - 便利性 — 无需在运行文件或脚本之前执行
npm install或bun install,只需使用bun run即可。 - 向后兼容 — 因为 Bun 仍然尊重存在时
package.json中指定的版本,所以只需一个命令即可切换到 Bun 风格解析:rm -rf node_modules。
限制
- 无智能提示。IDE 中 TypeScript 的自动补全依赖于
node_modules内存在类型声明文件。我们正在探索各种解决方案。 - 不支持 patch-package
常见问题解答
这与 pnpm 的做法有何不同?
这与 pnpm 的做法有何不同?
使用 pnpm,必须先运行
pnpm install,该命令会创建一个包含符号链接的 node_modules 文件夹供运行时解析。相比之下,Bun 在运行文件时动态解析依赖,无需事先运行任何安装命令。Bun 也不会创建 node_modules 文件夹。这与 Yarn Plug'N'Play 有何不同?
这与 Yarn Plug'N'Play 有何不同?
使用 Yarn,必须先运行
yarn install 才能运行脚本。相比之下,Bun 在运行文件时动态解析依赖,无需事先运行任何安装命令。Yarn Plug’N’Play 使用 zip 文件存储依赖,这导致依赖加载在运行时更慢,因为对 zip 文件的随机访问通常比等效的磁盘查找更慢。参考这与 Deno 有何区别?
这与 Deno 有何区别?
Deno 需要在每个 npm
import 之前加上 npm: 说明符,不支持通过 tsconfig.json 中的 compilerOptions.paths 使用导入映射,并且对 package.json 配置支持不完整。与 Deno 不同,Bun 目前不支持 URL 导入。