Files
2026-07-13 21:35:53 +08:00

4.3 KiB
Raw Permalink Blame History

name, description
name description
pnpm-peer-dependencies 处理 peer dependencies 的自动安装与解析规则

pnpm Peer Dependencies

pnpm 默认对 peer dependencies 的处理非常严格。它提供了多种配置选项,用于控制 peer dependencies 的解析方式和报告方式。

自动安装 Peer Dependencies

默认情况下,pnpm 会自动安装 peer dependencies

# .npmrc(自 pnpm v8 起默认为 true
auto-install-peers=true

启用后,pnpm 会根据最佳匹配版本自动添加缺失的 peer dependencies。

严格模式 Peer Dependencies

控制 peer dependency 问题是否导致报错:

# peer dependency 问题视为错误(默认:false)
strict-peer-dependencies=true

启用严格模式后,pnpm 会在以下情况报错:

  • Peer dependency 缺失
  • 已安装版本不满足要求的版本范围

Peer Dependency 规则

package.json 中配置 peer dependency 行为:

{
  "pnpm": {
    "peerDependencyRules": {
      "ignoreMissing": ["@babel/*", "eslint"],
      "allowedVersions": {
        "react": "17 || 18"
      },
      "allowAny": ["@types/*"]
    }
  }
}

ignoreMissing

忽略缺失 peer dependencies 的警告:

{
  "pnpm": {
    "peerDependencyRules": {
      "ignoreMissing": [
        "@babel/*",
        "eslint",
        "webpack"
      ]
    }
  }
}

支持的模式:

  • "react" —— 精确的包名
  • "@babel/*" —— 作用域下的所有包
  • "*" —— 所有包(不推荐)

allowedVersions

允许原本会触发警告的特定版本:

{
  "pnpm": {
    "peerDependencyRules": {
      "allowedVersions": {
        "react": "17 || 18",
        "webpack": "4 || 5",
        "@types/react": "*"
      }
    }
  }
}

allowAny

对指定的 peer dependencies 允许任意版本:

{
  "pnpm": {
    "peerDependencyRules": {
      "allowAny": ["@types/*", "eslint"]
    }
  }
}

通过 Hooks 添加 Peer Dependencies

使用 .pnpmfile.cjs 添加缺失的 peer dependencies

// .pnpmfile.cjs
function readPackage(pkg, context) {
  // 添加缺失的 peer dependency
  if (pkg.name === 'problematic-package') {
    pkg.peerDependencies = {
      ...pkg.peerDependencies,
      react: '*'
    }
  }
  return pkg
}

module.exports = {
  hooks: {
    readPackage
  }
}

Workspaces 中的 Peer Dependencies

Workspace 中的包可以满足 peer dependencies

// packages/app/package.json
{
  "dependencies": {
    "react": "^18.2.0",
    "@myorg/components": "workspace:^"
  }
}

// packages/components/package.json
{
  "peerDependencies": {
    "react": "^17.0.0 || ^18.0.0"
  }
}

Workspace 中的 app 提供了 react,满足了 components 的 peer dependency 要求。

常见场景

共享 React 的 Monorepo

# pnpm-workspace.yaml
catalog:
  react: ^18.2.0
  react-dom: ^18.2.0
// packages/ui/package.json
{
  "peerDependencies": {
    "react": "^18.0.0",
    "react-dom": "^18.0.0"
  }
}

// apps/web/package.json
{
  "dependencies": {
    "react": "catalog:",
    "react-dom": "catalog:",
    "@myorg/ui": "workspace:^"
  }
}

忽略 ESLint 插件警告

{
  "pnpm": {
    "peerDependencyRules": {
      "ignoreMissing": [
        "eslint",
        "@typescript-eslint/parser"
      ]
    }
  }
}

允许多个主版本

{
  "pnpm": {
    "peerDependencyRules": {
      "allowedVersions": {
        "webpack": "4 || 5",
        "postcss": "7 || 8"
      }
    }
  }
}

调试 Peer Dependencies

# 查看某个包的安装原因
pnpm why <package>

# 列出所有 peer dependency 警告
pnpm install --reporter=append-only 2>&1 | grep -i peer

# 查看依赖树
pnpm list --depth=Infinity

最佳实践

  1. 开启 auto-install-peers 以方便使用(pnpm v8+ 默认开启)

  2. 使用 peerDependencyRules,而不是忽略所有警告

  3. 记录已忽略的警告,说明为什么安全

  4. 在库中保持 peer deps 的版本范围宽松

    {
      "peerDependencies": {
        "react": "^17.0.0 || ^18.0.0"
      }
    }
    
  5. 如果你支持多个主版本,请使用不同的 peer 版本进行测试