目录
"目录" 是一个工作空间特性,用于将依赖项的版本范围定义为可重用的常量。在目录中定义的常量后续可以在 package.json
文件中引用。
目录协议 (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
:dependencies
devDependencies
peerDependencies
optionalDependencies
pnpm-workspace.yaml
:overrides
catalog:
协议允许在冒号后面添加可选的名称(例如:catalog:name
)来指定应该使用哪个目录。当省略名称时,将使用默认目录。
根据具体场景,与直接编写版本范围相比,catalog:
协议提供了一些优势,下面将详细介绍。
优势
在工作空间(即 monorepo 或多包仓库)中,同一个依赖项经常被多个包使用。目录在编写 package.json
文件时可以减少重复,并提供以下好处:
- 维护唯一版本 — 在工作空间中通常希望一个依赖项只有一个版本。目录使这更容易维护。重复的依赖项可能在运行时发生冲突并导致 bug。在使用打包工具时,重复也会增加体积。
- 更容易升级 — 在升级依赖项时,只需要编辑
pnpm-workspace.yaml
中的目录条目,而不是编辑所有使用该依赖 项的package.json
文件。这节省了时间 — 只需要修改一行而不是多行。 - 更少的合并冲突 — 由于升级依赖项时不需要编辑
package.json
文件,这些文件中不再会出现 git 合并冲突。
定义目录
目录在 pnpm-workspace.yaml
文件中定义。有两种方式定义目录。
- 使用(单数)
catalog
字段创建一个名为default
的目录。 - 使用(复数)
catalogs
字段创建任意命名的目录。
如果你有一个现有的工作空间想要迁移到使用目录,你可以使用以下 codemod:
pnpx codemod pnpm/catalog
默认目录
顶层的 catalog
字段允许用户定义一个名为 default
的目录。
catalog:
react: ^18.2.0
react-dom: ^18.2.0
这些版本范围可以通过 catalog:default
引用。仅对于默认目录,也可以使用特殊的 catalog:
简写方式。可以把 catalog:
看作是 catalog:default
的简写形式。
命名目录
可以在 catalogs
键下配置多个任意命名的目录。
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
发布
在运行 pnpm publish
或 pnpm pack
时,catalog:
协议会被移除。这类似于 workspace:
协议,它在发布时也会被替换。
例如,
{
"name": "@example/components",
"dependencies": {
"react": "catalog:react18",
}
}
在发布时会变成:
{
"name": "@example/components",
"dependencies": {
"react": "^18.3.1",
}
}
catalog:
协议的替换过程使得 @example/components
包可以被其他工作空间或包管理器使用。
注意事项
pnpm update
命令目前还不支持目录。
在 pnpm 的未来版本支持之前,需要手动为 pnpm-workspace.yaml
中定义的依赖项选择更新的版本范围。