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 会在运行文件时动态解析依赖;无需事先运行任何 install 命令。Yarn Plug’N’Play 使用 zip 文件存储依赖,这导致依赖加载在运行时更慢,因为对 zip 文件的随机访问通常比等效的磁盘查找更慢。参考这与 Deno 有何区别?
这与 Deno 有何区别?
Deno 要求在每个 npm
import 前使用 npm: 说明符,不支持通过 tsconfig.json 中的 compilerOptions.paths 使用导入映射,并且对 package.json 设置的支持尚不完整。与 Deno 不同,Bun 目前不支持 URL 导入。