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

# 自动安装

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

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

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

```ts index.ts icon="https://mintcdn.com/bun-zhcndoc/cnUTwgMuf4cCrwC-/icons/typescript.svg?fit=max&auto=format&n=cnUTwgMuf4cCrwC-&q=85&s=e7767043c9e885c34f2d6c8fe2a95217" theme={"theme":{"light":"github-light","dark":"dracula"}}
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>` 下创建了一个符号链接，以更快地查找缓存中存在的某个包的所有版本。

***

## 版本说明符

您可以在导入语句中直接指定版本或版本范围，从而简化整个解析算法。

```ts index.ts icon="https://mintcdn.com/bun-zhcndoc/cnUTwgMuf4cCrwC-/icons/typescript.svg?fit=max&auto=format&n=cnUTwgMuf4cCrwC-&q=85&s=e7767043c9e885c34f2d6c8fe2a95217" theme={"theme":{"light":"github-light","dark":"dracula"}}
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 install` 或 `bun install`。用 `bun run` 运行即可。
* **向后兼容** — 因为如果存在 `package.json`，Bun 仍会尊重其中指定的版本，所以你可以只用一个命令切换到 Bun 风格的解析：`rm -rf node_modules`。

***

## 限制

* 无智能提示。IDE 中 TypeScript 的自动补全依赖于 `node_modules` 内存在类型声明文件。我们正在探索各种解决方案。
* 不支持 [patch-package](https://github.com/ds300/patch-package)

***

## 常见问题解答

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

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

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

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