惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

云风的 BLOG
云风的 BLOG
IT之家
IT之家
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
博客园 - 司徒正美
美团技术团队
Last Week in AI
Last Week in AI
月光博客
月光博客
博客园 - 叶小钗
MongoDB | Blog
MongoDB | Blog
U
Unit 42
T
Tailwind CSS Blog
GbyAI
GbyAI
T
The Blog of Author Tim Ferriss
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
H
Hackread – Cybersecurity News, Data Breaches, AI and More
酷 壳 – CoolShell
酷 壳 – CoolShell
Google DeepMind News
Google DeepMind News
H
Help Net Security
Hugging Face - Blog
Hugging Face - Blog
爱范儿
爱范儿
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
N
Netflix TechBlog - Medium
B
Blog RSS Feed
大猫的无限游戏
大猫的无限游戏
aimingoo的专栏
aimingoo的专栏
A
About on SuperTechFans
Y
Y Combinator Blog
罗磊的独立博客
D
DataBreaches.Net
有赞技术团队
有赞技术团队
MyScale Blog
MyScale Blog
博客园_首页
博客园 - 三生石上(FineUI控件)
G
Google Developers Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
雷峰网
雷峰网
博客园 - 【当耐特】
Engineering at Meta
Engineering at Meta
博客园 - Franky
M
MIT News - Artificial intelligence
B
Blog
The Cloudflare Blog
Apple Machine Learning Research
Apple Machine Learning Research
I
InfoQ
S
SegmentFault 最新的问题
F
Fortinet All Blogs
阮一峰的网络日志
阮一峰的网络日志
Stack Overflow Blog
Stack Overflow Blog
Microsoft Security Blog
Microsoft Security Blog

pnpm Blog

pnpm 11.10 pnpm 11.9 pnpm 11.8 pnpm 11.7 Why pnpm no longer expands environment variables in a repository's .npmrc pnpm 11.6 pnpm 11.5 pnpm 11.4 pnpm 11.3 pnpm 11.2 pnpm 11.1 pnpm 10.32 pnpm 10.31 pnpm 10.30 pnpm 10.29 pnpm 10.28 pnpm 10.27 🚀 2025年的 pnpm pnpm 10.26 pnpm 10.25 我们如何保护新闻编辑部免受npm供应链攻击 pnpm 10.24 pnpm 10.23 pnpm 10.22 pnpm 10.21 pnpm 10.20
pnpm 11.0
Zoltan Kochan · 2026-04-28 · via pnpm Blog

pnpm 11 来了! 此版本加强了 v10 周期中引入的安全默认设置,放弃了 npm CLI 发布回退,转而采用原生实现,将每个包的 JSON 存储索引替换为单个 SQLite 数据库,并将全局安装隔离,使其不再相互干扰。

它还需要 Node.js 22 或更高版本——pnpm 本身现在是纯 ESM。

从 v10 升级? 请参阅 从 v10 迁移到 v11 指南。 大多数配置更改都是机械性的,可以通过 pnpm-v10-to-v11 代码转换来应用。

亮点

  • 需要 Node.js 22+。 已停止支持 Node 18、19、20 和 21。 独立可执行文件需要 glibc 2.27 或更高版本。
  • 供应链保护默认开启。 minimumReleaseAge 默认为 1440(1 天),blockExoticSubdeps 默认为 true
  • allowBuilds 取代了旧版构建依赖项设置。 onlyBuiltDependenciesonlyBuiltDependenciesFileneverBuiltDependenciesignoredBuiltDependenciesignoreDepScripts 已移除。
  • 全局安装是隔离的,默认情况下使用全局虚拟存储。 每个 pnpm add -g 都会获得自己的目录,其中包含自己的 package.jsonnode_modules 和 lockfile。
  • 新的 SQLite 支持的存储索引(存储 v11),捆绑了清单和十六进制摘要,减少了系统调用,加快了安装速度。
  • 原生发布流程。 pnpm publishloginlogoutviewdeprecateunpublishdist-tagversion 不再委托给 npm CLI。
  • .npmrc 仅用于身份验证/注册源。 其他设置必须放在 pnpm-workspace.yaml 或新的全局 config.yaml 中。 环境变量使用 pnpm_config_* 前缀。

破坏性改动

需求

  • 不支持 Node.js 18、19、20 和 21。
  • pnpm 现在以纯 ESM 格式分发。
  • 独立可执行文件需要 glibc 2.27+。

安全和构建默认值

多项默认值已翻转为更安全的值:

