构建文档参考指南博客
Bun

工作区

Bun 支持 package.json 中的 workspaces。Workspaces 可以轻松地将复杂的软件开发为由多个独立包组成的单体仓库

单体仓库通常具有以下结构

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" 键用于指定哪些子目录应被视为单体仓库中的包/工作区。通常将所有工作区放在一个名为 packages 的目录中。

{
  "name": "my-project",
  "version": "1.0.0",
  "workspaces": ["packages/*"],
  "devDependencies": {
    "example-package-in-monorepo": "workspace:*"
  }
}

支持 Glob 语法 — Bun 支持 "workspaces" 中的完整 Glob 语法,包括否定模式(例如 !**/excluded/**)。有关支持语法的完整列表,请参阅此处

{
  "name": "my-project",
  "version": "1.0.0",
  "workspaces": [
    "packages/**",
    "!packages/**/test/**",
    "!packages/**/template/**"
  ]
}

每个工作区都有自己的 package.json。在引用单体仓库中的其他包时,可以使用 semver 或 workspace 协议(例如 workspace:*)作为 package.json 中的版本字段。

{
  "name": "pkg-a",
  "version": "1.0.0",
  "dependencies": {
    "pkg-b": "workspace:*"
  }
}

bun install 将为单体仓库中的所有工作区安装依赖项,并在可能的情况下进行去重。如果您只想为特定工作区安装依赖项,可以使用 --filter 标志。

# Install dependencies for all workspaces starting with `pkg-` except for `pkg-c`
bun install --filter "pkg-*" --filter "!pkg-c"

# Paths can also be used. This is equivalent to the command above.
bun install --filter "./packages/pkg-*" --filter "!pkg-c" # or --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" // Even if current version is 1.0.1

Workspaces 有几个主要优点。

  • 代码可以被拆分成逻辑部分。 如果一个包依赖于另一个包,您可以将其添加为 package.json 中的依赖项。如果包 b 依赖于 abun install 将把本地的 packages/a 目录安装到 node_modules 中,而不是从 npm 注册表中下载。
  • 依赖项可以去重。 如果 ab 共享一个通用依赖项,该依赖项将被提升到根目录的 node_modules。这减少了冗余的磁盘使用量,并最大限度地减少了同时安装多个包版本时出现的“依赖地狱”问题。
  • 在多个包中运行脚本。 您可以使用 --filter 标志轻松地在工作区中的多个包中运行 package.json 脚本,或者使用 --workspaces 跨所有工作区运行脚本。

使用 Catalogs 共享版本

当许多包需要相同的依赖版本时,catalogs 允许您在根目录的 package.json 中定义 这些版本一次,并在您的 工作区中使用 catalog: 协议引用它们。更新 catalog 会自动 更新所有引用它的包。有关详细信息,请参阅 Catalogs

⚡️ 速度 — 安装速度很快,即使对于大型单体仓库也是如此。Bun 大约在 500ms 内安装 Remix 单体仓库(在 Linux 上)。

  • npm install 快 28 倍
  • yarn install (v1) 快 12 倍
  • pnpm install 快 8 倍