因为使用peerDependencies而引发的bug

简介: 因为使用peerDependencies而引发的bug

前言


前几天有个人跟我反馈说,她fork了我右键菜单那个开源项目,一直无法打包成功。我寻思着应该不可能吧,当我尝试打包时,果然翻车了🤡。


经过了一番调试后,终于找到了问题所在,本文就跟大家分享下这个问题从发现到解决的整个过程,欢迎各位感兴趣的开发者阅读本文。


排查问题


因为我电脑重装过几次系统,一些放在github上的项目我就没有备份,我把项目(https://github.com/likaia/vue-right-click-menu-next/)重新clone到本地,安装依赖项后运行了build命令,意想不到的事情发生了:它报错了😿


ERROR  Failed to compile with 4 errors                                                                                                                                                                        11:02:26 AM
error  in ./src/components/right-menu.vue
Module parse failed: Unexpected token (1:0)
File was processed with these loaders:
 * ./node_modules/eslint-loader/index.js
You may need an additional loader to handle the result of these loaders.


640.png

                               image-20210912110303981


上述报错的意思是找不到处理vue文件的相关loader,我就纳闷了,这不可能啊,几个月前插件写好时还能打包的,现在咋就突然不能打包了呢。


可能是node版本的问题


难道是我node版本的问题?插件写好到现在代码一直没动过,唯一变化的就是我升级了node版本,降级node版本太麻烦,于是我安装了node版本管理工具n


因为我的系统是macos,我可以直接用brew来安装它,命令如下:


brew install n


如果你是windows系统,你可以通过npm包的形式来安装它,命令如下:


npm install -g n


安装完成后,我去找了下我写这个项目时所发布的node版本v14.14.0,我们用n工具来安装并切换它:


n 14.14.0


我们运行node --version命令看下是否成功。


640.png

                             image-20210912112948408


一切准备就绪,我寻思着应该不会出现问题了吧😼,结果运行后,我傻眼了,仍然报着同样的错误🤧


640.png

                                   image-20210912110303981


node版本管理工具有挺多的,除了文中说的n还有nvmnpx,感兴趣的开发者可自行了解。


发现猫腻(yarn.lock)


当我一筹莫展发呆时,突然发现目录树中的yarn.lock变色了,看来是有改动了,我寻思着不可能啊,我没动package.json中的依赖项啊,怎么会发生变化呢?


640.png

                                 image-20210912115021573


重新创建个项目试试


既然lock文件发生了变化,那我重新创建个项目试试,把相关依赖项拷过去再打包看看。


我们继续使用Vue CLI作为插件搭建环境,对此不熟悉的开发者请移步我的另一篇文章:使用CLI开发一个Vue3的npm库


vue create test-vue3-project


项目创建完成后,我把相关文件拷贝了过去,修改了package.json中的build命令。


{
  "build": "vue-cli-service build --target lib --name vueRightMenuPlugin src/main.ts"
}


运行命令后,它居然打包成功了🌝


640.png

                                      image-20210912120532953


找到问题


经过前面的一番折腾,创建了一个新的项目他就好了,那我比对下这俩项目有啥不同之处,那么问题就迎刃而解了。


经过比对后,我发现了package.json中的不同之处:


"dependencies": {
    "core-js": "^3.6.5",
    "vue": "^3.0.0"
  }
"peerDependencies": {
    "core-js": "^3.6.5",
    "vue": "^3.0.0"
  }


区别就在于,vuecore-js这两个包的位置,问题应该就出在这里了。


我们来验证下吧,将dependencies中的那两个包放到peerDependencies中,重新install下,再build看下。


不出意料,果然报错了。


640.png

                             image-20210912131448829


那么为啥我的项目之前能跑,现在却没法跑了,我想应该是因为之前改了后,我没有重新install的缘故吧🌝。


解决问题


那么,既然找到问题了,我们反过来,把右键菜单的peerDependencies下的两个包放到dependencies下,再看看问题能否得到解决。


当我满怀信心的执行build命令后,结局却让我很失望。


是的,他换了个错误🌚


640.png

                               image-20210912132222990


看报错是类型无法自动推导,这就很怪异了。那么就只能尝试下我的三板斧了:


  • 重启软件
  • 重启电脑
  • 删除项目,重新clone,重新install依赖


前两个尝试过后,发现并无卵用,只好用了最后一个方法。


重新install后,执行了build命令,成功解决了这个问题。


640.png

                                      image-20210912132919200


为什么呢


问题是解决了,那么为什么要那样做呢?接下来就带大家深入研究下dependenciespeerDependencies


dependencies


dependencies是package.json中的一个属性,里面放运行代码时所需的依赖,在install时这些包会被安装,打包项目时,这里面的包也会被打包进去。


peerDependencies


peerDependencies也是package.json中的一个属性,这个单词翻译过来是对等依赖的意思,这里面的包在install时并不会安装,打包项目时,这里面的包也不会被打包进去。


两者存在的问题


如果将依赖包放在dependencies下,那么当别人在他的项目中引入你的插件时,会出现下述情况:


  • 他项目里没有引入你所需的依赖包,那么你插件所依赖的包会被安装
  • 他项目里引入了你所需的依赖包:
  • 版本号一致,那么你所需的依赖包不会被安装,插件将共用项目里的依赖包
  • 版本号不一致,那么你所需的依赖包就会被安装,项目里就存在了两套不同版本的依赖


版本号一致那还好,万事大吉。版本号不一致时,你插件所依赖的那个包需要的功能与调用者项目里安装的那个版本的包并无区别,那么调用者的项目将变得臃肿起来,又多安装了一份依赖。


如果将依赖包放在peerDependencies下,对插件开发者是不友好的,会出现下述问题:


  • install的时候,所需的依赖不会安装,使用ide开发时会报错找不到相关依赖。

image-20210912140550142

  • build的时候,因为依赖未安装,导致无法打包(文章开头提到的报错)

这么看的话,peerDependencies这个属性,好像没啥用了。当然存在即合理,如果大家有什么更好的看法,欢迎在评论区留言讨论。


解决方案


知道他们各自的优点和缺点后,我也就知道了如何解决这个问题。


既然dependencies中的依赖包只要和调用者的版本号一致,就不需要重新安装依赖,那我们把它的版本号放开,给个范围,这样不就可以了😁


在package.json中的版本号可以带下述符号:


  • ~波浪号,匹配最新补丁版本号,即版本号的第三个数字,例如~3.0.0就会匹配3.0.x版本,将在3.1.0停止
  • ^插入符号,匹配次要的版本号,即版本号的第二个数字,例如^3.0.0就会匹配任何3.x.x版本,将在4.0.0停止
  • >、<、>=、<=比较运算符,匹配的就是这个区间的版本,例如>3.0.0 <= 3.1.4,就会匹配这个区间的版本号


如果不带符号,那么它就是精确匹配。


本文中,用的是^3.0.0,满足了我们插件的使用场景,因此不需要更改。


写在最后


至此,文章就分享完毕了。


我是神奇的程序员,一位前端开发工程师。


  如果本文帮到了你,那就点个“在看”吧。

相关文章
|
JavaScript 前端开发
vue 实现word文档预览和下载
vue 实现word文档预览和下载
1163 0
|
前端开发
Window对象提示框、确认框、输入框、弹窗详解
本文目录 1. 背景 2. alert提示框 3. confirm确认框 4. prompt输入框 5. showModalDialog弹窗 6. 小结
1488 0
Window对象提示框、确认框、输入框、弹窗详解
|
前端开发 开发者
【微信公众号对接】有关签名一直报错,提示invalid signature问题(我的签名和使用微信开发者工具验证返回的签名的是一致的)但还是报错!!!
【微信公众号对接】有关签名一直报错,提示invalid signature问题(我的签名和使用微信开发者工具验证返回的签名的是一致的)但还是报错!!!
853 0
|
编解码 JavaScript 前端开发
jsQR 一个完全独立的javascript 二维码识别库
jsQR 是一款纯粹的由javascript实现的二维码识别库,可以在浏览器端使用,也可以在后端node.js环境使用。我之前使用过其他的识别库,例如:qrcode-reader 或其他,在使用上都比较麻烦,而且识别率并不高。jsQR是后来发现的,感觉(没有实际对比验证)jsQR识别率要更高些,使用起来也更简单,不需要安装其他依赖软件。
jsQR 一个完全独立的javascript 二维码识别库
|
XML Java 数据格式
Spring注解开发管理第三方bean及依赖注入
Spring注解开发管理第三方bean及依赖注入
243 0
|
Docker 容器
docker的导入本地镜像和导出本地镜像
本文介绍了如何使用Docker对本地镜像进行导入和导出操作,包括从本地导入`nginx.tar`镜像以及将`open-webui`镜像导出并压缩为`open-webui.tar.gz`。
1292 1
|
SQL JSON Java
springboot 如何编写增删改查后端接口,小白极速入门,附完整代码
本文为Spring Boot增删改查接口的小白入门教程,介绍了项目的构建、配置YML文件、代码编写(包括实体类、Mapper接口、Mapper.xml、Service和Controller)以及使用Postman进行接口测试的方法。同时提供了SQL代码和完整代码的下载链接。
springboot 如何编写增删改查后端接口,小白极速入门,附完整代码
|
JavaScript 前端开发 Linux
在 Node.js 和 Electron 中获取设备 UUID 的最佳实践
【JS】在 Node.js 和 Electron 中获取设备 UUID 的最佳实践
921 1
|
JSON 前端开发 JavaScript
成功解决:[object Object]
这篇文章讨论了在JavaScript中打印对象时出现的"[object Object]"问题的原因,并提供了使用`JSON.stringify()`方法将对象转换为字符串以便于打印和调试的解决方案。
成功解决:[object Object]
|
Linux
深入理解Linux虚拟内存管理(七)(上)
深入理解Linux虚拟内存管理(七)
302 1