performant npm
,意味高性能的npm
。pnpm
由npm/yarn
衍生而来,解决了npm/yarn
内部潜在的bug
,极大的优化了性能,扩展了使用场景。被誉为"最先进的包管理工具"。
我们按照包管理工具的发展历史开始讲起:
npm2
-
用
node
版本管理工具把node
版本降到 4,那npm
版本就是2.x
了。 -
找个目录,执行下
npm init -y
,快速创建个package.json
。 -
执行
npm install express
,那么express
包和它的依赖都会被下载下来:
-
展开
express
,它也有node_modules
: -
再展开几层,每个依赖都有自己的
node_modules
:
也就是说npm2
的node_module
s 是嵌套的 -
这样其实是有问题的,多个包之间难免会有公共的依赖,这样嵌套的话,同样的依赖会复制很多次,会占据比较大的磁盘空间。
-
这个还不是最大的问题,致命问题是
windows
的文件路径最长是 260 多个字符,这样嵌套是会超过windows
路径的长度限制的。 -
当时
npm
还没解决,社区就出来新的解决方案了,就是yarn
yarn
yarn 是怎么解决依赖重复很多次,嵌套路径过长的问题的呢?
-
铺平。所有的依赖不再一层层嵌套了,而是全部在同一层,这样也就没有依赖重复多次的问题了,也就没有路径过长的问题了。
-
我们把
node_modules
删了,用yarn
再重新安装下,执行yarn add express
,这时候node_modules
就是这样了:
-
全部铺平在了一层,展开下面的包大部分是没有二层
node_modules
的: -
但是这样是有隐患的,因为没有显式依赖,万一有一天别的包不依赖这个包了,那你的代码也就不能跑了,因为你依赖这个包,但是现在不会被安装了。
这就是幽灵依赖的问题。 -
而且还有一个问题,就是上面提到的依赖包有多个版本的时候,只会提升一个,那其余版本的包不还是复制了很多次么,依然有浪费磁盘空间的问题。
所以衍生出来了pnpm
pnpm
pnpm采用的是软硬连接,硬连接就是同一个文件的不同引用,而软链接是新建一个文件,文件内容指向另一个路径,
- 这样不会有复制多次的磁盘空间浪费,而且也不会有路径过长的问题。
- 因为路径过长的限制本质上是不能有太深的目录层级,现在都是各个位置的目录的 link,并不是同一个目录,所以也不会有长度限制
- 再把
node_modules
删掉,然后用pnpm
重新装一遍,执行pnpm install
,包是从全局store
硬连接到虚拟 store 的,这里的虚拟 store 就是node_modules/.pnpm
- 确实不是扁平化的了,依赖了
express
,那node_modules
下就只有express
,没有幽灵依赖。 - 依赖都是从全局
store
硬连接到了node_modules/.pnpm
下,然后之间通过软链接来相互依赖
总结: npm2
是通过嵌套的方式管理node_modules
的,会有同样的依赖复制多次的问题。npm3+
和yarn
是通过铺平的扁平化的方式来管理node_modules
,解决了嵌套方式的部分问题,但是引入了幽灵依赖的问题,并且同名的包只会提升一个版本的,其余的版本依然会复制多次。pnpm
则是用了另一种方式,不再是复制了,而是都从全局store
硬连接到node_modules/.pnpm
,然后之间通过软链接来组织依赖关系。这样不但节省磁盘空间,也没有幽灵依赖问题,安装速度还快,从机制上来说完胜npm
和yarn
。