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

# Catalogs

> 在单体仓库中跨多个包共享公共依赖版本

**Catalogs（目录）** 在单体仓库中的包之间共享依赖版本。无需在每个工作空间包中重复相同的版本，你可以在根 `package.json` 中统一定义它们，并在整个项目中引用。

## 概述

不再让每个工作空间包指定自己的版本，而是：

1. 在根 `package.json` 中定义版本目录
2. 使用 `catalog:` 协议引用这些版本
3. 通过在一处更改版本即可同时更新所有包

这在大型单体仓库中尤为重要，因为数十个包依赖于相同版本的關鍵依赖。

## 如何使用 Catalogs

### 目录结构示例

考虑以下结构的单体仓库：

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

### 1. 在根 package.json 中定义 Catalogs

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

```json package.json icon="file-json" theme={null}
{
  "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={null}
{
  "name": "app",
  "dependencies": {
    "react": "catalog:",
    "react-dom": "catalog:",
    "jest": "catalog:testing"
  }
}
```

```json packages/ui/package.json icon="file-json" theme={null}
{
  "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={null}
   "catalog": {
     "react": "^19.0.0",
     "react-dom": "^19.0.0"
   }
   ```

   使用 `catalog:` 引用：

   ```json packages/app/package.json icon="file-json" theme={null}
   "dependencies": {
     "react": "catalog:"
   }
   ```

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

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

   使用 `catalog:<name>` 引用：

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

## 使用 Catalogs 的好处

* **一致性**：所有包使用相同版本的关键依赖
* **维护性**：在一处更新依赖版本，而不是在多个 `package.json` 文件中
* **清晰性**：一目了然地了解哪些依赖在你的单体仓库中是标准化的
* **简洁性**：无需额外的版本解析策略或外部工具

## 实际示例

一个更大的示例，用于 React 应用：

**根 package.json**

```json package.json icon="file-json" theme={null}
{
  "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={null}
{
  "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={null}
{
  "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={null}
{
  "name": "@monorepo/utils",
  "dependencies": {
    "react": "catalog:"
  },
  "devDependencies": {
    "jest": "catalog:testing"
  }
}
```

## 更新版本

要更新所有包中的版本，请更改根 package.json 中的版本：

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

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

## 锁文件集成

Bun 的锁文件会跟踪目录版本，因此安装在不同环境中是一致的。锁文件包含：

* 来自你的 `package.json` 的目录定义
* 每个目录依赖的解析结果

```json bun.lock(摘录) icon="file-json" theme={null}
{
  "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` 时解析失败
* 目录仅在工作空间内可用；不能在单体仓库之外使用

## 发布

当你运行 `bun publish` 或 `bun pm pack` 时，Bun 会将 `package.json` 中的 `catalog:` 引用替换为已解析的版本号。发布的包包含常规的 semver 字符串，不再依赖于你的目录定义。