设置新的默认值
minimumReleaseAge1440(1天)
minimumReleaseAgeStrictfalse
blockExoticSubdepstrue
strictDepBuildstrue
optimisticRepeatInstalltrue
verifyDepsBeforeRuninstall

新发布的软件包至少要过 1 天才能被解析。 若要选择退出,在 pnpm-workspace.yaml 中设置 minimumReleaseAge: 0

allowBuilds 取代了旧的构建设置

onlyBuiltDependenciesonlyBuiltDependenciesFileneverBuiltDependenciesignoredBuiltDependenciesignoreDepScripts 都已被移除。 请改用 allowBuilds — 一个从包名称模式到布尔值的映射:

之前:

onlyBuiltDependencies:
- electron
onlyBuiltDependenciesFile: "allowed-builds.json"
neverBuiltDependencies:
- core-js
ignoredBuiltDependencies:
- esbuild

之后:

allowBuilds:
electron: true
core-js: false
esbuild: false

同时移除了:allowNonAppliedPatches(使用 allowUnusedPatches)和ignorePatchFailures(补丁失败现在会抛出异常)。

.npmrc 仅用于身份验证/注册源

pnpm 不再从 .npmrc 读取非身份验证设置。 配置分为两类:

  • 注册源和认证设置 — INI 文件(.npmrc, 全局rc文件, ~/.config/pnpm/auth.ini)。
  • pnpm 特定设置 — YAML 文件(pnpm-workspace.yaml,新的全局 ~/.config/pnpm/config.yaml)。

其他相关变更:

  • pnpm 不再读取 npm_config_* 环境变量。 请改用 pnpm_config_*(例如 pnpm_config_registry)。

  • pnpm 不再读取 package.json 中的 pnpm 字段。

  • pnpm 不再读取 npm 的全局配置,位于 $PREFIX/etc/npmrc

  • 网络设置(httpProxyhttpsProxynoProxylocalAddressstrictSslgitShallowHosts)现在写入到 config.yaml / pnpm-workspace.yaml 中(仍然从 .npmrc 中读取以平滑迁移)。

  • pnpm-workspace.yaml 文件中新增的 registries 设置替换了 @scope:registry= 行:

    registries:
    default: https://registry.npmjs.org/
    "@my-org": https://private.example.com/
    "@internal": https://nexus.corp.com/
  • 每个项目的 .npmrc 文件被 pnpm-workspace.yaml 文件中的 packageConfigs 文件取代:

    packages:
    - "packages/project-1"
    - "packages/project-2"
    packageConfigs:
    "project-1":
    saveExact: true
    "project-2":
    savePrefix: "~"

原生发布流程,不再使用 npm CLI 回退方案

以前通过传递给 npm CLI 实现的命令要么已经以原生方式重新实现,要么已经移除

重新实现:publish, view (info, show, v), login (adduser), logout, deprecate, unpublish, dist-tag, version, search, star/unstar/stars, whoami, ping, docs/home

已移除(现在抛出“未实现”):accessbugseditissuesownerprefixprofilepkgreposet-scriptteamtokenxmas

关于新的原生 pnpm publish 的一些说明:

  • OTP 环境变量现在是 PNPM_CONFIG_OTP(以前是 NPM_CONFIG_OTP)。
  • 如果注册源要求提供 OTP 但未提供,pnpm 将以交互方式提示输入 OTP。
  • 基于网页的身份验证会显示可扫描的二维码和网址。

pnpm audit 使用批量建议端点

注册源已停用旧版 /-/npm/v1/security/audits{,/quick} 端点。 pnpm audit 现在调用 /-/npm/v1/security/advisories/bulk,该命令不返回 CVE 标识符——因此,基于 CVE 的过滤已被基于 GHSA 的过滤所取代:

  • auditConfig.ignoreCvesauditConfig.ignoreGhsas
  • pnpm audit --ignore <id>--ignore-unfixable 读取和写入 GHSA

要进行迁移,请将 ignoreCves 下的每个 CVE-YYYY-NNNNN 条目替换为匹配的 GHSA-xxxx-xxxx-xxxx(在 pnpm auditMore info 列中可见),并将其移动到 ignoreGhsas

孤立的、全局虚拟存储的全局安装

