Skip to main content
如果在工作目录或更高级目录中未找到 node_modules 目录,Bun 将放弃 Node.js 风格的模块解析,转而使用 Bun 模块解析算法 在 Bun 风格的模块解析下,所有导入的包将在运行时自动安装到一个全局模块缓存中(与 bun install 使用的缓存相同)。
https://mintcdn.com/bun-zhcndoc/cnUTwgMuf4cCrwC-/icons/typescript.svg?fit=max&auto=format&n=cnUTwgMuf4cCrwC-&q=85&s=e7767043c9e885c34f2d6c8fe2a95217index.ts
import { foo } from "foo"; // 安装 `latest` 版本

foo();
首次运行此脚本时,Bun 会自动安装 "foo" 并缓存它。下一次运行该脚本时,将使用缓存的版本。

版本解析

为确定安装哪个版本,Bun 遵循以下算法:
  1. 检查项目根目录中是否存在 bun.lock 文件。如果存在,则使用锁文件中指定的版本。
  2. 否则,向上遍历目录查找包含 "foo" 作为依赖项的 package.json。如果找到,则使用指定的语义版本或版本范围。
  3. 否则,使用 latest

缓存行为

一旦确定了版本或版本范围,Bun 将:
  1. 检查模块缓存中是否有兼容版本。如果存在,则使用它。
  2. 解析 latest 时,Bun 会检查 package@latest 是否在最近 24 小时内 已下载并缓存。如果是,则使用它。
  3. 否则,从 npm 注册表下载并安装合适的版本。

安装

包被安装并缓存到 <cache>/<pkg>@<version>,因此同一包的多个版本可以同时缓存。此外,在 <cache>/<pkg>/<version> 下创建了一个符号链接,以更快地查找缓存中存在的某个包的所有版本。

版本说明符

您可以在导入语句中直接指定版本或版本范围,从而简化整个解析算法。
https://mintcdn.com/bun-zhcndoc/cnUTwgMuf4cCrwC-/icons/typescript.svg?fit=max&auto=format&n=cnUTwgMuf4cCrwC-&q=85&s=e7767043c9e885c34f2d6c8fe2a95217index.ts
import { z } from "zod@3.0.0"; // 指定版本
import { z } from "zod@next"; // npm 标签
import { z } from "zod@^3.20.0"; // 语义版本范围

优势

这种自动安装方式有以下几方面的优势:
  • 空间效率 — 每个依赖的每个版本在磁盘上都只存在于一个位置。与每个项目中为避免重复安装而进行的冗余安装相比,这带来了巨大的空间和时间节省。
  • 可移植性 — 要共享简单脚本和 gist,您的源文件是 自包含 的。无需把包含代码和配置文件的目录打包成 zip。通过在 import 语句中使用版本说明符,即使没有 package.json 也不需要。
  • 便利性 — 运行文件或脚本之前无需先运行 npm installbun install。用 bun run 运行即可。
  • 向后兼容 — 因为如果存在 package.json,Bun 仍会尊重其中指定的版本,所以你可以只用一个命令切换到 Bun 风格的解析:rm -rf node_modules

限制

  • 无智能提示。IDE 中 TypeScript 的自动补全依赖于 node_modules 内存在类型声明文件。我们正在探索各种解决方案。
  • 不支持 patch-package

常见问题解答

使用 pnpm,必须先运行 pnpm install,该命令会创建一个包含符号链接的 node_modules 文件夹供运行时解析。相比之下,Bun 在运行文件时动态解析依赖,无需事先运行任何安装命令。Bun 也不会创建 node_modules 文件夹。
使用 Yarn,必须先运行 yarn install 才能运行脚本。相比之下,Bun 在运行文件时动态解析依赖,无需事先运行任何安装命令。Yarn Plug’N’Play 使用 zip 文件存储依赖,这导致依赖加载在运行时更慢,因为对 zip 文件的随机访问通常比等效的磁盘查找更慢。参考
Deno 需要在每个 npm import 之前加上 npm: 说明符,不支持通过 tsconfig.json 中的 compilerOptions.paths 使用导入映射,并且对 package.json 配置支持不完整。与 Deno 不同,Bun 目前不支持 URL 导入。