背景
在大家健康项目用vue重构后,终于在一周前成功上线。但是一番折腾后,上线后正式环境却出现了一些bug,然后在改bug的过程中又导致了一些新bug,道路曲折且离奇,为了避免以后重复踩坑,特整理了一下遇到的问题以及解决方案,并持续更新中。
问题列表
持续更新中…
-
Cannot read property ‘call’ of undefined
-
该bug出现的原因是,删除package-lock.json文件重新打包上线,导致webpack版本自动升级到最新版本4.28.x,该版本下的webpack在打包构建时无任何报错信息,但是在运行时会部分安卓机型会报“Cannot read property ‘call’ of undefined”的错误,导致页面空白。
-
本地复现之后的定位结果是webpack运行时缺少了某个模块,重新添加package-lock.json,并将webpack的版本降级到4.17.1,重新部署上线后错误得到解决。
-
但是之后在还原到之前出错对应的webpack版本下,并revirson到之前的代码,也并没有复现出来该错误。。。
-
修正:之前定位到的出现这个错误的原因是wepack版本的原因导致的,其实不然。我们在之后的一次上线中,又一次的导致了线上的“Cannot read property ‘call’ of undefined”,于是我们猜测之前的判断是错误的。经过一段时间的重新定位过后,发现原因是我们的cdn惹的祸。
-
本地复现规则: 使用上一个版本的entry.js,然后其余的内部逻辑js使用当前版本的,本地运行, “Cannot read property ‘call’ of undefined”,并且页面无法正常打开。
-
我们发现webpack打包之后的入口文件entry.js比较大,如果我们修改了entry.js的相关代码导致hash改变,比如从 entry.js?hash1 变为了 entry.js?hash2,正常情况下,cdn会比对比两个相同的文件(因为cdn那边不认识我们?后面的hash部分,所以会认为是请求同一个文件),然后进行一个同步过程。由于我们entry.js文件相对较大,而且网络环境也可能较差,这就会导致一部分地区同步过程较长或者直接卡顿,这样的话可能就会导致加载老的cdn资源,就导致了上述的复现步骤。
-
我们通过修改webpack打包js的hash命名规则,来强制每次重新打包后,cdn每次都去加载新的js资源,解决了以上问题。
//new output: { path: path.resolve(__dirname, './dist' + _env.outputPath), filename: 'wx/[name]_[chunkhash].js', chunkFilename: 'wx/js/[name]_[chunkhash].js', }, //old output: { path: path.resolve(__dirname, './dist' + _env.outputPath), filename: 'wx/[name].js?[chunkhash]', chunkFilename: 'wx/js/[name].js?[chunkhash]', },
-
-
填写问诊单无法点击下一步 && 聊天页没有消息记录
-
填写问诊单无法点击下一步,起初认为是微信内核原因(因为之前有一例同样的无法点击问题,通过让用户重新卸载安装微信解决),设置了断点上报,也并没有发现问题。然后该用户又反应,医生列表页点击咨询无反应。
-
继续排查日志发现该出问题的用户的机器为ios7.x的苹果手机,然后就怀疑是不是系统太低的原因。
-
找到一台ios8的测试机,发现页面报错,“unhandled promise rejection”,并且后来也成功复现该用户的行为,问诊单下一步和医生列表页的咨询按钮均无法点击,由此猜测就是该错误导致的。查了一下资料,发现这个错误可能会出现在低版本的安卓和ios机器中,浏览器不兼容Promise导致的错误。
-
解决办法:下载babel-polyfill,并在入口entry配置数组的第一个元素中加上”babel-polyfill”
let ret = { entry: { entry: ["babel-polyfill",_env.inputPath + '/entry.js'], //添加babel-polyfill }, output: { path: path.resolve(__dirname, './dist' + _env.outputPath), filename: 'wx/[name].js?[chunkhash]', chunkFilename: 'wx/js/[name].js?[chunkhash]', }, ... }
- 另一个聊天页无法显现消息记录的那个用户,同样是一个问题,咨询页报错导致了无法正常加载。上线babel-polyfill后也成功修复。
-
-
公众号页面字体被放大
-
原因是该用户可能在本公众号或者别的公众号手动设置过字体大小,这种改动是持续性并且保持性的,不随公众号的不同而不同,也不随微信退出而恢复,除非用户再手动设置成常规大小,所以我们需要在我们的公众号中做逻辑强制字体以正常大小去显示。这里ios和安卓的设置方式有所不同。
- ios:
body{ -webkit-text-size-adjust: 100% !important; text-size-adjust: 100% !important; -moz-text-size-adjust: 100% !important; }
-
安卓:
function setPageSize() { if (typeof (WeixinJSBridge) == "undefined") { // eslint-disable-line document.addEventListener("WeixinJSBridgeReady", function (e) { // eslint-disable-line if (typeof (WeixinJSBridge) != "undefined"){ // eslint-disable-line // 设置网页字体为默认大小 WeixinJSBridge.invoke('setFontSizeCallback', { // eslint-disable-line 'fontSize': 0 }); // 重写设置网页字体大小的事件 WeixinJSBridge.on('menu:setfont', function(){ // eslint-disable-line WeixinJSBridge.invoke('setFontSizeCallback', { // eslint-disable-line 'fontSize': 0 }) }) } }); } else { // 设置网页字体为默认大小 WeixinJSBridge.invoke('setFontSizeCallback', { // eslint-disable-line 'fontSize': 0 }); // 重写设置网页字体大小的事件 WeixinJSBridge.on('menu:setfont', function(){ // eslint-disable-line WeixinJSBridge.invoke('setFontSizeCallback', { // eslint-disable-line 'fontSize': 0 }) }) } }
-
-
微信支付始终无法唤起密码框
-
从老早以前,线上零零散散就有一些微信无法支付的问题,具体表现就是点击支付无任何反应,起初认为是微信jssdk的不稳定问题(因为有的用户重新卸载微信后就可以正常使用),到后来又认为是我们的授权目录配置问题(也只是猜测),直到我们复现出来。
-
复现的过程中我们发现,不仅仅是微信支付用不了,所有和我们项目中微信jssdk相关的,都是无法正常使用的,也不会报错。但是都有一个同样的表现,就是weixin.ready()回调都没有执行(fail,success,cancel都没有进入),看样子就是微信jssdk的config都没有执行;
-
刚开始,我们的入口html文件中是这样的,引入了两个远程js库
< body> < script> !(function(c,b,d,a){c[a]||(c[a]={});c[a].config={pid:pid,imgUrl:imgUrl,enableSPA:true}; with(b)with(body)with(insertBefore(createElement("script"),firstChild))setAttribute("crossorigin","",src=d) })(window,document,"https://retcode.alicdn.com/retcode/bl.js","__bl"); < /script> < script src="https://jic.talkingdata.com/app/h5/v1?appid=appid&vn=djjkversion&vc=version" async>< /script> < /body>
在让用户帮忙调试的过程中,我们发现,在注释掉这两个库之后jssdk正常,加上就不行。猜想是用户在加载这两个外部js的时候,由于网络或者各种原因导致加载过程中比较缓慢甚至卡住,导致的jssdk无法正常运行;
-
于是我们本地也是添加了一个加载脚本,用一个google请求来模拟加载缓慢的情况
< body> < script src="http://maps.google.com/maps/api/js?sensor=false&libraries=geometry&v=3.7" async></script> < /body>
发现成功模拟出了用户的那种情况,在google.js下载的过程中,weixin.ready()始终没有运行,直到google.js下载连接超时(大概等了几分钟,请求状态从pending变成了加载失败),这时才弹出weixn.ready成功的提示。
-
得出结论:我们在微信浏览器中,html里面下载js的任务(即使加上了async),和微信jssdk的config过程,是放在了同一个任务队列中,而且js的下载在队列中是排在config前面的,所以才会出现在下载google.js超时以后 才收到weixin.ready()成功的通知
-
这样解决问题就变得很简单了,尽量避免直接去加载远程的cdn js文件,如果不能避免,可以在微信jssdk ready后,再去动态的加载所需要的远程js文件
-