pnpm add -g <pkg>pnx 现在使用全局虚拟存储,并且每个安装都会在 {pnpmHomeDir}/global/v11/{hash}/ 获得自己的独立目录,其中包含自己的 package.jsonnode_modules/ 和锁文件。 这样可以防止全局包之间因对等依赖冲突、提升更改或版本错位而相互干扰。

  • pnpm remove -g <pkg> 会删除包含该软件包的整个安装组。
  • pnpm update -g [pkg] 会将软件包重新安装到一个新的隔离目录中。
  • pnpm list -g 扫描隔离目录。
  • pnpm install -g(不带参数)不再受支持——请使用 pnpm add -g <pkg>

全局安装的二进制文件现在位于 PNPM_HOMEbin 子目录中(而不是直接位于 PNPM_HOME 中),因此像 global/store/ 这样的内部目录不会污染 shell 自动补全。 升级后运行 pnpm setup 以更新 shell 配置。

pnpm link 也进行了收紧:只接受相对路径或绝对路径,移除了 --global(使用 pnpm add -g .),并且移除了不带参数的 pnpm link

其他移除

  • pnpm server.

  • useNodeVersionexecutionEnv.nodeVersion — 使用 devEngines.runtime / engines.runtime

  • hooks.fetchers — 已被 pnpmfile 中的新 fetchers 字段取代。

  • managePackageManagerVersionspackageManagerStrictpackageManagerStrictVersion。 这些都继承了旧版 packageManager 字段的 onFail 行为;新的 pmOnFail 设置包含了它们:

    已移除替换为
    managePackageManagerVersions: truepmOnFail: download(默认)
    managePackageManagerVersions: falsepmOnFail: ignore
    packageManagerStrict: falsepmOnFail: warn
    packageManagerStrictVersion: truepmOnFail: error
    COREPACK_ENABLE_STRICT=0pmOnFail: warn

新命令

命令它的作用
pnpm ci运行 pnpm clean,然后运行 pnpm install --frozen-lockfile。 别名:clean-installicinstall-clean.
pnpm clean从所有工作区项目中移除 node_modules--lockfile 也会删除 pnpm-lock.yaml
pnpm sbom生成 CycloneDX 1.7 或 SPDX 2.3 JSON 格式的软件物料清单。
pnpm peers check报告锁文件中未满足/缺失的对等依赖。
pnpm runtime set安装运行时;弃用 pnpm env use
pnpm docs / home打开软件包主页。
pnpm ping向注册源发送 Ping 请求。
pnpm with在单次调用中以特定(或当前)版本运行 pnpm,绕过 packageManager 的版本限制。
pnpm pack-app通过 Node.js SEA 将 CommonJS 条目打包成一个或多个目标平台的独立可执行文件。

此外,还有上面“原生发布流程”下列出的原生重新实现的命令,以及 pnpm 的短别名 pnpnpx/pnpm dlx 的短别名 pnx

pnpm audit --fix=update

通过更新锁文件 中的软件包来修复易受伤害性,而不是添加覆盖。 为了实现更精细的控制,新增的 --interactive / -i 标志允许你选择要修复的警示:

pnpm audit --fix=update --interactive

pnpm audit --fix 还会将每个安全公告的最小补丁版本添加到 pnpm-workspace.yaml 中的 minimumReleaseAgeExclude,这样就可以在不等待 minimumReleaseAge 的情况下安装安全修复程序。

ESM pnpmfiles

现在可以使用 .mjs 扩展名以 ESM 格式编写 pnpmfiles。 当 .pnpmfile.mjs 存在时,它的优先级高于 .pnpmfile.cjs,并且只会加载其中一个。

存储 v11

该存储的重建围绕两个理念展开:减少读取,减少系统调用。

  • 现在,软件包索引是一个位于 $STORE/index.db 的单个 SQLite 数据库(具有 MessagePack 值,WAL 模式用于并发访问),而不是位于 $STORE/index/ 下的数百万个 JSON 文件。 新索引中缺失的软件包会根据需要重新获取。
  • 捆绑清单(名称、版本、bin、引擎、脚本等) 直接存储在软件包索引中,无需在解析和安装过程中从 CAS 读取 package.json
  • 索引条目存储十六进制摘要,而不是完整的完整性字符串(<algo>-<digest>),并且哈希算法每个文件记录一次,而不是每个条目记录一次。 这样可以避免每次 CAS 路径查找时进行 base64 → hex 转换。
  • 启用全局虚拟存储后,不允许构建的软件包(并且不间接依赖于允许构建的软件包)将获得不包含引擎名称(平台、架构、Node.js 主版本号)的哈希值。 现在约 95% 的 GVS 包无需重新导入即可在 Node.js 升级和架构变更后继续保留。

性能

