Skip to main content

pnpm 11.8

· 7 min read
Zoltan Kochan
Lead maintainer of pnpm

pnpm 11.8 增加了安装的干运行预览、Node.js 包映射生成、更丰富的 SBOM 输出,pnpm view 默认为当前包,并且修复了 pnpm run --no-bail 的退出代码。它还包括一个配置依赖锁文件遍历修复以及许多安装/更新确定性修复。

🌐 pnpm 11.8 adds install dry-run previews, Node.js package map generation, richer SBOM output, pnpm view defaulting to the current package, and correct pnpm run --no-bail exit codes. It also includes a config-dependency lockfile traversal fix and many install/update determinism fixes.

小幅更改

🌐 Minor Changes

pnpm install --dry-run

pnpm install 现在支持 --dry-run。它会执行完整的依赖解析并报告真实安装会更改的内容,但不会写入任何内容到磁盘:没有锁文件、没有清单文件,也没有 node_modules 更新。

已完成的演练以代码 0 退出,与 npm install --dry-run 的预览行为相匹配 (#7340)。

🌐 A completed dry run exits with code 0, matching the preview behavior of npm install --dry-run (#7340).

Node.js 包映射

🌐 Node.js package maps

pnpm 现在在隔离和提升安装过程中生成 node_modules/.package-map.json。该映射描述了包应如何通过已安装的 node_modules 布局进行解析。

🌐 pnpm now generates node_modules/.package-map.json during isolated and hoisted installs. The map describes how packages should resolve through the installed node_modules layout.

新的 nodeExperimentalPackageMap 设置通过将 Node 的 --experimental-package-map 选项添加到 NODE_OPTIONS,将生成的映射注入到 pnpm 管理的 Node.js 脚本环境中。nodePackageMapType 设置在 standard 映射(仅显示声明的依赖)和 loose 映射(还映射通过已安装布局可访问的包)之间进行选择。

🌐 The new nodeExperimentalPackageMap setting injects the generated map into pnpm-managed Node.js script environments by adding Node's --experimental-package-map option to NODE_OPTIONS. The nodePackageMapType setting chooses between standard maps, which expose declared dependencies only, and loose maps, which also map packages reachable through the installed layout.

软件物料清单改进

🌐 SBOM improvements

pnpm sbom 现在可以使用 --out 将 SBOM 写入文件,使用 --split 为每个选定的工作区包生成一个 SBOM,并在 --filter 选择单个包时使用选定包的元数据作为根组件。

CycloneDX 输出现在将仅通过 devDependencies 可访问的组件标记为 scope: "excluded" 并具有 cdx:npm:package:development 属性。运行时组件,包括已安装的可选依赖,保持默认的必需范围。

🌐 CycloneDX output now marks components reachable only through devDependencies with scope: "excluded" and the cdx:npm:package:development property. Runtime components, including installed optional dependencies, keep the default required scope.

命令行接口行为

🌐 CLI behavior

pnpm run --no-bail 现在会继续运行每个匹配的脚本,但如果有任何脚本失败,将以非零代码退出。递归运行已经是这种行为;非递归运行现在与之匹配 (#8013)。

pnpm view 现在可以在没有包名的情况下运行。在这种情况下,它会向上搜索最近的项目清单并使用其 name 字段。

补丁更改

🌐 Patch Changes

  • Security: Validate config dependency names and versions from the env lockfile before using them to build filesystem paths. A committed lockfile can no longer use traversal-shaped configDependencies names or versions to write outside node_modules/.pnpm-config or the store. Names must be valid npm package names, and versions must be exact semver versions. See GHSA-qrv3-253h-g69c.

  • Fixed pnpm update overriding the version range policy of a named catalog whose name parses as a version, such as catalog:express4-21 (#10321).

  • Fixed link: workspace protocol dependencies switching to file: after pnpm rm when injectWorkspacePackages: true is set and the target workspace dependency has its own dependencies.

  • Stopped warning about matching packageManager and devEngines.packageManager values when both pin the same package manager, version, and integrity hash (#12028).

  • Fixed interactive progress output leaving characters behind when external processes write to the terminal, such as SSH passphrase prompts (#12350).

  • Fixed pnpm approve-builds missing packages whose build approval was revoked and then re-added (#12221).

  • Skipped the redundant Windows warning about an existing node.exe when it already matches the target (#12203).

  • Fixed macOS Gatekeeper blocking native binaries imported from the store by removing the com.apple.quarantine extended attribute from native binaries after import (#11056).

  • Fixed optimisticRepeatInstall incorrectly reporting "Already up to date" when only pnpm-lock.yaml changed, and fixed the same checks for git branch lockfiles (#12100).

  • Fixed recursive updates that mix transitive dependency patterns with direct dependency selectors, such as pnpm up -r "@babel/core" uuid (#12103).

  • Registered pnpm update --no-save in CLI help and option parsing.

  • Fixed pnpm import for Yarn v2 lockfiles when js-yaml v4 is installed.

  • Fixed repeated reinstall prompts when enableGlobalVirtualStore is enabled by keeping the virtual store directory recorded during post-install builds aligned with the install step (#12307).

  • Documented the --cpu, --os, and --libc flags in pnpm install --help (#12359).

  • Avoided reading README.md from disk during publish when the publish manifest already provides a readme field.

  • Fixed pnpm peers check rejecting loose peer dependency ranges that the installed peer satisfies (#12149).

  • Preserved workspace: dependencies that point at local paths during pnpm update (#3902).

  • Fixed a lockfile non-convergence case where incremental installs could keep a duplicate transitive dependency that a fresh install would remove.

  • pnpm install detects changes inside local file: dependencies and local tarballs again, bypassing the optimistic fast path for those projects (#11795).

  • Preserved the existing Node.js runtime version prefix when resolving node@runtime:<range> to a concrete version.

  • Shortened CAFS temporary package directories to leave room for lifecycle scripts that create IPC socket paths under TMPDIR.

  • Reporter output for pnpm store and pnpm config subcommands now goes to stderr, so scripts can safely capture stdout.

  • Avoided relinking unchanged child dependencies and removed stale child links during warm installs.

  • Fixed lockfile churn where transitivePeerDependencies could be dropped or shifted when a package participates in a dependency cycle (#5108).

  • Fixed pnpm install reporting "Already up to date" after a catalog entry in pnpm-workspace.yaml was reverted to a previous version (#12418).

  • Kept lockfile overrides that resolve through a catalog in sync when pnpm update bumps the catalog entry.

  • Fixed pnpm version --recursive so it honors workspace selection instead of always bumping every workspace package (#11348).