Skip to main content
Bun 支持在 package.json 中使用 workspaces。工作区使得将复杂软件作为包含多个独立包的 monorepo 进行开发变得简单。 一个 monorepo 通常具有如下结构:
File Tree
<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 的目录下。
package.json
{
  "name": "my-project",
  "version": "1.0.0",
  "workspaces": ["packages/*"],
  "devDependencies": {
    "example-package-in-monorepo": "workspace:*"
  }
}
支持 Glob 语法 — Bun 在 "workspaces" 中支持完整的 glob 语法,包括否定模式(例如 !**/excluded/**)。详细支持语法列表见 这里
package.json
{
  "name": "my-project",
  "version": "1.0.0",
  "workspaces": ["packages/**", "!packages/**/test/**", "!packages/**/template/**"]
}
每个工作区有自己的 package.json。当引用 monorepo 中的其他包时,可以在 package.json 的版本字段中使用语义化版本号(semver)或工作区协议(例如 workspace:*)。
packages/pkg-a/package.json
{
  "name": "pkg-a",
  "version": "1.0.0",
  "dependencies": {
    "pkg-b": "workspace:*"
  }
}
bun install 会为 monorepo 中的所有工作区安装依赖,如果可能会去重包。如果只想为指定工作区安装依赖,可以使用 --filter 标志。
# 安装所有以 `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 依赖 abun install 会将本地的 packages/a 目录安装到 node_modules,而不是从 npm 注册表下载。
  • 依赖可以去重。 如果 ab 有共同依赖,则会将其 提升 到根目录的 node_modules,减少重复磁盘占用,并最小化因同时安装多个版本依赖引发的“依赖地狱”问题。
  • 可在多个包中运行脚本。 你可以使用 --filter 参数 在多个工作区中轻松运行 package.json 脚本,或用 --workspaces 在所有工作区间运行脚本。

使用 Catalogs 共享版本

当多个包需要相同依赖版本时,Catalogs 允许你在根目录的 package.json 中一次性定义这些版本,并使用 catalog: 协议在工作区中引用。更新 Catalog 会自动更新所有引用它的包。详情请见 Catalogs
⚡️ 速度 — 即使是大型 monorepo,安装速度依然非常快。Bun 在 Linux 下安装 Remix monorepo 约需 500ms
  • npm install 快 28 倍
  • yarn install (v1) 快 12 倍
  • pnpm install 快 8 倍