浅谈前端包管理器

222 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情

前言

前端最大的文件:node_modules

image.png

npm

npm v1,v2

最早的npm v1,v2版本它是存在以来嵌套的问题

image.png

例如模块A和模块D同时引入模块B就会导致B模块重复现在两次,非常浪费空间,就会造成类似依赖地狱的问题

npm v3

到了V3版本,所谓的扁平化管理,减少了依赖嵌套的问题,但是扁平化这种模式,也带来新的问题,俗称幽灵依赖,

image.png

和这张图表示的是一样的

npm v5

后面到了V5版本,有了锁的概念,项目中会有一个package-lock.json文件,用该文件锁定整个项目所依赖的版本,

package-lock.json具体的作用

首先执行npm install 安装后,会自动生成一个package-lock.json文件,该文件里面记录了package.json依赖的模块,以及模块的子依赖并且给每个依赖标明了版本,获取地址和验证模块完整性哈希值,保障了依赖包安装的确定性与兼容性,使得每次安装都会出现相同的结果

yarn

后面出现了yarn

yarn和npm的区别

  • 1.文本格式不同,npm v5使用的是json格式,yarn使用的是自定义格式

  • 2.package.json文件里记录的依赖的版本都是确定的。不会出现语义化版本范围,符号(-^*) 而yarn.lock文件里仍然会出现语义化版本范围符号

  • 3.package.json文件内容更丰富,实现了更密集的锁文件,包括子依赖的提升信息

其第二个大版本推出了php版本,即零安装版本,放弃了node_modules,更加保证了依赖这种可靠性,安全性,同时间pnp模式,其优点和缺点也非常明显

pnp模式优缺点

  • 1.优点:摆脱node_modules,安装,模块速度加载快
    
              所有npm模块都会存放在全局的缓存目录下,避免重复依赖
    
              严格模式下子依赖不会提升,也避免了幽灵依赖(但这可能会导致某些包出现问题,因此也支持依赖提升的宽松模式:<)
    
  • 2.缺点:自建resolver处理Node require方法,执行Node文件需要通过yarn node解释器执行,脱离Node现存生态,兼容性不太好
    

pnpm

后面又出现了pnpm

其具有安装速度快,节省磁盘空间,安全性好等优点,pnpm他提出了两个概念,一个叫硬链接,他能节省磁盘的空间,还有一种就是符号链接

image.png

pnpm看似解决了yarn和npm遗留的问题,但其也有一定的局限性

pnpm局限性

  • 1.忽略了package-lock.json,npm的锁文件旨在反映平铺的node_modules布局,但是pnpm默认创建隔离布局,无法由npm的锁文件格式反映出来,而是使用自身的锁文件pnpm-lock.yaml

  • 2.符号链接兼容性。存在符号链接不能适用的一些场景,比如Electron应用,部署在lambda上的应用无法使用pnpm。

  • 3.子依赖提升到同级的目录结构,虽然由于Node.js的父目录上溯寻子逻辑,可以实现兼容。但对于类似Egg,Webpack的插件加载逻辑,在用到相对路径的地方,需要去适配

  • 4.不同应用的依赖是硬依赖到同一份文件,如果在调试时修改了文件,有可能会无意中影响到了其他项目

此时nodejs作者提出node_modules是他的十大遗憾之一

image.png

后面他又提出了deno

deno

deno不再使用npm,package.json,node_modules,而是将引入源,包名,版本号全部放入url中,如图

image.png

通过url的导入依赖进行统一的全局管理,不仅节省了磁盘的空间,也优化了整个项目的结构,只是目前deno的方式还不够成熟

总结

所以说结论就是目前还没有非常好的包管理方案,无论所谓的扁平化也好,非扁平化也好,还有pnpm提出的抛弃node_modules模式,我们只能做到以不变应万变,期待后续的统一