# 硬核解密:pnpm 的包到底存哪了?从本地到全局的存储机制全解析

4 阅读4分钟

作为一个开发者,你可能已经习惯了使用 pnpm 来替代 npmyarn,因为它极快且节省磁盘空间。但你是否好奇过:那些原本塞满磁盘的 node_modules 文件,在 pnpm 中到底去了哪里?

今天我们就来深入扒一扒 pnpm 的文件存储架构,带你彻底搞懂从项目本地全局环境的文件流向。


一、 项目本地:当你运行 pnpm install

在传统的 npm/yarn 中,依赖包是被完整复制到项目的 node_modules 中的。但在 pnpm 中,文件存储采用了 “三层架构”,利用了**硬链接(Hard Links)符号链接(Symlinks)**的魔法。

1. 表层:node_modules(符号链接)

这是你肉眼直接看到的目录。

  • 内容:你只会在根目录下看到你在 package.json 中声明的直接依赖
  • 机制:这些其实不是真实的文件,而是符号链接(软链接)
  • 目的:解决“幽灵依赖”问题。你没声明的包,这里就没有,代码里就引用不到,非常安全。

2. 中层:node_modules/.pnpm(虚拟存储库)

这是 pnpm 的核心设计,被称为 Virtual Store

  • 内容:所有的依赖(包括直接依赖和它们所有的子依赖)都平铺在这里。
  • 格式:通常以 包名@版本号 的格式命名文件夹。
  • 机制:这里的每个文件,通过硬链接指向磁盘上真正的物理仓库。
  • 目的:扁平化结构解决了依赖嵌套过深的问题,同时让 node 的解析算法能找到对应的包。

3. 底层:全局物理存储(Content-addressable Store)

这是文件真正占用磁盘空间的地方(同一磁盘分区下,所有项目共用一份)。

  • 机制:基于内容寻址。只要文件内容没变,无论你在多少个项目中安装了 vue@3.0,硬盘上永远只有这一份文件。

二、 全局环境:当你运行 pnpm add -g

当你安装全局工具(如 nodemon, create-react-app)时,它们并不会乱跑,而是会被井井有条地安置在两个关键位置:

1. 可执行文件目录(Global Binaries)

这是存放命令的地方,也就是你的终端能敲出命令的原因。

  • 作用:存放 cmd/sh 脚本或软链接,指向具体的库文件。
  • 查看命令
    pnpm config get global-bin-dir
    
  • 常见位置
    • Windows: %LOCALAPPDATA%\pnpm
    • macOS/Linux: ~/.local/share/pnpm

2. 全局库文件目录(Global Packages)

进入~/.local/share/pnpm/global/5/目录下, 下面也是包含.pnmpnode_modules, 逻辑与上面是一样的, 只不过是放在一个规定的全局路径下.

  • 作用:存放包的代码逻辑。
  • 查看命令
    pnpm root -g
    
  • 常见位置:通常在 global-bin-dir 下的 global/5/node_modules 目录中。

三、 终极答案:物理文件到底在哪?

无论是项目里的依赖,还是全局安装的工具,它们物理上的真身都汇聚在同一个地方,我们称之为 Global Store(全局存储)

如何找到它?

在终端运行:

pnpm store path

常见路径:

  • macOS/Linux: ~/.local/share/pnpm/store
  • Windows: C:\Users\你的用户名\AppData\Local\pnpm\store

这里的机制是怎样的?

  • pnpm 的省空间魔法:当你安装一个包时,pnpm 会先去这个 Global Store 看有没有。
    • :直接在你的项目中创建一个硬链接指向这里(速度极快,几乎不占额外空间)。
    • 没有:下载文件到这里,然后再创建硬链接。

四、 总结与命令速查表

pnpm 的设计哲学可以总结为:物理文件存一份(Global Store),各处引用靠链接(Symlink/Hardlink)。

为了方便记忆,这里有一份常用的路径查询命令清单:

你想找什么?运行这个命令
我的全局命令安装在哪了? (如 vite 放在哪)pnpm config get global-bin-dir
全局包的源码目录在哪?pnpm root -g
硬盘上真正的物理文件库在哪?pnpm store path
查看当前项目安装了哪些包?pnpm list
查看全局安装了哪些包?pnpm list -g

希望这篇文章能帮你彻底理清 pnpm 的文件结构!如果你觉得有用,不妨分享给团队里的小伙伴。