pnpm 11.3
pnpm 11.3 增加了对 npm 的分阶段发布 (pnpm stage) 的支持、新的 trustLockfile 设置,用于跳过已信任锁文件的供应链验证流程,以及 pnpm pkg、pnpm repo 和 pnpm 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:
trustLockfile: true
此版本还减少了验证过程本身的内存占用:每个(注册表,名称)的信任元数据缓存之前会保留完整的包文档——依赖图、脚本、README,以及每个版本的清单——用于整个安装。在大型工作区(启用 minimumReleaseAge + trustPolicy: no-downgrade 的约 4000 个锁文件条目)中,这可能会在堆内存限制为 2 GB 的 CI 运行器上导致 OOM。现在缓存仅存储信任检查实际读取的字段(time、每个版本的 _npmUser.trustedPublisher、dist.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 pkg、pnpm repo 和 pnpm 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 inpackage.json. -
pnpm repo— open the repository URL of a package in the browser. -
pnpm set-script(aliasss) — add or update an entry in thescriptsfield of the project manifest. Supportspackage.json,package.json5, andpackage.yamlformats.
--skip-manifest-obfuscation用于pack和publish
🌐 --skip-manifest-obfuscation for pack and publish
针对 pnpm pack 和 pnpm 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 dlxfailing withERR_PNPM_NO_IMPORTER_MANIFEST_FOUNDwhen the installed package's CAS slot is missing itspackage.json. Observed in the wild forpnpm dlx node@runtime:<version>when the GVS slot was populated without the synthesized manifest runtime archives need.dlxnow falls back to the scopeless package name when the slot's manifest is unreadable — for single-bin packages (the dlx common case, including everyruntime:spec) this matches whatmanifest.binwould have named. -
Fixed non-determinism in
pnpm dedupeandpnpm installwhen a dependency graph contains packages with transitive peer dependencies on each other (e.g.@aws-sdk/client-stsand@aws-sdk/client-sso-oidc) andauto-install-peersis enabled. The lockfile no longer flips between two equally-valid forms across consecutive runs. The root cause was thatresolveDependenciespushed onto itspkgAddresses/postponedResolutionsQueuearrays from insidePromise.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 orpnpm/test-git-fetch#sha) was silently dropped from the manifest update and frompendingBuilds. -
Fixed
pnpm add --configleaving orphan entries inpnpm-lock.env.yaml(the optional subdependencies of the previously resolved version of the updated config dependency).
