全局虚拟存储
默认情况下,pnpm 会在每个项目的 node_modules 目录下创建一个 .pnpm 目录——这就是“虚拟存储”。 它包含指向 内容寻址存储 中文件的硬链接。 每个项目都有自己的虚拟存储投影——pnpm 将内容寻址商店中的文件硬链接到 .pnpm 目录结构中。 实际的文件内容在磁盘上只存在一次,但目录结构会为每个项目重新创建,以便 Node.js 的模块解析算法能够找到每个包的正确依赖项。
启用全局虚拟存储(enableGlobalVirtualStore: true)可以改变这一点。 pnpm 不为每个项目都设置自己的 node_modules/.pnpm 目录,而是维护一个共享的虚拟存储(位于 <store-path>/links/,运行 pnpm store path 可以找到 <store-path>)。 每个项目的 node_modules 目录下只包含指向这个共享位置的符号链接。
默认行为与全局虚拟存储
默认(每个项目一个虚拟存储)
project-a/
└── node_modules/
├── lodash → .pnpm/lodash@4.17.21/node_modules/lodash
└── .pnpm/
└── lodash@4.17.21/
└── node_modules/
└── lodash/ ← 指向内容寻址存储的硬链接
project-b/
└── node_modules/
├── lodash → .pnpm/lodash@4.17.21/node_modules/lodash
└── .pnpm/
└── lodash@4.17.21/
└── node_modules/
└── lodash/ ← 相同的硬链接,重复的目录结构
每个项目都有自己的 .pnpm 文件,其中包含硬链接。 文件内容不会在磁盘上重复(硬链接共享 inode),但目录结构会重复。 对于大型单体仓库或许多并行检出,在 pnpm install 期间创建数千个硬链接所花费的时间会累积。
使用全局虚拟存储
project-a/
└── node_modules/
└── lodash → <global-store>/links/@/lodash/4.17.21/<hash>/node_modules/lodash
project-b/
└── node_modules/
└── lodash → <global-store>/links/@/lodash/4.17.21/<hash>/node_modules/lodash ← 相同目标
这两个项目都直接符号链接到全局虚拟存储中的同一位置。 没有每个项目单独的 .pnpm 目录。 全局虚拟存储本身包含指向内容寻址存储的硬链接——但这只发生在每个依赖图上一次(下文会详细说明),而不是每个项目。
软件包标识如何工作
在全局虚拟存储中,每个软件包目录都以其依赖关系图的哈希值命名。 两个使用 lodash@4.17.21 且具有相同传递依赖树的项目将指向完全相同的目录。 如果依赖关系树不同(例如,不同的对等依赖关系),pnpm 会创建单独的条目。 这在概念上类似于 NixOS 管理软件包 使用依赖关系图哈希的方式。
何时使用它
当你在磁盘上有同一项目的多个检出版本时,全局虚拟存储最为有用——例如,在使用git 工作树进行多代理开发 时。 在这种情况下,每个工作树都可以获得几乎无成本的 node_modules,因为所有真正的包内容都已存在于共享存储中。
它还可以加快同一台机器上不相关项目的安装速度,因为任何项目已经安装的任何软件包版本都可以立即使用。
局限性
- CI 环境:在 CI 中,通常没有缓存,因此没有可用的全局热存储。 全局虚拟存储在 CI 中通常没用。
- ESM 提升:pnpm 使用
NODE_PATH环境变量来支持全局虚拟存储的提升依赖项。 但是,Node.js 并不遵循 ESM 导入的NODE_PATH。 如果 ESM 依赖项尝试导入未在其自身package.json中声明的包,则解析将失败。 您可以使用 packageExtensions 或 @pnpm/plugin-esm-node-path 配置依赖项来解决此问题。./settings.md#packageextensions
The global virtual store is currently disabled by default for project installs and marked as experimental, as some tools may not work correctly with symlinked node_modules. You need to explicitly set enableGlobalVirtualStore: true in pnpm-workspace.yaml to use it for project installs. 在 pnpm v11 中,默认情况下,通过 pnpm dlx (pnpx) 安装的软件包和全局安装的软件包都会启用全局虚拟存储。 目标是在未来的版本中默认启用该功能。
Global packages
In pnpm v11, global installs (pnpm add -g) and pnpm dlx use the global virtual store by default. See Global Packages for the full guide on how global package management works in v11, including isolated installations and the new binaries location.
配置
有关所有配置详情,请参阅 enableGlobalVirtualStore。