npm、yarn、pnpm区别
本文主要介绍npm
、 yarn
、pnpm
三者在依赖管理方面的不同。
在npm2
中,当我们使用依赖A
时,依赖A
里使用了依赖B
,依赖B
里使用了依赖C
,node_modules
里就会是这样的结构:
node_modules
--packageA.js
--node_modules
--packageB.js
--node_modules
--packageC.js
......
嵌套的层级太深,会导致文件的路径过长,有些程序可能无法处理过长的文件名。
另外假如还有个依赖D
中也使用了依赖C
,那么依赖D
的node_modules
下会再次安装依赖C
,这样就会导致有大量的依赖重复安装的问题,导致文件体积过大。
在npm3
中及yarn
中,采用扁平化依赖的方法来处理npm2
中存在的问题,在npm3
及yarn
中会是这样的接口:
node_modules
-- packageA.js
-- packageB.js
-- packageC.js
项目中的依赖及依赖使用的依赖都会平铺在node_modules
下,这样就能解决嵌套层级过深的问题,包也不会被重复被安装,如遇到版本不同的情况,则会进行版本提升。
这种方法的缺点是,npm
必须首先遍历所有的项目依赖关系,然后再决定如何生成扁平的node_modules
目录结构。npm
必须为所有使用到的模块构建一个完整的依赖关系树,这是一个耗时的操作,是npm
安装速度慢的一个很重要的原因。
另外由于扁平化的结构,导致即使项目中声明了依赖B
,但是没有声明过依赖C
,也可以直接使用依赖C
,这样就会造成隐患问题。如果依赖B
中哪天不需要使用依赖C
了,那我们的node_modules
里就会没有依赖C
,这样就会导致项目报错。
pnpm
中,使用符号链接和硬链接的做法来放置依赖。
硬链接是原始文件的一个镜像副本,它只能指向文件,记录了原始文件的内容,原始文件改变的时候,链接会同步改变。软链接类似于Windows
系统中的快捷方式,它可以指向文件目录或文件,链接文件只记录原始文件的路径,不记录原始文件的内容。
使用pnpm
的项目的node_modules
下的包名下存放的其实是一个软链接,连接到node_modules
下的.pnpm/包名/node_modules/xxx
该目录下存放的是该依赖包的依赖以及该依赖包本身,每个包里面都存放了一个全局store
中对应包源代码的hard link
。每个项目的node_modules
下存放的是一些link
。
使用pnpm
的好处是可以节约磁盘并提升安装速度,也能避免开发时使用间接依赖的问题。
参考文章
1、一文看懂npm、yarn、pnpm之间的区别
2、npm 和 yarn 你选哪个?
3、为什么现在我更推荐 pnpm 而不是 npm/yarn?
4、pnpm又是什么?
5、pnpm原理
6、Linux硬链接和软连接的区别与总结
7、Linux 中软链接和硬链接的区别
6、Yarn vs npm:你需要知道的一切
7、字节的一个小问题 npm 和 yarn不一样吗?