跳到主要内容
版本:9.x

目录

新增于:v9.5.0

"目录"是工作区功能,用于将依赖版本范围定义为可重用常量。在目录中定义的常量之后可以在package.json文件中引用。

目录协议(catalog:

一旦在pnpm-workspace.yaml中定义了目录,

pnpm-workspace.yaml
packages:
- packages/*

# 定义版本范围目录
catalog:
react: ^18.3.1
redux: ^5.0.1

可以使用catalog:协议代替版本范围本身。

packages/example-app/package.json
{
"name": "@example/app",
"dependencies": {
"react": "catalog:",
"redux": "catalog:"
}
}

这相当于直接编写版本范围(例如^18.3.1)。

packages/example-app/package.json
{
"name": "@example/app",
"dependencies": {
"react": "^18.3.1",
"redux": "^5.0.1"
}
}

您可以在package.json的以下字段中使用catalog:协议:

  • dependencies
  • devDependencies
  • peerDependencies
  • optionalDependencies
  • pnpm.overrides

catalog:协议允许在冒号后使用可选名称(例如:catalog:name)来指定应使用的目录。当省略名称时,使用默认目录。

根据不同的场景,与直接编写版本范围相比,catalog:协议提供了一些优势,详细说明如下。

优势

在工作区(即单体仓库或多包仓库)中,多个包使用相同依赖的情况很常见。目录减少了编写package.json文件时的重复,并为此提供了一些好处:

  • 保持唯一版本 —— 在工作区中通常希望只有一个依赖版本。目录使维护更加容易。重复的依赖可能在运行时发生冲突并导致错误。使用打包器时,重复还会增加体积。
  • 更轻松的升级 —— 当升级依赖时,只需编辑pnpm-workspace.yaml中的目录条目,而无需编辑所有使用该依赖的package.json文件。这节省了时间——只需更改一行而不是多行。
  • 更少的合并冲突 —— 由于升级依赖时不需要编辑package.json文件,因此这些文件中不再会发生Git合并冲突。

定义目录

目录在pnpm-workspace.yaml文件中定义。有两种方式定义目录。

  1. 使用(单数)catalog字段创建名为default的目录。
  2. 使用(复数)catalogs字段创建任意命名的目录。
提示

如果您有一个现有工作区想要迁移到使用目录,可以使用以下codemod

pnpx codemod pnpm/catalog

默认目录

顶级catalog字段允许用户定义名为default的目录。

pnpm-workspace.yaml
catalog:
react: ^18.2.0
react-dom: ^18.2.0

这些版本范围可以通过catalog:default引用。对于默认目录,还可以使用特殊的catalog:简写。可以把catalog:视为扩展为catalog:default的简写。

命名目录

可以在catalogs键下配置多个任意命名的目录。

pnpm-workspace.yaml
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

可以在定义多个命名目录的同时定义默认目录。这在大型多包仓库逐步迁移到新版本依赖时可能很有用。

pnpm-workspace.yaml
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

发布

运行pnpm publishpnpm pack时会移除catalog:协议。这类似于workspace:协议,它在发布时也会被替换。

例如,

packages/example-components/package.json
{
"name": "@example/components",
"dependencies": {
"react": "catalog:react18",
}
}

在发布时会变成:

packages/example-components/package.json
{
"name": "@example/components",
"dependencies": {
"react": "^18.3.1",
}
}

catalog:协议替换过程使得@example/components包可以被其他工作区或包管理器使用。

注意事项

pnpm update命令尚不支持目录。

要更新在pnpm-workspace.yaml中定义的依赖项,需要手动选择较新的版本范围,直到未来版本的pnpm处理此问题。