Skip to main content
Version: 11.x

目录

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

目录协议(catalog:

🌐 The Catalog Protocol (catalog:)

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

🌐 Once a catalog is defined in pnpm-workspace.yaml,

pnpm-workspace.yaml
packages:
- packages/*

# Define a catalog of version ranges.
catalog:
react: ^18.3.1
redux: ^5.0.1

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

🌐 The catalog: protocol can be used instead of the version range itself.

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

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

🌐 This is equivalent to writing a version range (e.g. ^18.3.1) directly.

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

你可以在接下来的字段中使用 catalog: 协议:

🌐 You may use the catalog: protocol in the next fields:

  • package.json:
    • dependencies
    • devDependencies
    • peerDependencies
    • optionalDependencies
  • pnpm-workspace.yaml
    • overrides

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

🌐 The catalog: protocol allows an optional name after the colon (ex: catalog:name) to specify which catalog should be used. When a name is omitted, the default catalog is used.

根据具体情况,catalog: 协议相比直接编写版本范围具有一些优势,具体如下所述。

🌐 Depending on the scenario, the catalog: protocol offers a few advantages compared to writing version ranges directly that are detailed next.

优点

🌐 Advantages

在工作区(即单体仓库或多包仓库)中,许多包通常会使用相同的依赖。目录在编写 package.json 文件时可以减少重复,并在此过程中提供一些好处:

🌐 In a workspace (i.e. monorepo or multi-package repo) it's common for the same dependency to be used by many packages. Catalogs reduce duplication when authoring package.json files and provide a few benefits in doing so:

  • Maintain unique versions — It's usually desirable to have only one version of a dependency in a workspace. Catalogs make this easier to maintain. Duplicated dependencies can conflict at runtime and cause bugs. Duplicates also increase size when using a bundler.

  • Easier upgrades — When upgrading a dependency, only the catalog entry in pnpm-workspace.yaml needs to be edited rather than all package.json files using that dependency. This saves time — only one line needs to be changed instead of many.

  • Fewer merge conflicts — Since package.json files do not need to be edited when upgrading a dependency, git merge conflicts no longer happen in these files.

定义目录

🌐 Defining Catalogs

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

🌐 Catalogs are defined in the pnpm-workspace.yaml file. There are two ways to define catalogs.

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

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

🌐 If you have an existing workspace that you want to migrate to using catalogs, you can use the following codemod:

pnpx codemod pnpm/catalog

默认目录

🌐 Default Catalog

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

🌐 The top-level catalog field allows users to define a catalog named default.

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

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

🌐 These version ranges can be referenced through catalog:default. For the default catalog only, a special catalog: shorthand can also be used. Think of catalog: as a shorthand that expands to catalog:default.

命名目录

🌐 Named Catalogs

可以在 catalogs 键下配置多个具有任意选择名称的目录。

🌐 Multiple catalogs with arbitrarily chosen names can be configured under the catalogs key.

pnpm-workspace.yaml
catalogs:
# Can be referenced through "catalog:react17"
react17:
react: ^17.0.2
react-dom: ^17.0.2

# Can be referenced through "catalog:react18"
react18:
react: ^18.2.0
react-dom: ^18.2.0

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

🌐 A default catalog can be defined alongside multiple named catalogs. This might be useful in a large multi-package repo that's migrating to a newer version of a dependency piecemeal.

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

catalogs:
# Can be referenced through "catalog:react17"
react17:
react: ^17.0.2
react-dom: ^17.0.2

# Can be referenced through "catalog:react18"
react18:
react: ^18.2.0
react-dom: ^18.2.0

发布

🌐 Publishing

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

🌐 The catalog: protocol is removed when running pnpm publish or pnpm pack. This is similar to the workspace: protocol, which is also replaced on publish.

例如,

🌐 For example,

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

发布时将成为以下内容。

🌐 Will become the following on publish.

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

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

🌐 The catalog: protocol replacement process allows the @example/components package to be used by other workspaces or package managers.

设置

🌐 Settings

catalogMode

新增于:v10.12.1

🌐 Added in: v10.12.1

  • 默认:手动
  • 类型:手动严格偏好

控制在运行 pnpm add 时是否以及如何将依赖添加到默认目录。有三种模式:

🌐 Controls if and how dependencies are added to the default catalog, when running pnpm add. There are three modes:

  • strict - only allows dependency versions from the catalog. Adding a dependency outside the catalog's version range will cause an error.

  • prefer - prefers catalog versions, but will fall back to direct dependencies if no compatible version is found.

  • manual (default) - does not automatically add dependencies to the catalog.

cleanupUnusedCatalogs

新增于:v10.15.0

🌐 Added in: v10.15.0

  • 默认:
  • 类型:布尔

当设置为 true 时,pnpm 会在安装过程中移除未使用的目录条目。

🌐 When set to true, pnpm will remove unused catalog entries during installation.