其他包管理器
新增于: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。
有三个地方使用它:
- git 托管依赖是用它声明的包管理器准备的,参见准备一个 git 托管依赖;
pnpm dlx(pnx) 为一个命令运行一个运行时;pnpm shim add链接一个命令,运行当前项目固定的版本。
每个包管理器来自#
| 包管理器 | 提供来源 |
|---|---|
| npm | 注册表中的 npm 软件包 |
Yarn Classic (<2) | 注册表中的 yarn 软件包 |
Yarn Berry (2 – 5) | 注册表中的 @yarnpkg/cli-dist 软件包 |
| Yarn 6 | yarnpkg/zpm 发布存档 |
| Bun | oven-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,用于指定版本范围。
两个字段只会保留一个:它们声明同样的包管理器。如果一个项目中两个字段的声明不一致,版本切换工具则会拒绝运行。
{
"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 的项目有什么变化#
| 命令 | v11 | v12 |
|---|---|---|
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 | 运行包装器包 | 运行发行版 |
| 全局安装的软件包管理器 | 总是全局副本 | 遵循项目固定的版本(如果存在的话) |