npm与yarn
安装依赖
在npm@3之前,npm使用的是嵌套安装,即每个package都会有自己的node_modules文件夹,这种结构有两种严重的问题:
- package中经常创建极深的依赖树,这会造成目录路径过长的问题
- 当一个依赖项在不同packages都依赖时,该依赖项会被重复安装,本地磁盘就会存放多个相同的包。
为了解决这些问题,npm@3和yarn引入了扁平化结构,node_modules变成所有包存放在同一层级,以上面的例子,a和c都依赖b,那么b就会被提升到a和c的同一层级。值得注意的是,同一个包的不同版本只会有一个被提升,具体提升的是哪个版本取决于依赖它的包在package.json中的先后顺序。
然而这又会导致一个问题,由于依赖结构的不确定性,导致扁平化结果的不确定,于是又出现了package.lock.json和yarn.lock来保证install后的扁平化结果的确定性。
还有一个问题就是幽灵依赖,即某个包没有在package.json中被依赖,但用户仍能引用到这个包,这是由于扁平化结构导致依赖项层级被提升。这种幽灵依赖可能会导致问题,比如以下场景:
- 旧版本A和旧版本C依赖B,可以直接引用到B,而A更新后,B的版本被更新,API发生变化,而C使用B的旧版本API,导致错误。
- 旧版本A和旧版本C依赖B,可以直接引用到B,而A更新后,B不再被依赖,那么C就不会再被提升,直接引用C就会报错。
还有一个问题是重复安装,如图
pnpm
pnpm解决了幽灵依赖和重复安装依赖的问题。pnpm项目安装的node_modules结构如下
可以看到,node_modules里只存在package.json里的直接依赖,和一个.pnpm文件夹,而且这些直接依赖文件夹旁边有一个箭头,实际上他们是一个软连接,指向了实际存放该依赖的地址。那么.pnpm文件夹里存放的是什么呢?
在.pnpm中,以平铺的形式存放着所有的包,相同的包以@version区分,通过包名和版本号,来实现不同包的隔离与复用,由于不存在提升,所以解决了幽灵依赖的问题
.pnpm使用了.pnpm-store作为存储目录,存储所有依赖相关信息的硬链接, 通过访问这些硬链接,可以直接使用文件资源,如果不存在,就会去下载一次,这样相同的依赖最多只会被下载一次。所以解决了依赖重复安装的问题。
关于硬链接软连接www.cnblogs.com/itech/archi…