依赖解析设置

overrides#

此字段允许你指示 pnpm 覆盖依赖关系图中的任何依赖项,包括对等依赖项。这对于强制所有软件包使用一个依赖项的单个版本、反向移植一个修复、用分叉替换依赖项或删除未使用的依赖项很有用。

The overrides field can only be set at the root of the project.

overrides 字段的示例:

pnpm-workspace.yaml
overrides:
  "foo": "^1.0.0"
  "quux": "npm:@myorg/quux@^1.0.0"
  "bar@^2.1.0": "3.0.0"
  "qar@1>zoo": "2"

你可以用 ">" 来覆盖某个包下的子依赖的版本,比如 qar@1>zoo 只会覆盖 qar@1 依赖的 zoo 的版本,而不会影响其他依赖。

若要保持被覆盖的版本与工作区其他位置使用的版本同步,请在 catalog 中定义该版本,并使用 catalog: 协议进行引用。这样一来,版本号便统一维护于一处,并同时被你的依赖项和覆盖项引用:

pnpm-workspace.yaml
catalog:
  foo: "^1.0.0"

overrides:
  foo: "catalog:"

你也可以使用 catalog:<name> 引用已命名的目录。有关更多详细信息,请参阅 Catalogs。

如果你发现你使用某个包不需要它的依赖之一,你可以使用 - 来删除它。例如,如果软件包 foo@1.0.0 需要一个名为 bar 的大型软件包来实现你不使用的功能,删除它可以减少安装时间:

pnpm-workspace.yaml
overrides:
  "foo@1.0.0>bar": "-"

此功能对于 optionalDependencies 特别有用,其中大多数可选包可以被安全地跳过。

合并覆盖#

新增于:v11.13.0

A selector with an empty range, "pkg@", is a convergence override. 与无条件重写所有匹配边的常规覆盖不同,收敛覆盖仅在依赖边的版本满足该边所声明的版本范围时,才会重写该依赖边:

pnpm-workspace.yaml
overrides:
  "form-data@": 4.0.6

基于上述配置,声明 form-data: "^4.0.5" 的依赖会被锁定在 4.0.6 版本,而声明 ^3.0.0 的依赖则保持其原有的解析结果。 This lets compatible consumers converge on a single version, now and for any dependent added in the future, without forcing an incompatible version on the rest of the graph.

规则:

  • 该数值必须是精确的版本。使用版本范围、dist-tag 或 - 移除操作时,会因 ERR_PNPM_INVALID_CONVERGENCE_OVERRIDE 错误而失败。只要 catalog: 引用能解析为确切版本,该引用就是允许的。
  • 仅涉及普通的语义化版本依赖关系。对于声明为 workspace:、catalog:、npm:、dist-tag 或 git/URL 格式的依赖,由于不存在有意义的“满足”关系,它们将保持原样,不予处理。
  • 收敛覆盖不能与父选择器组合使用:"parent>pkg@" 被拒绝。
  • 常规覆盖总是优先于同一边缘的收敛覆盖。

当完整解析发现每个声明的范围都允许使用更高版本时,pnpm 会警告该覆盖已过期,并指明建议收敛到的版本。

注意

在 v11.13.0 版本之前,覆盖选择器中的空范围属于未公开文档的行为,且其表现与无范围限制(未指定范围)的覆盖相同。

覆盖对等依赖项#

覆盖规则也适用于 peerDependencies。该行为取决于覆盖中使用的版本说明符类型:

  • 语义版本范围(例如,^1.0.0)、工作区和目录协议:对等依赖项被覆盖,并且仍然是对等依赖项。
  • 非范围指定符如“link:”或“file:”协议:对等依赖被覆盖并移至“依赖”,因为这些不是有效的对等依赖范围。
  • 移除(-):完全移除对等依赖项。

例如,要覆盖 react-dom 的 react 对等依赖项:

pnpm-workspace.yaml
overrides:
  "react-dom>react": "18.1.0"

packageExtensions#

