◆

pnpm peerDependencyRules 配置忽略缺失警告

2023-02-02 01:370

peerDependencyRules

先说清楚 peerDependency 是什么。它表示「我需要宿主项目提供某个包,但我自己不装」。典型例子是 Vue 插件:插件必须和 Vue 配合工作,但如果插件自己把 Vue 装进依赖,项目里就会出现两份 Vue 实例,响应式系统、组件注册全乱掉。声明成 peerDependency 意味着让宿主项目提供那唯一的一份。

npm 和 yarn 对 peerDependency 缺失的态度比较宽松,npm 7 之前甚至默认不管。pnpm 严格得多,安装时会逐个检查每个依赖声明的 peer 是否被满足,缺了或者版本不匹配就打印警告。安装一个中等规模的项目,控制台刷出几十行 WARN Issues with peer dependencies found 是很常见的。

这些警告有真有假。真的比如你装了 eslint 插件却没装 eslint,那确实要补。假的占大多数——某个包声明了 peer 但实际代码路径根本用不到(比如只在某个可选功能里用),或者你的项目本来就不走那条路径。这时候警告纯属噪音,还会掩盖真正需要关注的问题。peerDependencyRules 就是用来消化这些噪音的。

ignoreMissing

pnpm 不会打印有关依赖列表中缺少对 peerDependency 的警告。

在 package.json 的 pnpm.peerDependencyRules.ignoreMissing 里列出包名,pnpm 就不再为这些包报「缺失 peer」的警告。支持用 * 做通配,按 scope 批量屏蔽:

如下配置当你

{
  "pnpm": {
    "peerDependencyRules": {
      "ignoreMissing": [
        "vue",
        "postcss",
        "typescript",
        "vite",
        "@types/node",
        "@babel/*",
        "@eslint/*"
      ]
    }
  }
}

注意这里配的是被缺失的那个包名,不是发出警告的包名。比如某个插件要求 peer vue 而你没装,就写 vue,不是写那个插件的名字。

ignoreMissing 只是不打印警告,它不改变任何实际安装行为——该缺的还是缺。所以用它之前得确认那个 peer 确实用不到,别把真问题盖掉了。判断办法是先补上依赖看功能有没有变化,或者查一下那个包的源码里 peer 用在哪条路径上。

allowedVersions

另一类警告是「peer 版本不匹配」:包要求 react@^17,项目装的是 18。多数情况下这是包的 peer 范围没及时更新,实际兼容。allowedVersions 用来放行这种情况:

{
  "pnpm": {
    "peerDependencyRules": {
      "allowedVersions": {
        "react": "18",
        "eslint": ">=8"
      }
    }
  }
}

新版 pnpm 还支持精确到某个包的规则,"某插件>react": "18" 表示只对这个插件放行 react 18,其他包照旧检查,比全局放行更精准。

allowAny

比 allowedVersions 更彻底,直接对某些包完全跳过版本检查:

{
  "pnpm": {
    "peerDependencyRules": {
      "allowAny": ["@babel/*", "vue"]
    }
  }
}

这三个配置的取舍是:先看警告说的是缺失还是版本不符,缺失用 ignoreMissing,版本不符优先用 allowedVersions 显式写清允许哪个版本,实在太多再考虑 allowAny。全用 allowAny 图省事等于关掉 pnpm 的检查,那还不如用 npm。

改完这些配置要重新 pnpm install 才生效,光改 package.json 不重新装是不会有变化的。在 monorepo 里这些配置只在根 package.json 上生效,写到子包里没用。

💬留言板0

还没有留言,来发表第一条吧~

PAGE LOAD / LIVEpnpm peerDependencyRules 配置忽略缺失警告加载中