背景
安卓上架vivo应用商店时,因为一级页面有内嵌H5,所以在低版本安卓(5.1.1)出现白屏,测试不通过,导致无法上架。经过定位,安卓应用初始化下载X5内核尚未完成,加载国产的webview内核,然后webview版本过低导致出现兼容问题。
解决过程
由于没有真机来调试, 所以想到通过android模拟器定位,由于应用只支持arm架构,所以无法在x86模拟器安装(android studio 虽然支持arm架构,但是性能很差基本无法使用),所以直接在模拟器默认浏览器定位, 浏览器版本如下
Mozilla/5.0 (Linux; Android 5.1.1; Android SDK built for x86 Build/LMY48X) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Mobile Safari/537.36
通过chorme的inspect
链接到模拟器, 调试后发现是由于部分代码,babel未编译到es5代码导致的。经过查阅资料。
所以通过以下两个方面来解决。
-
.browserslistrc 调整兼容范围 安卓4.4 是vue支持的最低版本,and_chr 30 是vivo低版本webview内核的版本。
android >= 4.4 ios >= 13 chrome > 66 and_chr >= 30 and_qq >= 10 not dead not ie 11
-
vue.config.js babel 编译范围调整。 vue cli 默认读取browserslist配置来决定项目需要的 polyfill,但是不包含node_modules。会导致打包之后的产物中会包含有es6 语法。 vue cli 提供了
transpileDependencies
配置来设置那些文件需要被编译。此时有个大坑,官方文档没有标注版本。文档上transpileDependencies
是支持配置true
, 直接全部编译的, 但是这个其实只有vuecli 5.x 支持这么配置。4.x需要自己做配置,配置如下{ transpileDependencies:[/[\\/]node_modules[\\/](?!(core-js|webpack|webpack-4|css-loader|mini-css-extract-plugin|promise-polyfill|html-webpack-plugin|whatwg-fetch))/, /[\\/]src[\\/].*\.js/], }
最开始的尝试是将node_modules下的所有文件都编译的,但是打包后发现不光是低版本浏览器无法正常打开,连现代浏览器也报错了,通过对vue cli 5.x 源码的阅读发现, 有些devDependencies是不需要编译,不然会报错, 所以需要忽略掉这些package。
-
重新打包发布
拓展
除非有特别强烈的低版本兼容需求,不推荐使用这种方法来做兼容,该兼容方法,会导致打包的速度变慢,打包的产物变大,有一定的性能损耗。以当前chrome 36两个突出问题,const 和 箭头函数来看, 不支持的浏览器市场占有率还是比较低的。做兼容是一个取舍的问题,想要更好的兼容就意味者增大更大补丁体积, 所以相对怎么做兼容来说,我觉的更重要的应该是我们首先要明确需要兼容到什么版本,是不是要为0.0.1%的用户来牺牲一部分其他用户的体验还有成本,并且这0.0.1%的用户是否真的是你的潜在用户。
有没有两全其美的方案呢,其实是有的,但是搭建成本和维护成本,在你做之前希望先评估好。
后续需要参考polyfill.io 做一套私有化的polyfill方案来做兼容处理,但是这个要依赖于webview的UA,所以又回到了上一篇关于UA的文章由UserAgent问题翻开的一则旧闻,要求webview的UA 一定要标准化不能不设置或者错误的设置
详细关于polyfill的方案可以参考@sorrycc的Polyfill 方案的过去、现在和未来的这篇讨论。