当前位置: 首页 > 科技观察

使用PeerDependencies导致的BUG

时间:2023-03-13 18:52:21 科技观察

前言前几天有人向我反映,她fork了我右键菜单里的开源项目,一直没有打包成功。本来以为不可能,结果想打包的时候,车翻了??。经过一番调试,终于找到了问题所在。本文将与大家分享从发现到解决的全过程。欢迎有兴趣的开发者阅读本文。排查问题是因为我在电脑上重装了几次系统,而且github上有些项目我没有备份。我重新安装了项目(https://github.com/likaia/vue-right-click-menu-next/)clone到本地,安装好依赖后运行build命令,意想不到的事情发生了:报错??*./node_modules/eslint-loader/index.js你可能需要一个额外的加载器来处理这些加载器的结果。出现上述错误的意思是找不到处理vue文件的相关loader,为什么现在突然不能打包了?可能是node版本的问题?我的节点版本有问题吗?代码自从写了插件就没动过。唯一改变的是我升级了节点版本。降级node版本太麻烦,所以安装了node版本管理工具n。因为我的系统是macos,可以直接用brew安装,命令如下:brewinstallsn如果你是windows系统,可以通过npm包安装,命令如下:npminstall-gn安装完成后就是完成,我去我写这个项目时发布的node版本v14.14.0,我们使用n工具安装切换:n14.14.0我们运行node--version命令看是否成功。万事俱备,本以为应该不会有什么问题??,但是运行之后,傻眼了,还是报同样的错误??node版本管理工具挺多的,除了文中提到的n,还有nvm、npx,有兴趣的开发者可以自行学习。Foundtricky(yarn.lock)正在发呆不知所措的时候,突然发现目录树中的yarn.lock变色了。似乎发生了变化。我认为这是不可能的。我没有触及package.json中的依赖项,怎么会变呢?尝试创建一个新项目。由于锁文件变了,我就尝试新建一个工程,把相关依赖复制过来打包。我们继续使用VueCLI作为插件来搭建环境。对此不熟悉的开发者请移步我的另一篇文章:使用CLI开发一个Vue3npm库vuecreatetest-vue3-project项目创建好后,我会把相关文件拷贝过去,package中的build命令.json已修改。{"build":"vue-cli-servicebuild--targetlib--namevueRightMenuPluginsrc/main.ts"}运行命令后,就打包成功了??找到问题后,经过一番折腾,新建了一个项目。那好,那我就比较一下这两个项目的区别,然后问题就解决了。对比之后发现package.json的区别:"dependencies":{"core-js":"^3.6.5","vue":"^3.0.0"}"peerDependencies":{"core-js":"^3.6.5","vue":"^3.0.0"}区别在于vue和core-js这两个包的位置,问题应该出在这里。我们来验证一下,把dependencies里面的两个包放到peerDependencies里面,重新安装,然后build。不出所料,这是错误的。那为什么我的项目以前可以运行,现在不能运行了,我想应该是我之前改完之后没有重新安装吧??。解决问题既然已经找到问题所在,那么我们反过来把右键菜单中peerDependencies下的两个包放到dependencies中,看看能否解决问题。当我满怀信心地执行构建命令时,结局却让我大失所望。是的,他改错了???image-20210912132222990报错是不能自动推导类型,很奇怪。那我只能试试我的三招:重启软件,重启电脑,删除项目,重新克隆,重新安装依赖。经过前两次尝试,发现没有用,只好用最后一种方法。重新安装后,执行build命令,成功解决了这个问题。为什么?问题解决了,那你为什么要这么做呢?接下来,我将带大家深入研究一下dependencies和peerDependencies。dependenciesdependencies是package.json中的一个属性,包含了运行代码所需要的依赖。安装的时候会安装这些包,打包项目的时候也会打包里面的包。peerDependenciespeerDependencies也是package.json中的一个属性。这个词翻译成点对点的依赖关系。安装的时候不会安装里面的包,打包项目的时候也不会打包进去。两者存在的问题如果你把依赖包放在dependencies下,当别人在他的项目中引入你的插件时,会出现以下情况:如果他的项目中没有引入你需要的依赖包,那么你的插件将安装依赖包。你需要的依赖包是在其他项目中引入的:如果版本号相同,那么你需要的依赖包就不会被安装,插件会共享项目中依赖包的版本号。会安装依赖包,项目中有两组不同版本的依赖版本号,没关系,万事大吉。当版本号不一致时,你的插件所依赖的包所需要的功能与调用方项目中安装的包的版本相同,这样调用方的项目就会变得臃肿,需要安装额外的依赖。如果依赖包放在peerDependencies下,对插件开发者不友好,会出现以下问题:安装时,需要的依赖会安装不上,使用IDE开发会报错,无法使用找到相关的依赖项。构建的时候,因为没有安装依赖,所以无法打包(文章开头提到的错误)。这样看,peerDependencies这个属性好像没什么用。当然,存在是合理的。如果大家有更好的意见,欢迎在评论区留言讨论。解决方案知道了各自的优缺点,也就知道如何解决这个问题了。既然dependencies里面的依赖包只要和调用者的版本号一样就不需要重新安装了,那我们就放开它的版本号,给它一个范围,这样就可以了??package.json中的版本号可以有以下符号:~波浪号,匹配最新的补丁版本号,即版本号的第三个数字,例如~3.0.0将匹配版本3.0.x,以及将在3.1.0^caret处停止,匹配Minor版本号,版本号的第二位,例如^3.0.0将匹配任何3.x.x版本,将在4.0.0处停止>,<,>=,<=比较运算符,matching就是这个区间的版本号,比如>3.0.0<=3.1.4,就会匹配这个区间的版本号。如果没有符号,则为完全匹配。本文使用^3.0.0,符合我们插件的使用场景,所以不需要改动。