pnpm 的 node_modules 结构设计独特,采用了三层结构:
目录结构:
shellnode_modules/ ├── .pnpm/ # 存储所有依赖的实际内容 │ ├── lodash@4.17.21/ # 每个包的具体版本 │ │ └── node_modules/ │ │ └── lodash/ # 硬链接到全局 store │ └── express@4.18.2/ │ └── node_modules/ │ ├── express/ # 硬链接 │ └── ... # 依赖的依赖 ├── .modules.yaml # pnpm 元数据 └── lodash -> .pnpm/lodash@4.17.21/node_modules/lodash # 符号链接
三层结构解析:
-
node_modules/[package]
- 符号链接,指向 .pnpm 目录中的实际包
- 只包含直接依赖,避免幽灵依赖
-
node_modules/.pnpm/[package@version]
- 包含每个包版本的实际内容
- 使用硬链接指向全局 store
-
全局 store(~/.pnpm-store)
- 所有项目的包只存储一份
- 通过内容寻址存储
设计优势:
javascript// ❌ npm/Yarn 中可以这样访问(幽灵依赖) import lodash from 'lodash' // 即使 package.json 中没有声明 // ✅ pnpm 中只能访问声明的依赖 // 未声明的依赖无法访问,更加安全
关键特性:
- 严格的依赖隔离
- 防止访问未声明的依赖
- 支持 peer dependencies 的正确解析
- 更好的包版本管理