【包管理器】一个由第三方包管理器与npm冲突导致的bug

【包管理器】一个由第三方包管理器与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.jsonpackage-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
2
3
4
5
6
7
8
9
10
      {
test: /\.js$/,
loader: 'babel-loader',
- include: [resolve('src'), resolve('test')]
+ include: [
+ resolve('src'),
+ resolve('test'),
+ resolve('node_modules/vue-echarts'),
+ ]
}

配置如同文档所写,也没啥大变化,也没啥特别之处,此方法pass。

尝试使用更改vue-echarts版本

我们项目目前使用的vue-echarts版本是v2.6.0版本,由于往后版本是跳大版本3.0.0,引入的Echarts也是大版本更新到
v4+,所以更新往上只尝试了一个版本,往下尝试了好几个版本,皆无功而返,没有任何用处。所以也就不再去比对新版本带来的特性会对现有的功能造成影响。

由于周五下午了,我们公司搬新大楼,收拾东西,也就没有再细究下去,心思也浮了。

尝试比对源码

当到了这一步的时候,已经周一了,收拾了下新公司楼层座位,便开始了上周的问题,开始静心分析源码。比对了vue-echarts的部分初始化问题,自己的推测大概问题出现在了初始化配置项的问题。于是乎在配置项分析了一会,修改配置,更改项目代码的配置项,发现也没甚问题。

后来觉得是不是vue的生命周期导致echarts初始化问题。修改后发现无效果。

后来干脆把npm下载的vue-echarts源码和cnpm下载可运行的vue-echarts包源码对比,不看不知道,一看哭笑不得。

请看如下图:

other-package-manage-error-main-01.jpg.

当时的心情就是想吐血!!!

所以问题出现在了cnpm居然跳版本安装了带有npm-shrinkwrap.json的项目的依赖!

知道问题所在,解决起来就简单了,将包版本更新至v3.1.3后,确实不会报那个错了。

但是会出现其他问题。原先引用的实例是直接挂在在根上,而今挂在VueECharts上,所以这里只要赋值多加个字段就好了。

分析第三方包管理原因

我对此的猜测是因为两种工具的模块机制不太一样。各位看官可以看看cnpm与npm的模块机制不一样的问题。目前网上还没有相关的讨论,只发现了一篇文章:为什么我从 Npm 到 Yarn 再到 Npm?,后面我会继续更新这篇文章具体探讨一下这一块的问题。个人觉得目前如果项目用的npm都是v6.0+版本的话,建议不要使用第三方包管理器了。

附带个人在项目中的解决方案,使用了黑魔法兼容两者的模块机制不同导致会出现的问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import * as Echarts from 'vue-echarts'
// 由于旧版使用cnpm安装锁定包版本,但是cnpm将vue-echarts版本从2.6.0跳3.1.3版本,所以会出现用npm安装报错问题,现将版本切换至npm的3.1.3,兼容npm可用。还有个深层原因是因为引入模块的机制导致cnpm与npm差异。
if (Echarts) {
window.echarts = Echarts
if (Echarts.VueECharts) {
window.echarts = Echarts.VueECharts
}
} else {
window.echarts = null
}
// Echarts && Echarts.VueECharts ? window.echarts = Echarts.VueECharts : window.echarts = null

// window.echarts = Echarts.VueECharts
console.log(window.echarts)

【包管理器】一个由第三方包管理器与npm冲突导致的bug

https://blog.vadxq.com/article/other-package-manage-error/

作者

vadxq

发布于

2020-11-02

更新于

2020-11-02

许可协议

评论