跳到主内容

pnpm 11.2

· 一分钟阅读
Zoltan Kochan
pnpm 的首席维护者

pnpm 11.2 引入了实验性的选择加入 pacquet(pnpm 的 Rust 移植版)作为安装后端,扩展了 配置依赖项 以安装一层 optionalDependencies(因此 esbuild/swc 平台二进制模式也适用于配置依赖项),连接了文档中长期存在的 pnpm login --scope 标志,并在 pnpm outdatedpnpm update --interactive 中显示运行时入口(Node.js、Deno、Bun)。

次要更改

实验性:使用 pacquet 作为安装后端

现在,在 pnpm-workspace.yamlconfigDependencies 中添加 @pnpm/pacquet(pnpm 的 Rust 移植版),即可将 pnpm install 的清单化阶段委托给 pacquet 二进制文件。 pnpm 仍然负责依赖项解析;pacquet 只从新写入的锁文件中获取和导入。 这是 Rust 安装引擎的可选预览版——参见 #11723

要在项目中配置 pacquet,请运行:

pnpm add @pnpm/pacquet --config

你会看到 pnpm-workspace.yamlpnpm-lock.yaml 中需要提交的更改。 如果你在使用 pacquet 时遇到任何问题,请在你创建的 GitHub 议题中告知我们。

optionalDependencies 用于配置依赖项

配置依赖项 现在解析并安装由配置依赖项声明的一级 optionalDependencies,并在安装时应用 os / cpu / libc 平台过滤。 这解锁了 esbuild/swc 风格的模式,其中软件包通过 optionalDependencies 分发特定于平台的二进制文件——现在配置依赖项也可以这样做,并将匹配的二进制文件符号链接到全局虚拟存储中的它旁边,因此配置依赖项内部的 require('pkg-platform-arch') 可以正确解析。

环境锁文件会记录所有平台变体,而不管主机平台如何,因此它可以在不同机器之间保持可移植性。 配置依赖项的 optionalDependencies 中的每个条目都必须声明一个确切的版本——为了保持安装的可重现性,范围和标签将被拒绝。

pnpm login --scope

早已记录在案的 pnpm login --scope <scope> 标志现已实现。 作用域已规范化(如果缺少前导 @,则添加 @;忽略空白值),并且 @<scope>:registry=<registry> 映射与身份验证令牌一起写入 pnpm 身份验证文件。 后续安装的 @<scope>/* 软件包将路由到选定的注册源。 之前此记录标志出现错误,提示 Unknown option: 'scope'。 请参阅 #11716

outdatedupdate --interactive 中的运行时

pnpm outdatedpnpm update --interactive 现在报告 Node.js、Deno 和 Bun 运行时已作为项目依赖项安装(runtime: 说明符)。 以前这些都是静默地跳过的。

补丁更改

  • 修复了当从不同的当前工作目录调用 pnpm 时(例如从 CI 包装器或 monorepo 脚本调用 pnpm --dir <project> install),.npmrc 中的 cafile=<relative-path> 从错误的目录读取的问题。 现在路径是根据声明它的 .npmrc 目录来解析的,而不是根据 process.cwd()。 在此修复之前,安装程序在没有配置 CA 的情况下继续运行,用户只会看到针对私有注册源的 TLS 错误,而没有日志行与错误解析的路径关联 #11624
  • 修复了当在 .npmrc 中设置了 registry 并且 pnpm-workspace.yaml 没有提供 registries.default 时,config.registry 会附加尾部斜杠的问题。
  • 修复了全局添加/更新操作,使其能够处理 minimumReleaseAge 策略违规,而不是抛出内部解析器防护错误。
  • 修复了当锁文件被清理(例如通过 turbo prune --docker)时,使用 injectWorkspacePackages: true 会导致的两个崩溃:一个是当对等依赖变体的基础 packages: 条目已被删除时,其注入的快照遇到 Cannot use 'in' operator to search for 'directory' in undefined;另一个是在 prepare / postinstall 重新导入每个注入的工作区包之后,在 node_modules/.bin/<tool> 上出现 ERR_PNPM_ENOENT
  • 修复了 pnpm loginpnpm logout 忽略 pnpm-workspace.yaml 中的 registries.default 的问题 #10099
  • 修复了 minimumReleaseAge (publishedBy) 成熟度快捷方式,使其包含截止时间。 以前,modified 字段等于截止值的缩写元数据会脱离快速路径,并触发完整元数据重新获取(或者在不允许完整元数据时触发 MISSING_TIME 错误)。
  • 发布软件包时遵守 publishConfig.access

11.2.1

  • 在环境锁文件中,使用 optional: true 标记可选的配置依赖项子依赖项快照,以匹配 pnpm-lock.yaml 中其他地方记录可选依赖项的方式。 以前,通过配置依赖项的 optionalDependencies 拉取的平台特定子依赖项的快照会被写为空对象。
  • Fixed pickRegistryForPackage returning the wrong registry for an unscoped npm: alias under a scoped local name. A manifest entry like "@private/foo": "npm:lodash@^1" was routing the lodash fetch through registries["@private"], even though lodash is unscoped.
  • Don't print Installing config dependencies... when config dependencies are already installed and nothing needs to be fetched, re-linked, or removed.

11.2.2

  • When the install engine is delegated to pacquet via configDependencies, the user's CLI flags passed to pnpm install (e.g. --no-runtime, --prod, --dev, --no-optional, --node-linker, --cpu / --os / --libc, --offline, --prefer-offline) are now forwarded to pacquet's install subcommand verbatim. Previously pacquet was invoked with a fixed argument list, so flags like --no-runtime were silently dropped. Flag forwarding is gated on the command being install / i; add, update, and dedupe still don't forward (their flag surface doesn't line up with pacquet's install).
  • Fixed pnpm up (and pnpm add / pnpm remove) failing with pacquet_package_manager::outdated_lockfile when pacquet is declared in configDependencies. pnpm now passes --ignore-manifest-check to pacquet so its --frozen-lockfile check doesn't fire against the (pre-mutation) package.json pnpm hasn't written yet #11797.