packageExtension 字段提供了一种用额外信息扩展现有软件包定义的方法。例如,如果 react-redux 本应该在它的 peerDependencies 中包含 react-dom 但它没有,则可以用 packageExtensions 来填补上 react-redux。

pnpm-workspace.yaml
packageExtensions:
  react-redux:
    peerDependencies:
      react-dom: "*"

packageExtensions 中的键是包名或包名和 semver 范围,因此可以只修补包的某些版本:

pnpm-workspace.yaml
packageExtensions:
  react-redux@1:
    peerDependencies:
      react-dom: "*"

以下字段可以使用 packageExtensions 进行扩展: dependencies、optionalDependencies、peerDependencies 和 peerDependenciesMeta。

一个更大的例子:

pnpm-workspace.yaml
packageExtensions:
  express@1:
    optionalDependencies:
      typescript: "2"
  fork-ts-checker-webpack-plugin:
    dependencies:
      "@babel/core": "1"
    peerDependencies:
      eslint: ">= 6"
    peerDependenciesMeta:
      eslint:
        optional: true

提示

我们与 Yarn 一起维护一个 packageExtensions 的数据库,以便修补在生态系统中损坏的包。如果你使用 packageExtensions, 考虑发送一个 PR 上游并将你的扩展贡献给 [@yarnpkg/extension] 数据库。

allowedDeprecatedVersions#

此项设置允许忽略特定依赖包的 deprecation 警告。

示例:

pnpm-workspace.yaml
allowedDeprecatedVersions:
  express: "1"
  request: "*"

使用上述配置,pnpm 将不会打印 request 任何版本和 express v1 版本的弃用警告。

update#

添加于:v11.16.0

本节中的设置用于调节pnpm update 和 pnpm outdated 命令。

update.ignoreDeps#

有时您无法更新依赖项。例如,最新版本的依赖项开始使用 ESM,但您的项目尚未采用 ESM。 Annoyingly, such a package will always be printed out by the pnpm outdated command and updated, when running pnpm update --latest. 不过,你可以在“ignoreDeps”字段列出你不想升级的包:

pnpm-workspace.yaml
update:
  ignoreDeps:
  - load-json-file

