pnpm.overrides 覆盖依赖用法

231 阅读2分钟

pnpm.io/zh/settings…

1. 是什么?

pnpm.overrides 字段允许你在 依赖关系图中强制指定某个依赖的版本
它常用于以下场景:

  • 让所有包使用统一版本(避免多版本并存问题)
  • 强制回退或前移某个依赖(比如修复 bug 或安全漏洞)
  • 替换成 fork 版本
  • 删除或屏蔽某些未使用/有问题的依赖

2. 为什么需要它?

用来解决依赖冲突安全漏洞

一个常见的场景:你的项目直接依赖了库 A@1.0.0 和库 B@2.0.0

  • A@1.0.0 又依赖了 C@^1.0.0(最终安装了 C@1.1.0)。
  • B@2.0.0 又依赖了 C@^2.0.0(最终安装了 C@2.0.0)。

这本来没问题,包管理器可以处理这种情况。但如果 C@2.0.0 有一个严重的安全漏洞,而修复版本是 C@2.1.0。你希望整个项目都使用 C@2.1.0

然而,库 A 的作者还没有更新它的依赖声明(它仍然接受 C@^1.0.0,但不接受 C@^2.1.0)。这时,你可以使用 overrides 来强制让 A 也使用安全的 C@2.1.0

3. 配置位置

你可以在以下位置定义 overrides

  1. pnpm-workspace.yaml(适合 monorepo 管理多个包时统一配置)
  2. package.json 中的 pnpm.overrides 字段(适合单项目场景) 示例:
# pnpm-workspace.yaml
overrides:
  foo: "^1.0.0"
  bar: "3.0.0"
// package.json
{
  "pnpm": {
    "overrides": {
      "foo": "^1.0.0",
      "bar": "3.0.0"
    }
  }
}

4. 使用语法

配置格式非常灵活:

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

可以通过 $ 引用直接依赖的版本:

// package.json
{
  "dependencies": {
    "foo": "^1.0.0"
  }
}

// pnpm-workspace.yaml
overrides:
  foo: "$foo"   // 覆盖子依赖版本,使其与顶层 foo 保持一致

可以使用 "-" 语法 删除某个子依赖:

overrides:
  "foo>bar@2": "-" // 当 `foo``bar@2` 这个子依赖时,pnpm 会把它移除

4. 核心要点

  • 强制性:覆盖和锁定版本,无视子依赖的声明。
  • 解决冲突:统一依赖版本,解决因版本不一致导致的 bug 或安全问题。
  • 在项目层操作:只在最终的应用程序项目中使用,而不是在你要发布的包库中使用。