Catalogs
“Catalogs” 是一个 工作空间功能,可将依赖项版本定义为可复用常量。目录中定义的常量稍后可以在 package.json 文件中引用。
The catalog protocol (catalog:)#
在 pnpm-workspace.yaml 中定义目录,
packages:
- packages/*
# 定义目录和依赖版本号
catalog:
react: ^18.3.1
redux: ^5.0.1
可以使用 catalog: 协议来代替依赖项版本。
{
"name": "@example/app",
"dependencies": {
"react": "catalog:",
"redux": "catalog:"
}
}
这等于直接写入一个版本范围(例如 ^18.3.1)。
{
"name": "@example/app",
"dependencies": {
"react": "^18.3.1",
"redux": "^5.0.1"
}
}
你可以在以下字段中使用 catalog: 协议:
package.json:dependenciesdevDependenciespeerDependenciesoptionalDependencies
pnpm-workspace.yamloverrides
Catalog 协议允许在冒号后使用可选名称 (例如:catalog:name) 来指定应使用哪个目录。当省略名称时,将使用默认目录。
根据不同的场景,catalog: 协议相比于直接编写版本范围提供了一些优势 ,将在下文中详细介绍。
优势#
在工作空间(即 monorepo 或多包 repo)中,许多包使用相同的依赖项是很常见的。在编写 package.json 文件时,目录可以减少重复,并在此过程中提供一些好处:
- Maintain unique versions: It's usually desirable to have only one version of a dependency in a workspace. Catalog 让工作区内共同依赖项的版本更容易维护。重复的依赖关系可能会在运行时冲突并导致错误。当使用打包器时,不同版本的重复依赖项也会增大项目体积。
- Easier upgrades: When upgrading a dependency, only the catalog entry in
pnpm-workspace.yamlneeds to be edited rather than allpackage.jsonfiles using that dependency. This saves time. Only one line needs to be changed instead of many. - Fewer merge conflicts: Since
package.jsonfiles do not need to be edited when upgrading a dependency, git merge conflicts no longer happen in these files.
Defining catalogs#
目录在 pnpm-workspace.yaml 文件中定义。有两种方法来定义目录。
- 使用 (单数)
catalog字段创建名为default的目录。 - 使用 (复数)
catalogs字段创建任意命名的目录。
Default catalog#
顶层 catalog 字段允许用户定义一个名为 default 的目录。
catalog:
react: ^18.2.0
react-dom: ^18.2.0
这些版本范围可以通过 catalog:default 引用。仅有默认目录时,也可以使用特殊的 catalog: 简写。将 catalog: 视为可扩展为 catalog:default 的简写。
Named catalogs#
可以在 catalogs 键下配置具有名称任意选择的多个catalog。
catalogs:
# 可以通过 "catalog:react17" 引用
react17:
react: ^17.0.2
react-dom: ^17.0.2
# 可以通过 "catalog:react18" 引用
react18:
react: ^18.2.0
react-dom: ^18.2.0
默认目录可以与多个命名目录一起定义。这对正在更新依赖项版本的大型多包存储库可能会很有用。
catalog:
react: ^16.14.0
react-dom: ^16.14.0
catalogs:
# 可以通过 "catalog:react17" 引用
react17:
react: ^17.0.2
react-dom: ^17.0.2
# 可以通过 "catalog:react18" 引用
react18:
react: ^18.2.0
react-dom: ^18.2.0
Workspace dependencies in a catalog#
Added in: v11.26.0
A catalog entry may hold a workspace: range, so the version a workspace dependency is linked by is written once too:
catalog:
'@example/utils': workspace:^
{
"name": "@example/app",
"dependencies": {
"@example/utils": "catalog:"
}
}
pnpm expands the catalog: reference to workspace:^ and then links the workspace project, exactly as if the package.json had declared workspace:^ itself. On publish both protocols are replaced, so the example above ships as "^1.4.0" when @example/utils is at 1.4.0.
发布#
运行 pnpm publish 或者 pnpm pack 时,catalog: 协议将被移除。这与 workspace: 协议 类似,该协议在发布时也会被替换。
例如,
{
"name": "@example/components",
"dependencies": {
"react": "catalog:react18"
}
}
在发布时将变为以下内容。
{
"name": "@example/components",
"dependencies": {
"react": "^18.3.1"
}
}
catalog: 的替换过程允许其他工作区或包管理器使用 @example/components 包。
设置#
catalogMode#
添加于:v10.12.1
- 默认值: manual
- 类型:manual、strict、prefer
控制运行 pnpm add 时是否以及如何将依赖项添加到默认目录中。有三种模式:
- strict - 仅允许来自目录的依赖版本。在目录版本范围之外添加依赖关系会导致错误。
- prefer - 优先使用目录版本,但如果未找到兼容版本,则会退回到直接依赖项。
- manual(默认)——不会自动将依赖项添加到目录中。
Since v11.26.0, a specifier that names a location rather than a version is never moved into a catalog: local paths, local tarballs, tarball URLs, and workspace:<path> ranges stay in the package.json that declares them. Such a specifier is resolved relative to its own project, so one catalog entry could not mean the same directory for every project that references it.
catalogPrune#
添加于:v11.22.0(自 v10.15.0 起为 cleanupUnusedCatalogs)
- 默认值: false
- 类型:Boolean
当设置为 true 时,pnpm 将在安装期间删除未使用的目录条目。
cleanupUnusedCatalogs 是该设置已弃用的名称,但仍可继续使用;若两者同时设置,则以 catalogPrune 为准。