> ## 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 在 `package.json` 中支持 [`workspaces`](https://docs.npmjs.com/cli/v9/using-npm/workspaces?v=true#description)。Workspaces 让你将复杂软件开发为一个由多个独立包组成的 *monorepo*。

一个 monorepo 通常具有如下结构：

```txt File Tree icon="folder-tree" theme={"theme":{"light":"github-light","dark":"dracula"}}
<root>
├── README.md
├── bun.lock
├── package.json
├── tsconfig.json
└── packages
    ├── pkg-a
    │   ├── index.ts
    │   ├── package.json
    │   └── tsconfig.json
    ├── pkg-b
    │   ├── index.ts
    │   ├── package.json
    │   └── tsconfig.json
    └── pkg-c
        ├── index.ts
        ├── package.json
        └── tsconfig.json
```

在根目录的 `package.json` 中，使用 `"workspaces"` 键来表示哪些子目录应被视为 monorepo 内的包/工作区。通常将所有工作区放置在名为 `packages` 的目录下。

```json package.json icon="file-json" theme={"theme":{"light":"github-light","dark":"dracula"}}
{
  "name": "my-project",
  "version": "1.0.0",
  "workspaces": ["packages/*"],
  "devDependencies": {
    "example-package-in-monorepo": "workspace:*"
  }
}
```

<Note>
  **支持 Glob 语法** — Bun 在 `"workspaces"` 中支持完整的 glob 语法，包括否定模式（例如 `!**/excluded/**`）。详细支持语法列表见 [这里](/runtime/glob#supported-glob-patterns)。
</Note>

```json package.json icon="file-json" theme={"theme":{"light":"github-light","dark":"dracula"}}
{
  "name": "my-project",
  "version": "1.0.0",
  "workspaces": ["packages/**", "!packages/**/test/**", "!packages/**/template/**"]
}
```

每个工作区有自己的 `package.json`。当引用 monorepo 中的其他包时，可以在 `package.json` 的版本字段中使用语义化版本号（semver）或工作区协议（例如 `workspace:*`）。

```json packages/pkg-a/package.json icon="file-json" theme={"theme":{"light":"github-light","dark":"dracula"}}
{
  "name": "pkg-a",
  "version": "1.0.0",
  "dependencies": {
    "pkg-b": "workspace:*"
  }
}
```

`bun install` 会为 monorepo 中的所有工作区安装依赖，如果可能会去重包。如果只想为指定工作区安装依赖，可以使用 `--filter` 标志。

```bash theme={"theme":{"light":"github-light","dark":"dracula"}}
# 安装所有以 `pkg-` 开头且不包含 `pkg-c` 的工作区依赖
bun install --filter "pkg-*" --filter "!pkg-c"

# 也可以使用路径，这与上面命令效果相同。
bun install --filter "./packages/pkg-*" --filter "!pkg-c" # 或 --filter "!./packages/pkg-c"
```

发布时，`workspace:` 版本会被替换为包的 `package.json` 中的版本号：

```
"workspace:*" -> "1.0.1"
"workspace:^" -> "^1.0.1"
"workspace:~" -> "~1.0.1"
```

指定具体版本会优先于包的 `package.json` 版本：

```
"workspace:1.0.2" -> "1.0.2" // 即使当前版本是 1.0.1
```

工作区有几个主要优势：

* **代码可以拆分成逻辑部分。** 如果一个包依赖另一个包，就在 `package.json` 中将其添加为依赖。如果包 `b` 依赖 `a`，那么 `bun install` 会把你本地的 `packages/a` 目录安装到 `node_modules` 中，而不是从 npm 注册表下载。
* **依赖可以去重。** 如果 `a` 和 `b` 共享一个共同依赖，它会被 *提升（hoist）* 到根目录的 `node_modules` 目录。这能减少重复的磁盘占用，并最大程度减少与同时安装多个版本包相关的“依赖地狱”问题。
* **在多个包中运行脚本。** 你可以使用 [`--filter` 标志](/pm/filter) 在你的工作区中对多个包运行 `package.json` 脚本，或使用 `--workspaces` 在所有工作区中运行脚本。

## 使用 Catalogs 共享版本

当多个包需要相同依赖版本时，Catalogs 允许你在根目录的 `package.json` 中一次性定义这些版本，并使用 `catalog:` 协议在工作区中引用。更新 Catalog 会自动更新所有引用它的包。详情请见 [Catalogs](/pm/catalogs)。

<Note>
  ⚡️ **速度** — 即使是大型 monorepo，安装速度依然非常快。Bun 在 Linux 下安装 [Remix](https://github.com/remix-run/remix) monorepo 约需 `500ms`。

  * 比 `npm install` 快 28 倍
  * 比 `yarn install` (v1) 快 12 倍
  * 比 `pnpm install` 快 8 倍

  <Image src="https://user-images.githubusercontent.com/709451/212829600-77df9544-7c9f-4d8d-a984-b2cd0fd2aa52.png" />
</Note>
