2023-12-13 浅谈pnpm

什么是幻影依赖

我们知道npm、yarn安装依赖包的时候是平铺的结构,如下图:

疑问:明明我package.json文件里只声明了express一个包,为啥有这么多的包被安装到node_modules目录中?

原因其实也都知道,是express这个包又依赖了其他的包,所以就一起安装进来了

那幻影依赖顾名思义就是没有在package.json文件里声明的依赖又出现在了node_modules目录中,这些依赖在生产版本中可能会造成影响

比如在文件中使用了lodash这个库,但是没有在package.json里声明这个依赖,这个依赖就是上述说的幻影依赖

一般会造成两个问题

一个是版本问题:

项目中声明了A库版本v1,A依赖于B库版本v1,这时候项目直接使用了B库(B库没有声明是幻影依赖);下一次升级A库到v2时候,依赖的B库也可能会升级到v2,这时候项目中使用的还是B库v1的版本,造成代码莫名其妙的报错,这种问题还不好排查,等到发生的时候再排查问题就大了

除了版本问题外,另外的一个问题是依赖丢失的问题:

如果A库是开发依赖,则导致在开发环境使用幻影依赖B库没有问题,但是一旦部署的时候就会导致生产环境没有安装开发依赖,使得B依赖丢失,则项目中使用的这个库找不到了,就会在生产环境上报错,那问题大了

解决方法

发现幻影依赖的本质原因后,解决方法也很简单

一种方法就是直接安装这个幻影依赖,这种做法直接有效,但是有个缺陷,就是有时候项目太大了,安装的依赖包太多了,开发人员不会一一去排查包是否是幻影依赖,会直接使用vscode中的智能提示,但是这种智能提示是根据在node_modules中是否有这个库去显示的,这时候就需要一种工具,提示在package.json中没有声明的依赖,你在代码中使用就要报错,马上提示这个库要安装

经常说的依赖关系树其实是一个依赖图结构,如上左侧所示

而把依赖安装过后,到文件系统中又变成文件树结构如上图中间所示,这种方式最早的时候就是npm用的文件方式这样会有重复文件

后来npm升级后以及yarn出现后就会把依赖安装成上图右边所示,扁平结构,这里就造成了幻影依赖了

使用pnpm

pnpm工具的出现完美的解决了上述问题,使用pnpm安装包后,会出现上图中间和右边所示的关系

首先会有个仓库形式的store,这里存储的是所有的安装包以及其依赖包,中间图所示的还是各个依赖之间的关系,不过是以符号链接-即软连接的方式存储的,实际指向的是store中的文件地址

使用pnpm安装的包,在package.json里未声明的包在node_modules下是找不到的,这样在项目中引入就不会有提示,还会报错,上图右边的小箭头指的就是符号链接也就是软连接,真正的包地址是在./node_modules/.pnpm/express@4.18.2/node_modules/express,express的依赖包又被软连接到.pnpm/node_modules目录下

硬连接:是指向文件或者目录的实际物理位置的直接引用,硬连接创建一个新的文件入口,但不创建新的文件内容,它与原始文件共享相同的inode(文件的唯一标识符)和数据块,因此,对硬连接的任何操作都会直接影响原始文件,删除原始文件或硬连接中的任何一个都不会导致数据丢失,只要至少还有一个硬连接存在

软连接(符号链接):是一种特殊类型的文件,包含了对另外一个文件或目录的引用,类似于快捷方式,软连接不直接指向文件的物理位置,而是通过文件路径名来引用目标文件或目录,当访问软连接时,操作系统会自动将其解析为目标文件或目录,删除软连接不会影响原始文件或目录的存在,但如果目标文件或目录被删除,软连接将变为无效

在pnpm中,默认情况下,使用软连接(符号链接)将项目的直接依赖添加到根目录下的node_modules文件夹下,而.pnpm目录中保存的直接和间接依赖的硬连接

下图是pnpm、npm、yarn的对比

相关推荐
m0_672449601 小时前
基础vue3前端登陆注册界面以及主页面设计
前端·vue.js·elementui
匹马夕阳1 小时前
Vue3中使用组合式API通过路由传值详解
前端·javascript·vue.js
zpjing~.~1 小时前
VUE中css样式scope和deep
前端·css·vue.js
fxshy1 小时前
Vue3父子组件双向绑定值用例
前端·javascript·vue.js
风茫1 小时前
如何在vue中渲染markdown内容?
前端·javascript·vue.js
蓝黑20201 小时前
从Vant图标的CSS文件提取图标文件
前端·css·python·vant
勤劳的进取家2 小时前
XML、HTML 和 JSON 的区别与联系
前端·python·算法
IT培训中心-竺老师3 小时前
Apache Web服务器技术指南 - 基于Kylin麒麟操作系统
服务器·前端·apache
枫叶落雨2223 小时前
03JavaWeb——Ajax-Vue-Element(项目实战)
前端·vue.js·ajax
程思扬4 小时前
Android笔记: 实现点击事件透传到底部
android·前端·windows·经验分享·笔记·科技·ui