解决 pnpm 版本与 package.jsonpackageManager 中的版本不一致

安装项目依赖遇到: ERR_PNPM_BAD_PM_VERSION  This project is configured to use v8.15.6 of pnpm. Your current pnpm is v9.1.3
你可以在项目 .npmrc 中这样配置

package-manager-strict=false

当然这只是临时解决方案,特意将此方案前置,若你需要更进一步的了解 corepack 可继续往下~

Corepack

https://nodejs.org/api/corepack.html

这是个实验性工具文档,请优先查看官方文档,以获得最新信息!

文档日期版本:

  • Node.js => v22.2.0
  • Corepack => v0.28.1

什么是 Corepack?

CorepackNode.js 的一个实验性工具,可以管理 package managers(包管理器)的版本,例如 npmyarnpnpm

Corepack 允许你在项目内指定所需的包管理器和版本,在使用时自动切换至指定版本。这样可以统一项目开发人员的包管理器和版本,减少因为包管理器版本不一致导致的各种问题。

使用 Corepack

完整体验 corepack,需要卸载全局安装的 pnpmyarn,或确保 which -a 返回的首选路径为 corepack

$ which -a pnpm
# /usr/local/bin/pnpm

卸载 pnpm

corepack enable [... name] - 启用 Corepack

Added in: v16.9.0Node 在该版本开始内置了 corepack,请确保你的 Node 版本大于等于 16.9.0

corepack enable
$ pnpm -v
# 9.1.3
$ yarn -v
# 1.22.22

启用后 corepack 会为 yarnpnpm 设置 shims(间接层),默认都为 latest(目前默认是 yarn 的 v1 版本),后续 corepack 靠此拦截。

corepack 默认没有为 npm 启用 shims,corepack 不会限制你使用 npm 的操作(例如 package.json 里的 packageManager)。
How does Corepack interact with npm?

目前支持的包管理器

Supported package managers

Package manager Binary names
Yarn yarn, yarnpkg
pnpm pnpm, pnpx

corepack use <name[@<version>]> - 在项目内指定包管理器

package.json

{
  "name": "corepack-project",
  "version": "0.0.0"
}

使用 corepack use

# 使用最新版本
$ corepack use pnpm
# or 使用 latest 8.x version
$ corepack use pnpm@8.x
# or
$ corepack use pnpm@8.9.0

执行该命令时会更改 package.jsonpackageManager 字段,并且执行安装命令(只要使用 use 都会,具体如何 install 看包管理器)。

直接使用包管理器安装

  1. package.json 中未指定 packageManager

    项目中未指定包管理器和版本时,corepack 将会使用当前执行命令的 “known good release” 版本,并在 package.json 中生成 packageManager 字段。

    pnpm -v
    # or ...
    pnpm install

    执行结果:package.json

    {
      "name": "corepack-project",
      "version": "0.0.0",
      "packageManager": "pnpm@9.1.3+sha512.7c2ea089e1a6af306409c4fc8c4f0897bdac32b772016196c469d9428f1fe2d5a21daf8ad6512762654ac645b5d9136bb210ec9a00afa8dbc4677843ba362ecd"
    }
  2. package.json 中指定了 packageManager

    {
      "name": "corepack-project",
      "version": "0.0.0",
      "packageManager": "pnpm@8.9.0"
    }

    执行结果:

    pnpm -v
    # 8.9.0

corepack install <-g,--global> [... name[@<version>]] - 更换全局包管理器版本

corepack install --global pnpm@latest
# or
corepack install --global pnpm@8.9.0

其他方式

该命令未在官方文档中找到,但当前版本仍可使用。

corepack prepare `<`packageManager>@`<`version> --activate
# or
corepack prepare pnpm@latest --activate

corepack disable [... name] - 禁用 Corepack 或禁用某个包管理器

禁用 corepack

corepack disable

禁用 pnpm

corepack disable pnpm
# result
pnpm -v
# command not found: pnpm

Node.js Corepack
Corepack
https://github.com/nodejs/corepack?tab=readme-ov-file#-corepack