Bun 在 package.json
中支持 workspaces
。Workspaces 使以 monorepo(由几个独立的包组成)形式开发复杂软件变得容易。
monorepo 通常具有以下结构
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
的目录中。
{
"name": "my-project",
"version": "1.0.0",
"workspaces": ["packages/*"],
"devDependencies": {
"example-package-in-monorepo": "workspace:*"
}
}
Glob 支持 — Bun 在 "workspaces"
中支持完整的 glob 语法(有关支持的语法的完整列表,请参阅此处),除了 排除项(例如 !**/excluded/**
),这些项尚未实现。
每个工作区都有自己的 package.json
。当引用 monorepo 中的其他包时,可以使用 semver 或 workspace 协议(例如 workspace:*
)作为 package.json
中的版本字段。
{
"name": "pkg-a",
"version": "1.0.0",
"dependencies": {
"pkg-b": "workspace:*"
}
}
bun install
将为 monorepo 中的所有工作区安装依赖项,如果可能,会去重包。 如果您只想为特定的工作区安装依赖项,可以使用 --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
工作区有几个主要优点。
- 代码可以拆分为逻辑部分。 如果一个包依赖于另一个包,您只需将其作为依赖项添加到
package.json
中。 如果包b
依赖于a
,则bun install
会将本地packages/a
目录安装到node_modules
中,而不是从 npm 注册表下载。 - 依赖项可以去重。 如果
a
和b
共享一个共同的依赖项,它将被提升到根目录的node_modules
目录。 这减少了冗余磁盘使用,并最大限度地减少了与同时安装多个版本的包相关的“依赖地狱”问题。 - 在多个包中运行脚本。 您可以使用
--filter
标志轻松地在工作区中的多个包中运行package.json
脚本。