其他包管理器

新增于:v12.0.0-rc.6(仅限 pnpm v12)

pnpm 安装其他软件包管理器,不仅仅是它自己:npm,Yarn Classic,Yarn Berry,Yarn 6 (yarnpkg/zpm) 和 Bun。 npm 发布的版本会通过可信的包管理器注册表解析并获取,并在该版本执行前根据 npm 的签名进行验证——同样的标准允许 pnpm 无需询问即可切换自身版本。 Yarn 6 和 Bun 则由各自的项目以平台存档的形式直接发布,通过发布者校验和进行固定。

在没有 Node.js 的机器上运行的 JavaScript 包管理器会运行一个托管的 LTS 运行时,因此不需要自行安装 Node.js。

有三个地方使用它:

每个包管理器来自#

包管理器提供来源
npm注册表中的 npm 软件包
Yarn Classic (<2)注册表中的 yarn 软件包
Yarn Berry (2 – 5)注册表中的 @yarnpkg/cli-dist 软件包
Yarn 6yarnpkg/zpm 发布存档
Bunoven-sh/bun 发布存档

注册表发布的版本与 pnpm 自己的引擎共享相同的解析、验证和安装流程。作为平台存档发布的版本通过发布者校验和固定,例如管理的运行时。

每个包管理器都会在 pnpm 主目录下生成各自的环境锁文件,因此一个包管理器的锁定配置绝不会覆盖另一个包管理器的配置。

声明一个项目的包管理器#

在 pnpm add 中指定一个包管理器会记录项目所使用的包管理器,而不是去安装同名的 npm 包:

pnpm add yarn@4

声明将被包管理器读取:

  • Yarn 是通过项目中的 packageManager 字段指定的,它只接受一个精确的版本。因此,所请求的依赖项会在写入前就被解析:pnpm add yarn@4 会生成 "packageManager": "yarn@4.18.0"。对于 Yarn Classic 版本(<2),它固定的构件是 npm 压缩包,其值也会携带压缩包的 +sha512.… 校验——"packageManager": "yarn@1.22.22+sha512.…"。
  • 每个其他包管理器都被记录到 devEngines.packageManager,用于指定版本范围。

两个字段只会保留一个:它们声明同样的包管理器。如果一个项目中两个字段的声明不一致,版本切换工具则会拒绝运行。

package.json
{
  "devEngines": {
    "packageManager": {
      "name": "npm",
      "version": "^11.0.0"
    }
  }
}

有两个内容故意不包含在其中:

  • pnpm 本身。 修改 pnpm 自身固定的版本会导致下一条命令切换正在运行的 CLI,这应当是 pnpm self-update 的任务,而非 add 命令的副作用。
  • 被过滤的选择。 项目使用什么包管理器是项目自身的声明,因此 pnpm add yarn --filter … 会以 ERR_PNPM_PACKAGE_MANAGER_IN_SELECTION 失败。在项目内部中运行该命令。

如果修饰符用于定位软件包而非请求特定发布版本,则会像普通依赖项一样安装它:

pnpm add yarn@npm:yarn@1.22.22
pnpm add yarn@yarnpkg/berry

除 pnpm 以外,包管理器解析的版本不会写入 pnpm-lock.yaml:它们会被分别锁定在 pnpm 主目录下的独立环境锁文件中。只有 pnpm 自身的固定版本会在项目的锁文件中记录,位于 packageManagerDependencies 下。

运行时#

pnpm add 为运行时以同样的规则处理:对于 node 或 deno 会在 engines.runtime 下记录它,就像显式的 node@runtime:22 拼写一样。

bun 同时是运行时和包管理器,并且包管理器会先响应:pnpm add bun 会将它声明为项目的包管理器。要将它添加为运行时,运行 pnpm add bun@runtime:1.3.0。

全局安装#

pnpm add -g yarn

会安装当前版本的 Yarn,而非 npm 上仅适用于 Classic 模式的 yarn 包;而执行 pnpm add -g node@22 或 pnpm add -g deno@2 命令时,会直接安装对应的 Node.js 或 Deno 发行版,而非用于下载这些发行版的包装类包。

一个全局安装的包管理器也会遵循项目固定的版本,一个全局安装的 Node.js 已经遵循 devEngines.runtime:如果项目中固定了一个版本,则会运行固定的版本,全局安装的版本是其余位置的回退。 pnpm 通过为包管理器添加一个 globalShims 条目记录这一点,除非你自行决定相关设置——显式设置一个包含 false 的条目会保留你的设置。

对于如何选定版本以及 pnpm 何时要求确认,请参阅项目感知的全局二进制。

在单个命令中运行#

pnx yarn@4 install
pnx npm@11 ci
pnx bun@1.3.0 install

参见运行包管理器或运行时。

准备一个 git 托管依赖#

一个必须先构建才能安装的 git 托管依赖会以它声明的包管理器准备,而不是宿主环境拥有的包管理器:

  • 它的 packageManager / devEngines.packageManager 固定版本会受尊重;
  • 如果版本锁定失败,生成的锁文件会标明所使用的包管理器;由 Yarn Classic 生成的 yarn.lock 文件将无法被 Yarn Berry 安装。 Yarn Berry 会在其生成的每个锁文件中加入 __metadata: 标记,且两种格式之间无法互相读取,因此究竟是哪种包管理器写入锁文件属于硬性约束,而非用户偏好选择。

当依赖固定某个版本,或主机无法满足依赖要求时,pnpm 会提供该包管理器——因此,通过 Yarn 构建的仓库现在能在仅有 pnpm 的主机上安装,而具备合适包管理器的主机则会继续使用它自己的包管理器。

对于来自 v11 的项目有什么变化#

命令v11v12
pnpm add yarn安装名为 yarn 的 npm 包记录项目的包管理器(该包仍可通过 pnpm add yarn@npm:yarn@1.22.22 访问)
pnpm add -g yarn安装 Yarn Classic安装当前版本的 Yarn
pnpm add -g node / pnpm add -g deno安装用于下载构建包的包装器包安装 Node.js 或 Deno 发行版
pnx node / pnx deno运行包装器包运行发行版
全局安装的软件包管理器总是全局副本遵循项目固定的版本(如果存在的话)