pnpm 11.0
pnpm 11 来了!此版本加强了在 v10 版本周期中引入的安全默认设置,取消了用于发布的 npm CLI 回退,转而使用原生实现,使用单个 SQLite 数据库替换了每个包的 JSON 存储索引,并隔离了全局安装,使它们不再相互干扰。
🌐 pnpm 11 is here! This release tightens the security defaults introduced throughout the v10 cycle, drops the npm CLI fallback for publishing in favor of a native implementation, replaces the JSON-per-package store index with a single SQLite database, and isolates global installs so they no longer interfere with each other.
它还需要 Node.js 22 或更高版本——pnpm 本身现在是纯 ESM。
🌐 It also requires Node.js 22 or newer — pnpm itself is now pure ESM.
从 v10 升级?请参阅 从 v10 迁移到 v11 指南。大多数配置更改是机械性的,可以通过 pnpm-v10-to-v11 codemod 应用。
🌐 Upgrading from v10? See the Migrating from v10 to v11 guide. Most config changes are mechanical and can be applied by the pnpm-v10-to-v11 codemod.
亮点
🌐 Highlights
-
Node.js 22+ required. Support for Node 18, 19, 20, and 21 is dropped. The standalone executable requires glibc 2.27 or newer.
-
Supply-chain protection on by default.
minimumReleaseAgedefaults to1440(1 day) andblockExoticSubdepsdefaults totrue. -
allowBuildsreplaces the legacy build-dependency settings.onlyBuiltDependencies,onlyBuiltDependenciesFile,neverBuiltDependencies,ignoredBuiltDependencies, andignoreDepScriptsare gone. -
Global installs are isolated and use the global virtual store by default. Each
pnpm add -ggets its own directory with its ownpackage.json,node_modules, and lockfile. -
New SQLite-backed store index (store v11), with bundled manifests and hex digests for fewer syscalls and faster installs.
-
Native publish flow.
pnpm publish,login,logout,view,deprecate,unpublish,dist-tag, andversionno longer delegate to the npm CLI. -
.npmrcis auth/registry only. Other settings must live inpnpm-workspace.yamlor the new globalconfig.yaml. Environment variables use thepnpm_config_*prefix.
重大变更
🌐 Breaking changes
要求
🌐 Requirements
-
Drops Node.js 18, 19, 20, and 21.
-
pnpm is now distributed as pure ESM.
-
The standalone exe requires glibc 2.27+.
安全与构建默认值
🌐 Security & build defaults
几个默认设置已切换为更安全的值:
🌐 Several defaults have flipped to safer values:
| 设置 | 新默认值 |
|---|---|
minimumReleaseAge | 1440(1天) |
minimumReleaseAgeStrict | false |
blockExoticSubdeps | true |
strictDepBuilds | true |
optimisticRepeatInstall | true |
verifyDepsBeforeRun | install |
新发布的软件包在至少 1 天后才会被解析。要选择退出,请在 pnpm-workspace.yaml 中设置 minimumReleaseAge: 0。
🌐 Newly published packages won't be resolved until they're at least 1 day old. To opt out, set minimumReleaseAge: 0 in pnpm-workspace.yaml.
allowBuilds 替换了旧的构建设置
🌐 allowBuilds replaces the old build settings
onlyBuiltDependencies、onlyBuiltDependenciesFile、neverBuiltDependencies、ignoredBuiltDependencies 和 ignoreDepScripts 都已被移除。请使用 allowBuilds 代替 — 一个从包名称模式到布尔值的映射:
之前:
🌐 Before:
onlyBuiltDependencies:
- electron
onlyBuiltDependenciesFile: "allowed-builds.json"
neverBuiltDependencies:
- core-js
ignoredBuiltDependencies:
- esbuild
之后:
🌐 After:
allowBuilds:
electron: true
core-js: false
esbuild: false
也已移除:allowNonAppliedPatches(使用 allowUnusedPatches)和 ignorePatchFailures(补丁失败现在会抛出)。
🌐 Also removed: allowNonAppliedPatches (use allowUnusedPatches) and ignorePatchFailures (patch failures now throw).
.npmrc 仅用于身份验证/注册表
🌐 .npmrc is auth/registry only
pnpm 不再从 .npmrc 读取非认证设置。配置分为两类:
🌐 pnpm no longer reads non-auth settings from .npmrc. Configuration is split into two categories:
-
Registry and auth settings — INI files (
.npmrc, the globalrcfile,~/.config/pnpm/auth.ini). -
pnpm-specific settings — YAML files (
pnpm-workspace.yaml, the new global~/.config/pnpm/config.yaml).
其他相关变化:
🌐 Other related changes:
-
pnpm no longer reads
npm_config_*environment variables. Usepnpm_config_*instead (e.g.pnpm_config_registry). -
pnpm no longer reads the
pnpmfield inpackage.json. -
pnpm no longer reads npm's global config at
$PREFIX/etc/npmrc. -
Network settings (
httpProxy,httpsProxy,noProxy,localAddress,strictSsl,gitShallowHosts) are now written toconfig.yaml/pnpm-workspace.yaml(still readable from.npmrcto ease migration). -
A new
registriessetting inpnpm-workspace.yamlreplaces@scope:registry=lines:registries:
default: https://registry.npmjs.org/
"@my-org": https://private.example.com/
"@internal": https://nexus.corp.com/ -
Per-project
.npmrcis replaced bypackageConfigsinpnpm-workspace.yaml:packages:
- "packages/project-1"
- "packages/project-2"
packageConfigs:
"project-1":
saveExact: true
"project-2":
savePrefix: "~"
本地发布流程,不再使用 npm CLI 回退
🌐 Native publish flow, no more npm CLI fallback
以前通过传递到 npm CLI 实现的命令要么已被本地重新实现,要么已被移除。
🌐 Commands previously implemented by passing through to the npm CLI have either been reimplemented natively or removed.
重新实现:publish、view(info、show、v)、login(adduser)、logout、deprecate、unpublish、dist-tag、version、search、star/unstar/stars、whoami、ping、docs/home。
🌐 Reimplemented: publish, view (info, show, v), login (adduser), logout, deprecate, unpublish, dist-tag, version, search, star/unstar/stars, whoami, ping, docs/home.
已移除(现在抛出“未实现”):access、bugs、edit、issues、owner、prefix、profile、pkg、repo、set-script、team、token、xmas。
🌐 Removed (now throw "not implemented"): access, bugs, edit, issues, owner, prefix, profile, pkg, repo, set-script, team, token, xmas.
关于新的本地 pnpm publish 的一些说明:
🌐 A few notes on the new native pnpm publish:
-
The OTP environment variable is now
PNPM_CONFIG_OTP(wasNPM_CONFIG_OTP). -
If the registry asks for OTP and none is provided, pnpm prompts for it interactively.
-
Web-based authentication shows a scannable QR code and URL.
pnpm audit 使用批量建议端点
🌐 pnpm audit uses the bulk advisories endpoint
注册表已淘汰了遗留的 /-/npm/v1/security/audits{,/quick} 端点。pnpm audit 现在调用 /-/npm/v1/security/advisories/bulk,它不返回 CVE 标识符 — 因此基于 CVE 的过滤已被 基于 GHSA 的过滤 所取代:
🌐 The legacy /-/npm/v1/security/audits{,/quick} endpoints have been retired by the registry. pnpm audit now calls /-/npm/v1/security/advisories/bulk, which doesn't return CVE identifiers — so CVE-based filtering has been replaced with GHSA-based filtering:
-
auditConfig.ignoreCves→auditConfig.ignoreGhsas -
pnpm audit --ignore <id>and--ignore-unfixableread and write GHSAs
要迁移,请将 ignoreCves 下的每个 CVE-YYYY-NNNNN 条目替换为匹配的 GHSA-xxxx-xxxx-xxxx(在 pnpm audit 的 More info 列中可见),并将其移动到 ignoreGhsas。
🌐 To migrate, replace each CVE-YYYY-NNNNN entry under ignoreCves with the matching GHSA-xxxx-xxxx-xxxx (visible in the More info column of pnpm audit) and move it to ignoreGhsas.
孤立的,全球虚拟商店的全球安装
🌐 Isolated, global-virtual-store global installs
pnpm add -g <pkg> 和 pnx 现在使用全局虚拟存储,并且 每次安装都会在 {pnpmHomeDir}/global/v11/{hash}/ 获得自己的独立目录,该目录拥有自己的 package.json、node_modules/ 和锁文件。这可以防止全局包通过同辈依赖冲突、提升更改或版本漂移相互干扰。
-
pnpm remove -g <pkg>removes the entire installation group containing the package. -
pnpm update -g [pkg]re-installs into a new isolated directory. -
pnpm list -gscans isolated directories. -
pnpm install -g(no args) is no longer supported — usepnpm add -g <pkg>.
全局安装的二进制文件现在位于 PNPM_HOME 的 bin 子目录中(而不是直接位于 PNPM_HOME),因此像 global/ 和 store/ 这样的内部目录不会污染 shell 自动补全。升级后运行 pnpm setup 以更新你的 shell 配置。
🌐 Globally installed binaries now live in a bin subdirectory of PNPM_HOME (rather than directly in PNPM_HOME), so internal directories like global/ and store/ don't pollute shell autocompletion. Run pnpm setup after upgrading to update your shell configuration.
pnpm link 也已被收紧:只接受相对路径或绝对路径,--global 已被移除(使用 pnpm add -g .),并且不带参数的 pnpm link 已被移除。
其他搬迁
🌐 Other removals
-
pnpm server. -
useNodeVersionandexecutionEnv.nodeVersion— usedevEngines.runtime/engines.runtime. -
hooks.fetchers— replaced by the newfetchersfield in pnpmfile. -
managePackageManagerVersions,packageManagerStrict, andpackageManagerStrictVersion. These all derived theonFailbehavior of the legacypackageManagerfield; the newpmOnFailsetting subsumes them:已移除 替换为 managePackageManagerVersions: truepmOnFail: download(默认)managePackageManagerVersions: falsepmOnFail: ignorepackageManagerStrict: falsepmOnFail: warnpackageManagerStrictVersion: truepmOnFail: errorCOREPACK_ENABLE_STRICT=0pmOnFail: warn
新命令
🌐 New commands
| 命令 | 它的作用 |
|---|---|
pnpm ci | 运行 pnpm clean,然后运行 pnpm install --frozen-lockfile。别名:clean-install、ic、install-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 的短别名 pn 和 pnpx/pnpm dlx 的短别名 pnx。
🌐 Plus the natively reimplemented commands listed under "Native publish flow" above, and short aliases pn for pnpm and pnx for pnpx/pnpm dlx.
pnpm audit --fix=update
通过更新锁文件中的包来修复漏洞,而不是添加覆盖。为了更精细的控制,新的 --interactive / -i 标志允许你选择要修复的安全公告:
🌐 Fix vulnerabilities by updating packages in the lockfile instead of adding overrides. For more granular control, the new --interactive / -i flag lets you select which advisories to fix:
pnpm audit --fix=update --interactive
pnpm audit --fix 还将每个公告的最小修补版本添加到 minimumReleaseAgeExclude 的 pnpm-workspace.yaml 中,因此可以在无需等待 minimumReleaseAge 的情况下安装安全修复。
ESM pnpm文件
🌐 ESM pnpmfiles
Pnpm 文件现在可以使用 ESM 编写,使用 .mjs 扩展名。当存在 .pnpmfile.mjs 时,它优先于 .pnpmfile.cjs,并且只加载一个。
🌐 Pnpmfiles can now be written in ESM, using the .mjs extension. When .pnpmfile.mjs exists, it takes priority over .pnpmfile.cjs, and only one is loaded.
商店 v11
🌐 Store v11
该商店围绕两个理念重建:少读数据,减少系统调用。
🌐 The store has been rebuilt around two ideas: read less, do fewer syscalls.
-
The package index is now a single SQLite database at
$STORE/index.db(with MessagePack values, WAL mode for concurrent access), instead of millions of JSON files under$STORE/index/. Packages missing from the new index are re-fetched on demand. -
The bundled manifest (name, version, bin, engines, scripts, etc.) is stored directly in the package index, eliminating the need to read
package.jsonfrom the CAS during resolution and installation. -
Index entries store hex digests instead of full integrity strings (
<algo>-<digest>), and the hash algorithm is recorded once per file instead of per entry. This avoids base64 → hex conversion on every CAS path lookup. -
When the global virtual store is enabled, packages that aren't allowed to build (and don't transitively depend on packages that are) get hashes that don't include the engine name (platform, arch, Node.js major). ~95% of GVS packages now survive Node.js upgrades and architecture changes without re-import.
性能
🌐 Performance
许多小的胜利累积起来会显著加快安装速度:
🌐 A lot of small wins add up to a noticeably faster install:
-
undicireplacesnode-fetchfor all HTTP, with Happy Eyeballs (dual-stack), better keep-alive, and an optimized global dispatcher. -
Tarball downloads with known size pre-allocate memory to avoid double-copy overhead.
-
The metadata cache is now NDJSON, with
If-Modified-Sincefor conditional fetches. -
minimumReleaseAgechecks use the abbreviated metadata endpoint to fetch less. -
CAS files are written directly to their content-addressed path instead of via a temp file + rename — saving ~30k rename syscalls per cold install.
-
The staging directory is gone when importing into
node_modules. -
Hot-path string operations in the CAS were tightened, and
gunzipSyncruns with a larger chunk size for fewer buffer allocations during tarball decompression. -
During GVS warm reinstalls, redundant internal linking is skipped when no packages were added.
更精简的运行时安装
🌐 Slimmer runtime installs
通过 node@runtime:<version> 安装 Node.js 运行时(包括 pnpm env use 和 pnpm runtime set node)不再从 Node.js 压缩包中提取打包的 npm、npx 和 corepack。这样大约减少了一半 pnpm 需要哈希、写入 CAS 并链接的文件。如果你仍然需要 npm,请将其作为单独的包安装。
🌐 Installing a Node.js runtime via node@runtime:<version> (including pnpm env use and pnpm runtime set node) no longer extracts the bundled npm, npx, and corepack from the Node.js archive. That cuts roughly half of the files pnpm has to hash, write to the CAS, and link. If you still need npm, install it as a separate package.
其他显著变化
🌐 Other notable changes
-
Cleaner script output.
pnpmnow prints$ command(to stderr, so stdout stays pipe-friendly) instead of> pkg@version stage path\n> command. Project name and path are shown only when running in a different directory. -
Peer dependency issues are no longer rendered as a tree during install — pnpm suggests running
pnpm peers checkto view them. -
Lifecycle scripts no longer get
npm_config_*env vars from the pnpm config; only well-knownnpm_*env vars are set, matching Yarn. -
pnpm initwritesdevEngines.packageManagerinstead ofpackageManagerwheninit-package-manageris enabled, and the defaulttypeis now"module". -
devEngines.packageManagernow supports version ranges; the resolved version is stored inpnpm-lock.yamland reused if it still satisfies the range. -
dedupePeersis a new setting that uses version-only suffixes (name@version) instead of full dep paths, eliminating nested suffixes like(foo@1.0.0(bar@2.0.0))for projects with many recursive peers. -
pnpm approve-buildsnow accepts positional arguments for non-interactive use; prefix a name with!to deny it. -
Hidden scripts — scripts starting with
.can only be called from other scripts and don't show up inpnpm run. -
-Fis a new short alias for--filter. -
pnpm addshort flags —-dis now--save-dev,-pis--save-prod,-ois--save-optional,-eis--save-exact(only insidepnpm add). -
virtualStoreOnlypopulates the virtual store without creating importer symlinks, hoisting, bin links, or running lifecycle scripts. Useful for pre-populating a store in Nix builds.pnpm fetchnow uses this internally. -
nodeDownloadMirrorsinpnpm-workspace.yamlreplaces thenode-mirror:<channel>.npmrcsetting:nodeDownloadMirrors:
release: https://my-mirror.example.com/download/release/ -
Config dependencies are now installed into
{storeDir}/links/and symlinked intonode_modules/.pnpm-config/, so they're shared across projects using the same store. Resolved versions and integrity hashes have moved frompnpm-workspace.yamlto a separate document inpnpm-lock.yaml; old inline-hash projects are migrated automatically.
升级
🌐 Upgrading
请参阅完整的 从 v10 迁移到 v11 指南,以了解 codemod 和手动后续步骤。简短版本如下:
🌐 See the full Migrating from v10 to v11 guide for the codemod and manual follow-ups. The short version:
-
Bump your CI and dev environments to Node.js 22+ before upgrading.
-
Move pnpm settings out of
.npmrcintopnpm-workspace.yaml(or the global~/.config/pnpm/config.yaml). -
Migrate
onlyBuiltDependenciesand friends toallowBuilds. -
Migrate
auditConfig.ignoreCvestoauditConfig.ignoreGhsas. -
After installing v11, run
pnpm setupto update your shell so the newbinsubdirectory is onPATH.
完整的更改列表请查看 changelog。如果你依赖的某些功能缺失或损坏,请在 github.com/pnpm/pnpm/issues 打开一个问题。
🌐 The full list of changes is in the changelog. If something you relied on is missing or broken, please open an issue at github.com/pnpm/pnpm/issues.
