工程化-包管理工具

128 阅读2分钟

npm与yarn

安装依赖

npm@3之前,npm使用的是嵌套安装,即每个package都会有自己的node_modules文件夹,这种结构有两种严重的问题:

  1. package中经常创建极深的依赖树,这会造成目录路径过长的问题
  2. 当一个依赖项在不同packages都依赖时,该依赖项会被重复安装,本地磁盘就会存放多个相同的包。

为了解决这些问题,npm@3yarn引入了扁平化结构,node_modules变成所有包存放在同一层级,以上面的例子,a和c都依赖b,那么b就会被提升到a和c的同一层级。值得注意的是,同一个包的不同版本只会有一个被提升,具体提升的是哪个版本取决于依赖它的包在package.json中的先后顺序。

然而这又会导致一个问题,由于依赖结构的不确定性,导致扁平化结果的不确定,于是又出现了package.lock.jsonyarn.lock来保证install后的扁平化结果的确定性。

还有一个问题就是幽灵依赖,即某个包没有在package.json中被依赖,但用户仍能引用到这个包,这是由于扁平化结构导致依赖项层级被提升。这种幽灵依赖可能会导致问题,比如以下场景:

  1. 旧版本A和旧版本C依赖B,可以直接引用到B,而A更新后,B的版本被更新,API发生变化,而C使用B的旧版本API,导致错误。
  2. 旧版本A和旧版本C依赖B,可以直接引用到B,而A更新后,B不再被依赖,那么C就不会再被提升,直接引用C就会报错。

还有一个问题是重复安装,如图

图片.png

pnpm

pnpm解决了幽灵依赖和重复安装依赖的问题。pnpm项目安装的node_modules结构如下

图片.png

可以看到,node_modules里只存在package.json里的直接依赖,和一个.pnpm文件夹,而且这些直接依赖文件夹旁边有一个箭头,实际上他们是一个软连接,指向了实际存放该依赖的地址。那么.pnpm文件夹里存放的是什么呢?

图片.png

图片.png

.pnpm中,以平铺的形式存放着所有的包,相同的包以@version区分,通过包名和版本号,来实现不同包的隔离与复用,由于不存在提升,所以解决了幽灵依赖的问题

.pnpm使用了.pnpm-store作为存储目录,存储所有依赖相关信息的硬链接, 通过访问这些硬链接,可以直接使用文件资源,如果不存在,就会去下载一次,这样相同的依赖最多只会被下载一次。所以解决了依赖重复安装的问题

关于硬链接软连接www.cnblogs.com/itech/archi…