> ## Documentation Index
> Fetch the complete documentation index at: https://bun.ll1025.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# 自动安装

> Bun 的自动包安装功能，用于独立脚本执行

如果 Bun 在工作目录或上级目录中找不到 `node_modules` 目录，它会放弃 Node.js 风格的模块解析，转而使用 **Bun 模块解析算法**。

在 Bun 风格的模块解析下，Bun 在执行过程中将每个导入的包动态自动安装到[全局模块缓存](/pm/global-cache)中（与 [`bun install`](/pm/cli/install) 使用的缓存相同）。

```ts index.ts icon="https://mintcdn.com/span-inc/82N53aP7NFbaCVSl/icons/typescript.svg?fit=max&auto=format&n=82N53aP7NFbaCVSl&q=85&s=787d39d6a7d96d7f9540dc74344eba23" theme={null}
import { foo } from "foo"; // 安装 `latest` 版本

foo();
```

第一次运行此脚本时，Bun 会自动安装 `"foo"` 并缓存它。后续运行会使用缓存的版本。

***

## 版本解析

Bun 按以下方式确定要安装的版本：

1. 检查项目根目录中的 `bun.lock` 文件。如果存在，使用锁定文件中指定的版本。
2. 否则，向上扫描目录树查找包含 `"foo"` 作为依赖的 `package.json`。如果找到，使用指定的 semver 版本或版本范围。
3. 否则，使用 `latest`。

***

## 缓存行为

一旦 Bun 确定了一个版本或版本范围，它会：

1. 检查模块缓存中是否有兼容版本。如果有，直接使用。
2. 解析 `latest` 时，检查 `package@latest` 是否在过去 *24 小时* 内下载并缓存过。如果是，直接使用。
3. 否则，从 `npm` 注册表下载并安装适当的版本。

***

## 安装

Bun 将包安装并缓存到 `<cache>/<pkg>@<version>` 中，因此同一包的多个版本可以同时缓存。它还会在 `<cache>/<pkg>/<version>` 下创建一个符号链接，以加速查找包的所有缓存版本。

***

## 版本说明符

要完全绕过版本解析，可以在导入语句中直接指定版本或版本范围。

```ts index.ts icon="https://mintcdn.com/span-inc/82N53aP7NFbaCVSl/icons/typescript.svg?fit=max&auto=format&n=82N53aP7NFbaCVSl&q=85&s=787d39d6a7d96d7f9540dc74344eba23" theme={null}
import { z } from "zod@3.0.0"; // 特定版本
import { z } from "zod@next"; // npm 标签
import { z } from "zod@^3.20.0"; // semver 范围
```

***

## 优势

* **空间效率** — 每个依赖版本在磁盘上只有一个位置。与冗余的每个项目安装相比，节省了空间和时间。
* **可移植性** — 你的源文件是\_自包含\_的，因此分享脚本和片段不需要打包代码和配置文件的目录。通过在 `import` 语句中使用版本说明符，甚至不需要 `package.json`。
* **便利性** — 在使用 `bun run` 运行文件或脚本之前，无需运行 `npm install` 或 `bun install`。
* **向后兼容** — 因为如果存在 `package.json`，Bun 仍然遵循其中指定的版本，你可以通过一条命令切换到 Bun 风格的解析：`rm -rf node_modules`。

***

## 限制

* 无 Intellisense。IDE 中的 TypeScript 自动补全依赖于 `node_modules` 中的类型声明文件。我们正在研究解决方案。
* 不支持 [patch-package](https://github.com/ds300/patch-package)

***

## 常见问题

<AccordionGroup>
  <Accordion title="这与 pnpm 的做法有何不同？">
    使用 pnpm，你需要运行 `pnpm install`，这会创建一个 `node_modules` 文件夹的符号链接供运行时解析。相比之下，Bun 在运行文件时动态解析依赖；无需提前运行任何 `install` 命令。Bun 也不会创建 `node_modules` 文件夹。
  </Accordion>

  <Accordion title="这与 Yarn Plug'N'Play 有何不同？">
    使用 Yarn，你必须在运行脚本之前运行 `yarn install`。相比之下，Bun 在运行文件时动态解析依赖；无需提前运行任何 `install` 命令。

    Yarn Plug'N'Play 还使用 zip 文件存储依赖。这使得依赖加载[在运行时更慢](https://twitter.com/jarredsumner/status/1458207919636287490)，因为 zip 文件上的随机访问读取往往比等效的磁盘查找更慢。
  </Accordion>

  <Accordion title="这与 Deno 的做法有何不同？">
    Deno 要求在每次 npm `import` 前加上 `npm:` 说明符，不支持通过 `tsconfig.json` 中的 `compilerOptions.paths` 使用导入映射，并且对 `package.json` 设置的支持不完整。与 Deno 不同，Bun 目前不支持 URL 导入。
  </Accordion>
</AccordionGroup>