许多小胜利增加了一个明显更快的安装:

  • undici 取代了 node-fetch 用于所有 HTTP 请求,具有 Happy Eyeballs(双栈)、更好的 keep-alive 和优化的全局调度器。
  • 已知大小的 Tarball 下载会预先分配内存,以避免重复复制带来的开销。
  • 元数据缓存现在采用 NDJSON 格式,并带有 If-Modified-Since 以进行条件获取。
  • minimumReleaseAge 检查使用 简化的元数据 端点来获取更少的信息。
  • CAS 文件直接写入其内容寻址路径,而不是通过临时文件 + 重命名 — 每次冷安装可节省约 30k 次重命名系统调用。
  • 导入到 node_modules 时,暂存目录消失了
  • CAS 中的热路径字符串操作得到了加强,gunzipSync 运行时使用更大的块大小,以减少 tarball 解压缩期间的缓冲区分配。
  • 在 GVS 热重装过程中,如果没有添加任何软件包,则会跳过冗余的内部链接。

更精简的运行时安装

通过 node@runtime:<version>(包括 pnpm env usepnpm runtime set node)安装 Node.js 运行时不再从 Node.js 归档中提取捆绑的 npmnpxcorepack。 这大约减少了一半数量的pnpm需要哈希、写入CAS和链接的文件。 如果仍然需要 npm,请将其作为单独的软件包安装。

其他重要改动

  • 更清晰的脚本输出。 pnpm 现在打印 $ command(到 stderr,因此 stdout 保持管道友好),而不是 > pkg@version stage path\n> command。 只有在不同目录下运行时才会显示项目名称和路径。

  • 安装过程中,对等依赖关系问题不再以树状结构呈现——pnpm 建议运行 pnpm peers check 来查看它们。

  • 生命周期脚本不再从 pnpm 配置中获取 npm_config_* 环境变量;仅设置众所周知的 npm_* 环境变量,与 Yarn 一致。

  • 当启用 init-package-manager 时,pnpm init 会写入 devEngines.packageManager 而不是 packageManager,并且默认的 type 现在是 "module"

  • devEngines.packageManager 现在支持版本范围;解析后的版本存储在 pnpm-lock.yaml 中,如果仍然满足范围,则会被重用。

  • dedupePeers 是一个新设置,它使用仅包含版本信息的后缀 (name@version) 而不是完整的依赖路径,从而消除具有许多递归对等项的项目的嵌套后缀,例如 (foo@1.0.0(bar@2.0.0))

  • pnpm approve-builds 现在接受用于非交互式使用的位置参数;在名称前加上 ! 即可拒绝。

  • 隐藏脚本 — 以 . 开头的脚本只能从其他脚本调用,并且不会显示在 pnpm run 中。

  • -F--filter 的新简短别名。

  • pnpm add 短标志-d 现在是 --save-dev-p--save-prod-o--save-optional-e--save-exact(仅在 pnpm add 内部)。

  • virtualStoreOnly 在不创建导入器符号链接、提升、bin 链接或运行生命周期脚本下填充虚拟存储。 在 Nix 构建中预先填充存储很有用。 pnpm fetch 现在内部使用此功能。

  • pnpm-workspace.yaml 中的 nodeDownloadMirrors 替换了 .npmrc 中的 node-mirror:<channel> 设置:

    nodeDownloadMirrors:
    release: https://my-mirror.example.com/download/release/
  • 配置依赖项 现在已安装到 {storeDir}/links/ 中,并且符号链接到 node_modules/.pnpm-config/,因此它们可以在使用同一存储的项目之间共享。 已解析的版本和完整性哈希值已从 pnpm-workspace.yaml 移至 pnpm-lock.yaml 中的单独文档;旧的内联哈希项目会自动迁移。

升级

有关代码转换和后续操作的完整指南,请参阅 从 v10 迁移到 v11。 简短版本:

  • 升级前,请将 CI 和开发环境升级到 Node.js 22+ 版本。
  • 将 pnpm 设置从 .npmrc 移到 pnpm-workspace.yaml(或全局的 ~/.config/pnpm/config.yaml)。
  • onlyBuiltDependencies 及其相关功能迁移到 allowBuilds
  • auditConfig.ignoreCves 迁移到 auditConfig.ignoreGhsas
  • 安装 v11 后,运行 pnpm setup 来更新你的 shell,以便将新的 bin 子目录添加到 PATH 中。

完整的更改列表在 更改日志。 如果你依赖的某些功能缺失或损坏,请在 github.com/pnpm/pnpm/issues 上提交问题。