【包管理器】一个由第三方包管理器与npm冲突导致的bug
这是一个神奇的bug,也是一个花费时间的bug哈哈哈。当遇到这种类型的bug确实会出现挺难下手的尴尬之处。
下面便是我对这个bug的折磨历程,对,我对它的折磨!
项目背景与问题分析
这是一个老项目,可能由于以前跳版本出现问题,前辈固定了版本,使用的是npm shrinkwrap
来固定版本,但由于前辈使用的是cnpm,所以当是形成的依赖包名字是下划线开头的。当后人使用npm安装的时候,便出现了这样的问题:
npm ERR! Invalid package name "_@types_babel-types@7.0.4@@types": name cannot start with an underscore; name can only contain URL-friendly characters
报错原因如字面意思,包名不够友好。所以问题在于包的问题
尝试使用固定依赖包解决问题
当发现这一步的时候,便开始了npm更多可能性的探索历程。npm-shrinkwrap.json文件,我也是第一次见,现在一般用lock用的多些。下面是他们的区别。
- npm-shrinkwrap.json与npm v2/3/4或者是后面的兼容,而package-lock.json仅可在npm v5+版本可用
- package-lock.json不在文件的根目录将会被忽略,但须依赖shrinkwrap文件
- npm-shrinkwrap.json其他人安装依赖必须是一样的,而package-lock.json准确记录您安装的依赖项的版本,其他人则可以安装规定的范围内兼容的依赖项的任何版本
处理方法是使用很笨的方法,将包全部提取出来固定的版本,然后将npm-shrinkwrap.json
和package-lock.json
文件删除,手动npm i
,再将新生成的package-lock.json
重新生成一份npm-shrinkwrap.json
。
结果:解决的大部分安装包问题,但是有一个包出现错误。那就是vue-echarts
。报错信息如下:Uncaught TypeError: Cannot use 'in' operator to search for 'default' in undefined
尝试使用webpack解决问题
出现了如上结果,TypeError,问题错误显示错在vue-echarts
上,于是乎,google搜索了以下问题,也去github issues搜索了遍,包的issue确实出现过问题,但是并没有什么解决方案。后来查找到了此条TypeError: Cannot use ‘in’ operator to search for ‘default’ in undefined #1407,问题提在了rollup上,看了下,好像是说是升级版本可用,同是打包工具,盲猜是不是因为webpack引入问题。于是乎便重新看了下webpack配置,看看引入vue-echarts
的webpack有没有黑魔法。
1 | { |
配置如同文档所写,也没啥大变化,也没啥特别之处,此方法pass。
尝试使用更改vue-echarts版本
我们项目目前使用的vue-echarts
版本是v2.6.0版本,由于往后版本是跳大版本3.0.0,引入的Echarts也是大版本更新到
v4+,所以更新往上只尝试了一个版本,往下尝试了好几个版本,皆无功而返,没有任何用处。所以也就不再去比对新版本带来的特性会对现有的功能造成影响。
由于周五下午了,我们公司搬新大楼,收拾东西,也就没有再细究下去,心思也浮了。
尝试比对源码
当到了这一步的时候,已经周一了,收拾了下新公司楼层座位,便开始了上周的问题,开始静心分析源码。比对了vue-echarts的部分初始化问题,自己的推测大概问题出现在了初始化配置项的问题。于是乎在配置项分析了一会,修改配置,更改项目代码的配置项,发现也没甚问题。
后来觉得是不是vue的生命周期导致echarts初始化问题。修改后发现无效果。
后来干脆把npm下载的vue-echarts
源码和cnpm下载可运行的vue-echarts
包源码对比,不看不知道,一看哭笑不得。
请看如下图:
当时的心情就是想吐血!!!
所以问题出现在了cnpm居然跳版本安装了带有npm-shrinkwrap.json
的项目的依赖!
知道问题所在,解决起来就简单了,将包版本更新至v3.1.3后,确实不会报那个错了。
但是会出现其他问题。原先引用的实例是直接挂在在根上,而今挂在VueECharts上,所以这里只要赋值多加个字段就好了。
分析第三方包管理原因
我对此的猜测是因为两种工具的模块机制不太一样。各位看官可以看看cnpm与npm的模块机制不一样的问题。目前网上还没有相关的讨论,只发现了一篇文章:为什么我从 Npm 到 Yarn 再到 Npm?,后面我会继续更新这篇文章具体探讨一下这一块的问题。个人觉得目前如果项目用的npm都是v6.0+版本的话,建议不要使用第三方包管理器了。
附带个人在项目中的解决方案,使用了黑魔法兼容两者的模块机制不同导致会出现的问题
1 | import * as Echarts from 'vue-echarts' |
【包管理器】一个由第三方包管理器与npm冲突导致的bug