前两天在项目中遇到一个IE兼容的问题,解决的过程需要记录并反思。
发现bug
项目进入到了测试阶段,有个IE11和Edge下兼容问题的的issue指派给我。我在IE下打开发现直接白屏。
定位bug
控制台看了下DOM结构没有构建出来,坑爹玩意,心想着编什么理由好像也蒙混不过去挑战来了,我就喜欢解决这种难题。
控制台报错,定位到是const那一行,查询了一下IE11兼容,const是支持IE11的,怀疑是箭头函数,查了一下果然是。我本地是配置了babel的编译的,看样子是babel没有执行。
查看本地工程配置文件.umirc.js,设置了兼容到IE11。先排除掉.umirc.local.js对.umirc.js的影响。看了下官方文档没有头绪。常识性的去讨论群里问大佬。
点进去一看,之前看过这个帖子uglify 压缩报错问题及 es5-imcompatible-versions。
产生原因
因为兼容及项目优化,线上的代码是经过工程"编译"的。"编译"会根据配置使用babel将不兼容的代码"编译"为浏览器兼容的。
默认情况下框架只会编译自己写的代码,依赖包不会"编译"(考虑性能问题)。有个约定俗称的规则是发表在npm中的包都会提供一份不必"编译"就可执行的代码。而有些包没有遵循这些规范,里面写的ES6语法浏览器不认识。
具体到本项目是某个依赖包里的箭头函数没有经过"编译"就被打包了,箭头函数导致IE的执行报错。
解决问题的大概思路也有了,找到有问题的包,fork es5-imcompatible-versions项目,给项目提PR,项目管理者把我代码加入到项目。以后每次build时遇到我加入的包就会进行babel编译。
定位bug产生位置
现在能做的就是找到这个包,例子中打包的过程中就报错了,在打包阶段就可以定位到问题。但我的是打包成功,执行环境里面报错,执行环境里面的代码都是压缩过的,很难看出端倪。
没有思路我又去问大佬了,大佬没理我,那我先自己想想办法。
- 首先es5-imcompatible-versions项目中已经提交的包可以在我的packages包里排除掉。
- 其次一些下载量动则上千万的包肯定是不会犯那么低级的错误,即使犯了,使用的人数多,也会被人提交到列表里。
- 可以去npm官方看下包的周下载量,下载量低的可能性就大。
在以上综合条件筛选后确定了两个最有可能的包。
从项目中把引用这个包的相关JS文件递归式的找出来从项目里剔除掉,打包好放nginx里,不报错就证明是那个包的问题。通过这个方法我找到了那个依赖包。
到现在为止感觉这个bug解决了70%。
如何解决
解决方法之前已经说过了,我fork项目后正准备添加。突然意识到,这个包是半年前加入到项目中的,现在不是最新版本。
我尝试性的把包升级到最新,打包项目,放nginx,用IE访问,没报错!!!
至此,只升级了依赖包就解决了问题。