node_modules 目录,它会放弃 Node.js 风格的模块解析,转而使用 Bun 模块解析算法。
在 Bun 风格的模块解析下,Bun 会在执行期间将每个导入的包即时自动安装到全局模块缓存中(该缓存与 bun install 使用的缓存相同)。
index.ts
"foo" 并将其缓存。之后的运行会使用缓存的版本。
版本解析
Bun 按照以下方式确定要安装的版本:- 检查项目根目录中是否存在
bun.lock文件。如果存在,则使用锁文件中指定的版本。 - 否则,向上遍历目录查找包含
"foo"作为依赖项的package.json文件。如果找到,则使用指定的语义版本或版本范围。 - 否则,使用
latest。
缓存行为
一旦 Bun 确定了一个版本或版本范围,它会:- 检查模块缓存中是否存在兼容版本。如果存在,则使用该版本。
- 解析
latest时,检查package@latest是否在过去 24 小时 内下载并缓存过。如果是,则使用该版本。 - 否则,从
npm注册表下载并安装适当的版本。
安装
Bun 会将软件包安装并缓存到<cache>/<pkg>@<version>,因此同一软件包的多个版本可以同时缓存。它还会在 <cache>/<pkg>/<version> 下创建一个符号链接,以加快查找某个软件包的所有已缓存版本。
版本说明符
要完全绕过版本解析,请直接在导入语句中指定版本或版本范围。index.ts
优势
- 空间效率 — 每个依赖版本在磁盘上仅存在一份。与每个项目重复安装相比,这样可以节省空间和时间。
- 可移植性 — 源文件是_自包含的_,因此分享脚本和代码片段时,不必将代码和配置文件目录压缩成 zip。借助
import语句中的版本指定符,甚至不需要package.json。 - 便利性 — 使用
bun run运行文件或脚本前,无需执行npm install或bun install。 - 向后兼容性 — 由于 Bun 仍会遵循
package.json中指定的版本(如果存在),因此只需一条命令即可切换到 Bun 风格的解析方式:rm -rf node_modules。
限制
- 无 IntelliSense。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 导入。