Skip to main content

pnpm 11.3

· 6 min read
Zoltan Kochan
Lead maintainer of pnpm

pnpm 11.3 增加了对 npm 的分阶段发布 (pnpm stage) 的支持、新的 trustLockfile 设置,用于跳过已信任锁文件的供应链验证流程,以及 pnpm pkgpnpm repopnpm set-script 的原生实现。它还为 pack / publish 添加了 --skip-manifest-obfuscation 标志,并在大型工作区中减少了 minimumReleaseAge / trustPolicy 验证的内存占用。

🌐 pnpm 11.3 adds support for npm's staged publishing (pnpm stage), the new trustLockfile setting for skipping the supply-chain verification pass on already-trusted lockfiles, and native implementations of pnpm pkg, pnpm repo, and pnpm set-script. It also adds a --skip-manifest-obfuscation flag for pack / publish and cuts the memory footprint of minimumReleaseAge / trustPolicy verification on large workspaces.

小幅更改

🌐 Minor Changes

pnpm stage

一个新的 pnpm stage 命令将 npm 的 分阶段发布 工作流程带到了 pnpm。分阶段发布允许你发布一个在 npm install 中隐藏的版本,直到你明确批准它 —— 这对于验证发布产物、冒烟测试 CI 或协调多包发布非常有用。

🌐 A new pnpm stage command brings npm's staged publishing workflow to pnpm. Staged publishing lets you publish a version that's hidden from npm install until you explicitly approve it — useful for verifying release artifacts, smoke-testing CI, or coordinating multi-package releases.

可用的子命令有:

🌐 The available subcommands are:

pnpm stage publish    # publish a version into staging
pnpm stage list # list staged versions
pnpm stage view # view a staged version
pnpm stage approve # promote a staged version to the registry
pnpm stage reject # discard a staged version
pnpm stage download # download a staged tarball

trustLockfile

一个新的 trustLockfile 设置控制 pnpm install 是否对加载的锁文件中的每个条目重新应用 minimumReleaseAge / trustPolicy: 'no-downgrade' 检查。当 true 时,安装会将锁文件视为已信任并跳过验证过程——这对于每次提交都来自可信作者的闭源项目非常有用。默认值是 false,因此默认情况下验证保持开启。

🌐 A new trustLockfile setting controls whether pnpm install re-applies the minimumReleaseAge / trustPolicy: 'no-downgrade' checks to every entry in the loaded lockfile. When true, the install treats the lockfile as already-trusted and skips the verification pass — useful for closed-source projects where every commit comes from a trusted author. The default is false, so verification stays on by default.

将其设置在 pnpm-workspace.yaml

🌐 Set it in pnpm-workspace.yaml:

pnpm-workspace.yaml
trustLockfile: true

此版本还减少了验证过程本身的内存占用:每个(注册表,名称)的信任元数据缓存之前会保留完整的包文档——依赖图、脚本、README,以及每个版本的清单——用于整个安装。在大型工作区(启用 minimumReleaseAge + trustPolicy: no-downgrade 的约 4000 个锁文件条目)中,这可能会在堆内存限制为 2 GB 的 CI 运行器上导致 OOM。现在缓存仅存储信任检查实际读取的字段(time、每个版本的 _npmUser.trustedPublisherdist.attestations.provenance);简化元数据缓存同样预计仅包含包级的 modified 字段和当前列出的版本名称集合。修复 #11860

🌐 This release also cuts the memory footprint of the verification pass itself: the per-(registry, name) trust-meta cache previously retained the full packument — dependency graphs, scripts, README, and per-version manifests — for the entire install. On large workspaces (~4k lockfile entries with minimumReleaseAge + trustPolicy: no-downgrade enabled) this could OOM CI runners with a 2 GB heap cap. The cache now stores only the fields the trust check actually reads (time, per-version _npmUser.trustedPublisher, dist.attestations.provenance); the abbreviated-metadata cache is similarly projected to just the package-level modified field and the set of currently-listed version names. Fixes #11860.

本地 pnpm pkgpnpm repopnpm set-script

🌐 Native pnpm pkg, pnpm repo, and pnpm set-script

另外三个之前委托给 npm(或在没有 npm 时缺失)的命令现在已原生实现,遵循 npm 命令约定:

🌐 Three more commands that previously delegated to (or were missing without) npm are now implemented natively, following the npm command conventions:

  • pnpm pkg — get / set / delete fields in package.json.

  • pnpm repo — open the repository URL of a package in the browser.

  • pnpm set-script (alias ss) — add or update an entry in the scripts field of the project manifest. Supports package.json, package.json5, and package.yaml formats.

--skip-manifest-obfuscation用于packpublish

🌐 --skip-manifest-obfuscation for pack and publish

针对 pnpm packpnpm publish 的新的 --skip-manifest-obfuscation 标志会保留原有的 packageManager 字段,并在打包/发布的清单中发布生命周期脚本,而不是将其删除。特定于 pnpm 的 pnpm 字段仍然会被省略。

🌐 A new --skip-manifest-obfuscation flag for pnpm pack and pnpm publish keeps the original packageManager field and publish lifecycle scripts in the packed/published manifest instead of stripping them. The pnpm-specific pnpm field continues to be omitted.

补丁更改

🌐 Patch Changes

  • Fixed pnpm dlx failing with ERR_PNPM_NO_IMPORTER_MANIFEST_FOUND when the installed package's CAS slot is missing its package.json. Observed in the wild for pnpm dlx node@runtime:<version> when the GVS slot was populated without the synthesized manifest runtime archives need. dlx now falls back to the scopeless package name when the slot's manifest is unreadable — for single-bin packages (the dlx common case, including every runtime: spec) this matches what manifest.bin would have named.

  • Fixed non-determinism in pnpm dedupe and pnpm install when a dependency graph contains packages with transitive peer dependencies on each other (e.g. @aws-sdk/client-sts and @aws-sdk/client-sso-oidc) and auto-install-peers is enabled. The lockfile no longer flips between two equally-valid forms across consecutive runs. The root cause was that resolveDependencies pushed onto its pkgAddresses / postponedResolutionsQueue arrays from inside Promise.all-spawned callbacks, so completion-order timing leaked into the array order and downstream cyclic-peer suffix assignment. Fixes #8155.

  • Fixed a regression where pnpm add <github-shorthand> (and any other wanted-dependency whose alias can't be parsed from the user-supplied spec, e.g. tarball URLs or pnpm/test-git-fetch#sha) was silently dropped from the manifest update and from pendingBuilds.

  • Fixed pnpm add --config leaving orphan entries in pnpm-lock.env.yaml (the optional subdependencies of the previously resolved version of the updated config dependency).