> ## 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.

# 目录

> 在 monorepo 中跨多个包共享通用依赖版本

Bun 的目录（Catalog）让你能够在 monorepo 中的多个包之间共享通用的依赖版本。与其在每个工作区包中反复指定相同的版本，不如在根目录的 `package.json` 中只定义一次，然后在整个项目中一致地引用它们。

## 概述

与传统的依赖管理方式中每个工作区包需要独立指定版本不同，目录让你能够：

1. 在根目录 package.json 中定义版本目录（version catalogs）
2. 使用 `catalog:` 协议引用这些版本
3. 通过在一个位置更改版本，同时更新所有包

这在需要多个包使用相同关键依赖版本的大型 monorepo 中尤其有用。

## 如何使用目录

### 目录结构示例

假设有如下结构的 monorepo：

```
my-monorepo/
├── package.json
├── bun.lock
└── packages/
    ├── app/
    │   └── package.json
    ├── ui/
    │   └── package.json
    └── utils/
        └── package.json
```

### 1. 在根目录 package.json 中定义目录

在根目录的 `package.json` 中，在 `workspaces` 对象内添加 `catalog` 或 `catalogs` 字段：

```json package.json icon="file-json" theme={"theme":{"light":"github-light","dark":"dracula"}}
{
  "name": "my-monorepo",
  "workspaces": {
    "packages": ["packages/*"],
    "catalog": {
      "react": "^19.0.0",
      "react-dom": "^19.0.0"
    },
    "catalogs": {
      "testing": {
        "jest": "30.0.0",
        "testing-library": "14.0.0"
      }
    }
  }
}
```

如果你将 `catalog` 或 `catalogs` 放在 `package.json` 的顶层，也同样有效。

### 2. 在工作区包中引用目录版本

在工作区包中，使用 `catalog:` 协议引用版本：

```json packages/app/package.json icon="file-json" theme={"theme":{"light":"github-light","dark":"dracula"}}
{
  "name": "app",
  "dependencies": {
    "react": "catalog:",
    "react-dom": "catalog:",
    "jest": "catalog:testing"
  }
}
```

```json packages/ui/package.json icon="file-json" theme={"theme":{"light":"github-light","dark":"dracula"}}
{
  "name": "ui",
  "dependencies": {
    "react": "catalog:",
    "react-dom": "catalog:"
  },
  "devDependencies": {
    "jest": "catalog:testing",
    "testing-library": "catalog:testing"
  }
}
```

### 3. 运行 Bun Install

运行 `bun install`，即可根据目录中定义的版本安装所有依赖。

## Catalog 与 Catalogs 的区别

Bun 支持两种定义目录的方式：

1. **`catalog`**（单数）：用于常用依赖的单一默认目录

   ```json package.json icon="file-json" theme={"theme":{"light":"github-light","dark":"dracula"}}
   "catalog": {
     "react": "^19.0.0",
     "react-dom": "^19.0.0"
   }
   ```

   使用 `catalog:` 引用：

   ```json packages/app/package.json icon="file-json" theme={"theme":{"light":"github-light","dark":"dracula"}}
   "dependencies": {
     "react": "catalog:"
   }
   ```

2. **`catalogs`**（复数）：用于分组依赖的多个命名目录

   ```json package.json icon="file-json" theme={"theme":{"light":"github-light","dark":"dracula"}}
   "catalogs": {
     "testing": {
       "jest": "30.0.0"
     },
     "ui": {
       "tailwind": "4.0.0"
     }
   }
   ```

   使用时需要指定目录名，格式为 `catalog:<name>`：

   ```json packages/app/package.json icon="file-json" theme={"theme":{"light":"github-light","dark":"dracula"}}
   "dependencies": {
     "jest": "catalog:testing",
     "tailwind": "catalog:ui"
   }
   ```

## 使用目录的好处

* **一致性**：确保所有包使用相同版本的关键依赖
* **维护方便**：只需在一个地方更新依赖版本，而非多个 package.json
* **清晰明了**：明确表示哪些依赖在整个 monorepo 中统一使用
* **简单易用**：无需复杂的版本解析策略或外部工具

