# Pnpm
# 原理
# 1. 硬链接和符号链接机制
- 全局存储
pnpm会将所有项目的依赖包下载到全局的仓库,通常是在用户的主目录下面(pnpm store path)。
- 硬链接
每个文件都是一个指针,指向具体的文件数据,所以不会产生额外的磁盘占用,可以重复创建各种硬链接,文件夹不能创建硬连接。

pnpm会在项目的node_modules中创建指向全局存储中相应的包的链接,只会占用一次空间,每个项目都可以访问到自己项目的依赖包副本。
- 符号链接
符号链接指向的是创建出来的文件,一旦一个删除,另一个也会无效,文件和文件夹都可以创建。

- node 处理
硬链接: node 无法区别对待,当作一个普通文件。 符号链接: 符号链接指向的是另一个文件/文件夹,当 node 执行文件的时候,使用的是原始路径。
# 2. 严格的依赖隔离
pnpm每个包只能访问自身声明的依赖,杜绝幽灵依赖,与传统npm不同。
# 具体目录结构
pnpm的node_modules布局使用符号链接来创建依赖关系的嵌套结构。
比如项目依赖foo@1.0.0这个包,而foo@1.0.0依赖bar@1.0.0。
- 首先会创建所有依赖到
.pnpm中,这些自身都属于硬连接,是真实存在的。
node_modules
└── .pnpm
├── bar@1.0.0
│ └── node_modules
│ └── bar -> <store>/bar
│ ├── index.js
│ └── package.json
└── foo@1.0.0
└── node_modules
└── foo -> <store>/foo
├── index.js
└── package.json
- 符号链接依赖项
根据依赖关系,创建符号链接。
node_modules
└── .pnpm
├── bar@1.0.0
│ └── node_modules
│ └── bar -> <store>/bar
└── foo@1.0.0
└── node_modules
├── foo -> <store>/foo
└── bar -> ../../bar@1.0.0/node_modules/bar
- 处理直接依赖关系。
最终只有foo作为项目的依赖。
node_modules
├── foo -> ./.pnpm/foo@1.0.0/node_modules/foo
└── .pnpm
├── bar@1.0.0
│ └── node_modules
│ └── bar -> <store>/bar
└── foo@1.0.0
└── node_modules
├── foo -> <store>/foo
└── bar -> ../../bar@1.0.0/node_modules/bar
React →