模式匹配也是支持的,因此你可以忽略在特定范围内的任何包: @babel/*。

The ignored packages still update when you name them, as in pnpm update load-json-file. They stay unchanged when every selector is negated, as in pnpm update '!webpack'.

update.changeset#

添加于:v11.16.0

  • 默认值: false
  • 类型:Boolean

当设为 true 时,pnpm update 会在更新工作区清单后写入一条变更意图,为其 dependencies 或 optionalDependencies 被该更新更改的每个工作区包声明 patch 版本提升,并在其 peerDependencies 发生变化时声明 major 提升。等同于传入 --changeset;若要为单次运行覆盖该设置,请传入 --no-changeset。

update.githubActions#

添加于:v11.16.0

  • 默认值: false
  • 类型:Boolean

当设为 true 时,pnpm update 和 pnpm outdated 也会检查仓库工作流文件所引用的 GitHub Actions。等同于传入 --include-github-actions。参见更新 GitHub Actions。

update.githubActionsServer#

添加于:v11.17.0

托管工作流文件所引用的 GitHub Actions 仓库的 GitHub 服务器的基础 URL(例如 GitHub Enterprise Server)。该 URL 必须使用 https:// 或 http:// 协议。仅在可信网络中的可信服务器上使用 http://:用于将 action 固定到提交哈希的 ref 会通过此 URL 获取,而未加密的流量可能被篡改。

提示

在 v11.16.0 之前,update.ignoreDeps 名为 updateConfig.ignoreDependencies。已废弃的 updateConfig 设置在下一个主版本之前仍可工作;当两者都设置时,update 部分优先,并会打印警告。

支持的架构#

你可以指定要安装的可选依赖项的架构,即使它们与运行安装的系统的架构不匹配。

例如,以下配置指示安装 Windows x64 的可选依赖项:

pnpm-workspace.yaml
supportedArchitectures:
  os:
  - win32
  cpu:
  - x64

而此配置将为 Windows、macOS 以及当前正在运行安装的系统架构安装可选依赖项。它包括 x64 和 arm64 CPU 的工件:

pnpm-workspace.yaml
supportedArchitectures:
  os:
  - win32
  - darwin
  - current
  cpu:
  - x64
  - arm64

另外, supportedArchitectures 还支持指定系统的 libc。

注意

Copying node_modules between platforms can cause native-module load errors, such as invalid ELF header or not a valid Win32 application. For packages that publish platform-specific optional dependencies, list the target operating systems, CPUs, and C libraries in supportedArchitectures before installing. The lockfile can contain separate entries for each platform variant.

This setting does not cross-compile native addons. If a package builds its addon in an install script, install or rebuild it on the target platform.

optional#

  • 默认值:true
  • 类型:Boolean

Set to false to skip optional dependencies during installation, including transitive optional dependencies. Equivalent to pnpm install --no-optional.

ignoredOptionalDependencies#

如果可选依赖项的名称包含在此数组中,则会跳过它。例如:

pnpm-workspace.yaml
ignoredOptionalDependencies:
- fsevents
- "@esbuild/*"

forceIgnoresPlatform#

Added in: v11.28.0

  • 默认值:true
  • 类型:Boolean

Controls whether pnpm install --force installs optional dependencies that do not match the host platform. When true, --force installs every optional dependency, whatever its os, cpu, or libc fields say. When false, --force still refetches packages and lifts engineStrict, but skips optional dependencies built for other platforms, the same way a regular install does:

pnpm-workspace.yaml
forceIgnoresPlatform: false

To install optional dependencies for specific other platforms, use supportedArchitectures instead.

minimumReleaseAge#

添加于:v10.16.0

  • 默认值:1440(自 v11 版本起),0(v11 版本之前)
  • 类型:number (分钟)

To reduce the risk of installing compromised or defective packages, you can delay the installation of newly published versions. 大多数情况下,恶意发布会在一小时内被发现并从注册源中删除。

minimumReleaseAge 设置定义了版本发布后 pnpm 安装之前必须经过的最少分钟数。这适用于所有依赖项,包括传递依赖项。 It does not apply to a config dependency pinned with version+integrity.

例如,以下设置确保只能安装至少一天前发布的软件包:

pnpm-workspace.yaml
minimumReleaseAge: 1440

minimumReleaseAgeExclude#

添加于:v10.16.0

  • 默认值:undefined
  • 类型:string[]

如果你设置了 minimumReleaseAge,但需要某些依赖项始终立即安装最新版本,则可以在 minimumReleaseAgeExclude 列出它们。排除由 软件包名称 起作用,适用于该软件包的所有版本。

示例:

pnpm-workspace.yaml
minimumReleaseAge: 1440
minimumReleaseAgeExclude:
- webpack
- react

在这种情况下,所有依赖项必须至少存在一天,除了 webpack 和 react,它们在发布时立即安装。

添加于: v10.17.0

你也可以使用模式。例如,允许你组织中的所有包:

pnpm-workspace.yaml
minimumReleaseAge: 1440
minimumReleaseAgeExclude:
- '@myorg/*'

添加于:v10.19.0

你也可以排除特定版本(或使用 || 的特定版本列表)。这允许固定对到期时间规则的例外:

pnpm-workspace.yaml
minimumReleaseAge: 1440
minimumReleaseAgeExclude:
- nx@21.6.5
- webpack@4.47.0 || 5.102.1

minimumReleaseAgeExcludePrune#

添加于:v11.22.0

  • 默认值: false
  • 类型:Boolean

当设为 true 时,pnpm add、pnpm update 和 pnpm remove 会清理 pnpm-workspace.yaml 中 minimumReleaseAgeExclude 里新写入的锁文件不再解析的条目:已消失的版本会被移除(当某个条目的任何版本都不再存在时即删除该条目),而锁文件中已不存在的包的条目也会被移除。名称模式(@myorg/*)始终会保留。 Pruning also checks resolved configuration dependencies and their transitive dependencies.

当本次安装的锁文件未覆盖整个工作区(sharedWorkspaceLockfile: false)时会跳过清理,因为其他项目仍需要的条目会被误认为过期。

minimumReleaseAgeIgnoreMissingTime#

添加于:v11.0.0

  • 默认值:true
  • 类型:Boolean

当 true 时,pnpm 会跳过对注册源元数据中不包含 time 字段的软件包的 minimumReleaseAge 检查(一些私有注册源和镜像会省略它)。设置为 false 则在这种情况下解析失败,而不是安装软件包。

pnpm-workspace.yaml
minimumReleaseAgeIgnoreMissingTime: false

Since v11.23.0, the setting also governs trustPolicy, which reads the same publish dates: trustPolicy: no-downgrade skips a package the registry cannot date, with a warning, rather than failing the install with ERR_PNPM_MISSING_TIME.

The opt-in covers a registry that cannot date its releases, not a package a registry says it never published: during lockfile verification, a lockfile entry missing from a packument that does date every version it lists remains a hard failure.

minimumReleaseAgeStrict#

添加于:v11.0.0

  • 默认值:如果minimumReleaseAge 被明确配置则true ,否则为 false
  • 类型:Boolean

控制当依赖项在请求的范围内没有满足 minimumReleaseAge 约束的版本时 pnpm 的行为。当为 false 时,pnpm 会回退到不满足 minimumReleaseAge 约束的版本,以便安装仍然可以成功。当为 true 时,pnpm 解析失败。

默认值取决于你是否自行配置了 minimumReleaseAge:如果你显式地设置了它(通过 pnpm-workspace.yaml、CLI 或环境变量),则默认情况下会启用严格模式,因此该设置会被强制执行。内置默认值 minimumReleaseAge(1440 分钟)并非严格限制,而是向后兼容。

pnpm-workspace.yaml
minimumReleaseAgeStrict: true

trustPolicy#

添加于:v10.21.0

  • 默认: off
  • 类型:no-downgrade | off

当设置为 no-downgrade 时,如果软件包的信任级别与以前的版本相比有所下降,pnpm 将失败。例如,如果一个软件包之前是由受信任的发布者发布的,但现在只有来源信息而没有信任证明,则安装将会失败。这有助于防止安装可能已被入侵的版本。信任检查仅基于发布日期,而非语义版本控制。如果先前发布的版本具有更强的可信度证据,则无法安装该软件包。从 v10.24.0 开始,在评估非预发布版本安装的信任证据时,预发布版本将被忽略,因此受信任的预发布版本不能阻止缺少信任证据的稳定版本。

The check also covers the pnpm version a project pins in packageManager or devEngines.packageManager. pnpm fails before it switches to that version or records it in the lockfile.

trustPolicyExclude#

添加于: v10.22.0

  • 默认值:[]
  • 类型:string[]

一份应排除在信任策略检查之外的包选择器列表。这样,即使特定的软件包或版本不满足 trustPolicy 要求,你也可以安装它们。

例如:

pnpm-workspace.yaml
trustPolicy: no-downgrade
trustPolicyExclude:
  - 'chokidar@4.0.3'
  - 'webpack@4.47.0 || 5.102.1'
  - '@babel/core@7.28.5'

trustPolicyIgnoreAfter#

添加于:v10.27.0

  • 默认值:undefined
  • 类型:number (分钟)

允许忽略发布时间超过指定分钟数的软件包的信任策略检查。这在启用严格的信任策略时非常有用,因为它允许安装旧版本的软件包(可能缺少带有签名或来源的发布流程),而无需手动排除,假设它们由于年代久远而安全。

trustPolicyExcludePrune#

Added in: v11.27.0

  • 默认值: false
  • 类型:Boolean

When set to true, pnpm add, pnpm update, and pnpm remove prune the entries of trustPolicyExclude in pnpm-workspace.yaml that the freshly written lockfile no longer resolves: a version that is gone is dropped (an entry is removed once none of its versions remain), and an entry for a package that is no longer in the lockfile is removed too. 名称模式(@myorg/*)始终保持不变。 Pruning also checks resolved configuration dependencies and their transitive dependencies.

当本次安装的锁文件未覆盖整个工作区(sharedWorkspaceLockfile: false)时会跳过清理,因为其他项目仍需要的条目会被视为过期。

trustLockfile#

添加于:v11.3.0

  • 默认值: false
  • 类型:Boolean

为 true 时,pnpm install 会跳过供应链验证步骤;该步骤通常会对已加载的 lockfile 中的每一项重新应用 minimumReleaseAge 和 trustPolicy 规则。安装过程将锁文件视为已受信任。

Useful in environments where the lockfile is effectively part of the trusted base: closed-source projects where every commit comes from a trusted author. “受污染”的锁文件(即贡献者在比 CI 强制执行的策略更宽松的条件下生成的锁文件)可能会漏检,因此,只要外部协作者能够编辑该锁文件,就应将此项设置为 false。

在大型工作区中,验证阶段会在安装期间将各包的注册源元数据保留在内存中;禁用该阶段可降低内存占用,但会牺牲供应链检查功能。对于大多数采用默认 frozenLockfile CI 工作流的项目,无需设置此项。

blockExoticSubdeps#

添加于:v10.26.0

  • 默认值:true
  • 类型:Boolean

设置为“true”时,只有直接依赖项(在根目录 package.json 中列出的依赖项)才能使用特殊来源(例如 git 仓库或直接 tarball URL)。所有传递依赖项都必须从受信任的来源解析,例如配置的注册表、本地文件路径、工作区链接或受信任的 GitHub 存储库(node、bun、deno)。

此设置有助于保护依赖项供应链,防止传递依赖项从不受信任的位置引入代码。

异域资源包括:

  • Git 仓库(git+ssh://...)
  • 直接链接到 tar 包(https://.../package.tgz)

registries#

添加于:v11.0.0

  • 默认值:undefined
  • 类型:Record<string, RegistryDeclaration> 或 Record<string, string>

声明项目从中安装的注册源。自 v11.23.0 起,每个注册源只需声明一次,并以它的 URL 为键,条目中包含了 pnpm 对该注册源的全部了解:路由到它的 scopes、它响应的裸说明符 prefix,以及服务器如何组织 tarball URL(serverType、supportsTimeField)。各字段的完整说明见专门的注册源页面。

pnpm-workspace.yaml
registries:
  https://npm.corp.example.com/:
    serverType: artifactory
    scopes: ["@my-org", "@internal"]
    prefix: work

将作用域映射到 URL 的旧结构仍然被接受。 default 键设置主注册源(等同于 .npmrc 中的 registry 设置),而带作用域的键则为特定包作用域配置注册源:

pnpm-workspace.yaml
registries:
  default: https://registry.npmjs.org/
  "@my-org": https://private.example.com/
  "@internal": https://nexus.corp.com/

两种结构不能混用在同一个映射中。

自 v11.11.0 起,该设置也可以定义在全局配置文件(config.yaml)中,这适用于应当对机器上每个项目生效、而不是仅对单个仓库生效的注册源。 Only the routes (scopes and prefix) are read from there; serverType and supportsTimeField shape the lockfile, so they are read only from pnpm-workspace.yaml. See where the setting may live.

namedRegistries#

添加于:v11.1.0

  • 默认值:undefined
  • 类型:** Record <string, string>**

注意

Deprecated since v11.23.0: declare a prefix in registries instead. See the Registries page. namedRegistries 仍会被读取,但仅用于 registries 未声明的前缀;当两个设置都声明了前缀时,pnpm 会发出警告。 Everything below about aliases (the built-in ones, reserved names, and the lockfile keys) applies to prefix-declared aliases the same way.

定义命名的注册源别名,在安装包时可以用作前缀,以 vlt 的命名注册源别名的风格。例如,使用以下配置:

pnpm-workspace.yaml
namedRegistries:
  gh: https://npm.pkg.github.example.com/
  work: https://npm.work.example.com/

pnpm add work:@corp/lib@^2.0.0 将 @corp/lib@^2.0.0 解析为 https://npm.work.example.com/。

身份验证信息来自现有的每个 URL 的 .npmrc 条目(例如 //npm.pkg.github.com/:_authToken=...),因此不需要单独的身份验证机制。

自 v11.11.0 起,该设置也可以定义在全局配置文件(config.yaml)中,因此像 work: 这样的别名可以在机器上的所有项目之间共享。

内置别名#

两个别名无需任何配置即可使用:

别名 注册源 备注
gh: https://npm.pkg.github.com/ GitHub Packages npm 注册源。
npmjs: https://registry.npmjs.org/ 公共 npm 注册源。添加于 v11.20.0。

Entries you define under namedRegistries are merged on top of these, so either one can be overridden. GitHub Enterprise Server users point gh at their own host, and an organization that mirrors or proxies npmjs should point npmjs at the mirror:

pnpm-workspace.yaml
namedRegistries:
  gh: https://npm.pkg.github.example.com/
  npmjs: https://npm.internal.example.com/

即使默认的 registry 指向别处,例如内部代理,npmjs: 也会把依赖固定到公共注册源:

package.json
{
  "dependencies": {
    "left-pad": "npmjs:^1.3.0"
  }
}

The npm: prefix cannot do this. It is the alias protocol (npm:<name>@<range>) and resolves through whatever registry points at.

当 pnpm 校验包时,内置 URL 也是用于匹配锁文件中记录的 tarball URL 的前缀。如果你代理 npmjs 而未覆盖该别名,则 tarball URL 位于 registry.npmjs.org 的条目将针对公共注册源而非你的镜像进行校验。 This only affects lockfiles that record such a URL (a canonical URL for your configured registry is omitted from the lockfile), and only when a tarball-URL, minimumReleaseAge, or trustPolicy check runs.

保留的别名名称#

自 v11.20.0 起,会遮蔽保留的依赖说明符前缀(file、link、workspace、runtime、npm、jsr、git、github、gitlab、bitbucket、catalog、custom、http、https、ssh)的别名会被以 ERR_PNPM_RESERVED_NAMED_REGISTRY_NAME 拒绝。此前此类别名会被相应的解析器静默遮蔽。别名还必须以字母开头,并且只能包含字母、数字、.、_ 和 -。

锁文件中的命名注册源#

自 v11.20.0 起,从命名注册源解析的包会以带注册源限定的键记录在 pnpm-lock.yaml 中,即 <name>@<registryName>:<version>:

pnpm-lock.yaml
packages:
  foo@work:1.0.0:
    resolution: {integrity: sha512-...}

在 v11.20.0 之前,包仅以 name@version 为键,因此同名同版本由两个注册源提供时会合并到同一个条目,先解析到的那一个决定了所有使用者获得的 tarball。这是一种包替换风险:你期望来自私有注册源的包,可能从另一个发布了相同名称和版本的注册源安装,而锁文件中没有任何信息会揭示这一点。带注册源限定的键让每个注册源都有各自的条目,并固定依赖来自哪一个注册源。

The lockfile format version is unchanged, and qualified keys appear only for packages resolved from a named registry, including the built-in gh: and npmjs: aliases, which need no namedRegistries entry. Most packages from the default registry keep plain keys, as described below. A project that declares no prefix and installs nothing through an alias sees no difference, and older pnpm versions keep reading the file.

The key names the registry a package resolved from, not the way its dependency was written. A registry that declares a prefix, through prefix in registries or through namedRegistries, keys every package resolved from it with that prefix: one written as work:^1.0.0 and one written as a plain range whose scope registries routes to that URL. A plain range and a prefixed specifier that reach one registry therefore share one packages: entry and one copy in node_modules/.pnpm, so a published package that depends on @work/util by a plain range shares the copy your project installs through work:. The built-in gh: and npmjs: aliases qualify only the specifiers that spell them, unless you declare that prefix yourself. The same name and version served by two registries still get two entries.

Packages from the default registry, the one the registry setting names, keep plain keys. That includes packages installed through a prefix that points at the default registry, such as npmjs pointed at the npm mirror your registry setting uses. A plain range and such a prefixed specifier share the plain entry. The exception is a package whose scope registries routes to another registry: npmjs:@work/util is keyed @work/util@npmjs:<version> when @work routes elsewhere.

When several prefixes declare one registry, its packages are keyed by the lexicographically smallest prefix, so work:^1.0.0 and zeta:^1.0.0 pointing at one URL record foo@work:1.0.0. The specifier in package.json is left as written.

注意

如果有任何依赖是通过别名安装的,你在 v11.20.0 或更新版本上的第一次非冻结安装会重新为这些条目生成键,这会体现为锁文件差异。 Commit it. That diff is the fix being applied. 同时也要审查它:若某个条目迁移到了你未预料的注册源,值得进一步调查。

The same applies when a scope you route reaches a registry that also declares a prefix: the next pnpm install moves the scope-routed entries under the prefix and merges them with the prefixed ones. A frozen install keeps installing the lockfile as recorded.

请先让参与该项目的所有人都升级到 v11.20.0 或更新版本。旧版 pnpm 可以正常读取重写键后的锁文件,冻结安装不受影响,然而它自身不会产出带注册源限定的键:任何会更新锁文件的安装都会把这些条目写回旧结构,而当前版本 pnpm 上的下一次安装又会重新为其加上限定。于是锁文件会反复翻转,而当它停留在旧结构时,项目便会再次处于暴露状态。因为锁文件格式版本有意保持不变,pnpm 无法识别这种情况,也无法提醒你。

There is no setting to keep the old behavior. The old shape is the vulnerability.

A plain key records no registry, so pnpm remembers in the workspace state (node_modules/.pnpm-workspace-state-v1.json) which registry each scope routed to when it last resolved the lockfile. When you route a scope to another registry, the next pnpm install resolves that scope's packages and their dependencies again from the new registry, at the locked versions it serves, and picks another version in range for a locked version it does not serve. A frozen install keeps installing the lockfile as recorded. Without that record, as in a fresh clone, pnpm reads the plain keys as resolved from the registries configured now. Only scope routes are tracked this way: changing the default registry, which is routinely a switch between mirrors, does not resolve anything again.

Every non-built-in alias that the lockfile references must stay declared, through prefix in registries or through namedRegistries. 若条目的别名已被移除,读取会以 ERR_PNPM_MISSING_NAMED_REGISTRY 失败,而不会回退到默认注册源,因为那会取到另一个包。重命名别名时,会重新解析曾使用该别名的包。

对于命名注册源包,遵循标准注册源布局的 tarball URL 不再写入锁文件;它们会按需从别名所声明的 URL 重新计算。

pnprServer#

  • 默认值: null
  • 类型:字符串

URL of a pnpr server.

When set, pnpm install offloads dependency resolution to the remote pnpr server. pnpm sends its workspace manifests and registry configuration to the server, and the server resolves the dependency graph against those registries, streaming back resolved package metadata frames as it walks the graph so pnpm can download tarballs in parallel. Once resolution finishes, the server returns the complete lockfile and pnpm links node_modules locally.

Public packages are fetched directly from their respective registries in parallel. Private packages configured through pnpr are fetched from its registry endpoint using server-side upstream credentials; client upstream registry credentials are not sent to the pnpr server.

pnpm-workspace.yaml
pnprServer: https://pnpr.example.com/

This can also be configured via the --config.pnprServer=<url> command-line option or the PNPM_CONFIG_PNPR_SERVER environment variable.

When pnprServer is set, authentication headers configured for the pnpr server URL in .npmrc (for example, //pnpr.example.com/:_authToken=...) are automatically sent to authenticate requests to the server.