## 真实示例

以下是一个针对 React 应用的更完整示例：

**根目录 package.json**

```json package.json icon="file-json" theme={"theme":{"light":"github-light","dark":"dracula"}}
{
  "name": "react-monorepo",
  "workspaces": {
    "packages": ["packages/*"],
    "catalog": {
      "react": "^19.0.0",
      "react-dom": "^19.0.0",
      "react-router-dom": "^6.15.0"
    },
    "catalogs": {
      "build": {
        "webpack": "5.88.2",
        "babel": "7.22.10"
      },
      "testing": {
        "jest": "29.6.2",
        "react-testing-library": "14.0.0"
      }
    }
  },
  "devDependencies": {
    "typescript": "5.1.6"
  }
}
```

```json packages/app/package.json icon="file-json" theme={"theme":{"light":"github-light","dark":"dracula"}}
{
  "name": "app",
  "dependencies": {
    "react": "catalog:",
    "react-dom": "catalog:",
    "react-router-dom": "catalog:",
    "@monorepo/ui": "workspace:*",
    "@monorepo/utils": "workspace:*"
  },
  "devDependencies": {
    "webpack": "catalog:build",
    "babel": "catalog:build",
    "jest": "catalog:testing",
    "react-testing-library": "catalog:testing"
  }
}
```

```json packages/ui/package.json icon="file-json" theme={"theme":{"light":"github-light","dark":"dracula"}}
{
  "name": "@monorepo/ui",
  "dependencies": {
    "react": "catalog:",
    "react-dom": "catalog:"
  },
  "devDependencies": {
    "jest": "catalog:testing",
    "react-testing-library": "catalog:testing"
  }
}
```

```json packages/utils/package.json icon="file-json" theme={"theme":{"light":"github-light","dark":"dracula"}}
{
  "name": "@monorepo/utils",
  "dependencies": {
    "react": "catalog:"
  },
  "devDependencies": {
    "jest": "catalog:testing"
  }
}
```

## 更新版本

要在所有包中更新版本，只需在根目录 package.json 中更改版本：

```json package.json icon="file-json" theme={"theme":{"light":"github-light","dark":"dracula"}}
"catalog": {
  "react": "^19.1.0",  // 从 ^19.0.0 更新
  "react-dom": "^19.1.0"  // 从 ^19.0.0 更新
}
```

然后运行 `bun install` 即可更新所有包。

## 锁文件集成

Bun 的 lockfile 会跟踪目录版本，确保在不同环境中进行一致的安装。锁文件包含：

* package.json 中的目录定义
* 每个目录依赖的解析结果

```json bun.lock(excerpt) icon="file-json" theme={"theme":{"light":"github-light","dark":"dracula"}}
{
  "lockfileVersion": 2,
  "workspaces": {
    "": {
      "name": "react-monorepo",
    },
    "packages/app": {
      "name": "app",
      "dependencies": {
        "react": "catalog:",
        "react-dom": "catalog:",
        ...
      },
    },
    ...
  },
  "catalog": {
    "react": "^19.0.0",
    "react-dom": "^19.0.0",
    ...
  },
  "catalogs": {
    "build": {
      "webpack": "5.88.2",
      ...
    },
    ...
  },
  "packages": {
    ...
  }
}
```

## 限制与注意事项

* 目录引用必须与 `catalog` 或某个命名 `catalogs` 中定义的依赖匹配
* 目录名称中的空字符串和空白字符会被忽略（视为默认目录）
* 目录中的无效依赖版本会导致 `bun install` 解析失败
* 目录仅在工作区内有效，无法在 monorepo 外使用

Bun 的目录系统能够在不增加工作流复杂度的情况下，维护你整个 monorepo 的一致性。

## 发布

当你运行 `bun publish` 或 `bun pm pack` 时，Bun 会自动将 `package.json` 中的 `catalog:` 引用替换为具体的版本号。发布的包中包含标准的 semver 版本字符串，不再依赖你的目录定义。
