微信小程序兼容性问题
微信小程序发布一周多了,兼容性问题,特别是 Android 平台兼容性问题特别严重。据我观察,好多小程序掉到兼容性的坑里。掉坑里不要紧,更让人捉急的是,从坑里爬上来的时候,手刚抓到坑沿,又被微信官方踩到(紧急修复兼容性的版本没审核通过,被微信打回重审),再次跌落坑底,然后眼睁睁地看着后台用户在破口大骂“什么东西都没有啊~,什么破小程序”。
微信小程序的兼容性问题除了微信本身的 Bug 外,大部分是目标平台对 JavaScript 标准库支持程度不同造成的。
微信本身的 Bug 引起的
微信本身的 Bug 引发的兼容性问题有个现成的例子,就是 wx.request() 返回的状态码 res.statusCode 的值在 iOS 下是 int 型数据,而在 Android 6.0.1 上却是 String 型数据。如果你判断服务器的返回状态码方法不当,可能就踩到坑里了。
wx.request({ url: 'https://api.example.com', success: function (res) { if (res.statusCode === 200) { // success } else { // server failure } } })
上述代码就踩坑了,正确的做法是使用 == 而不是使用 === 来判断。另外一个更规范的方法是使用 parseInt(res.statusCode) === 200 来实现。
Javascript 标准库兼容性问题
比如 Array.find() 方法在 iOS 10.2/Android 7.0 上完美支持,但在 Android 6.0.1 上却不支持。如果代码里用到了这个接口,就会导致在 Android 6.0.1 上无法正常工作。通过对比发现,这类接口不支持的个数还是比较多的。特别是 Android 平台版本众多,兼容性问题就更严重,可能一不小小心就掉到坑里。
解决方法
微信本身 Bug 只能绕过去,但对 JavaScript 引擎的兼容性,可以有更优雅的解决方法。比如,我们可以打补丁,使用 polyfill 来实现这些不支持的标准库方法。比如,修复 Android 6.0.1 平台不支持 String.startsWith() 的问题,可以使用下面的 polyfill 代码:
if (!String.prototype.startsWith) { console.warn('define polyfill for Array.prototype.startsWith'); String.prototype.startsWith = function (searchString, position) { position = position || 0; return this.substr(position, searchString.length) === searchString; }; }
推而广之,我们可以把平台不支持的标准库方法,使用 polyfill 实现。这就是 minapp-polyfill 这个项目的目的。
使用方法很简单,把 minapp-polyfill 项目里的 polyfill.js 拷贝到小程序源码目录下,在需要打补丁的 JavaScript 源文件头部引入如下代码即可:
import 'path/to/polyfill.js'
目前这个项目只是搭了个骨架,还有很多方法需要实现。PRs is welcome。
各个平台对 JavaScript 标准库支持情况
条件限制,这里统计了四个平台对 JavaScript 标准库的支持情况,分别是 iOS 10.2, Android 6.0.1, Android 7.0, 微信开发者工具,具体数据如下:
Component.apiName | iOS 10.2 | Android 6.0.1 | Android 7.0 | devtool |
---|---|---|---|---|
Array.toString | YES | YES | YES | YES |
Array.values | YES | N/A | YES | N/A |
Array.toLocaleString | YES | YES | YES | YES |
Array.concat | YES | YES | YES | YES |
Array.fill | YES | N/A | YES | YES |
Array.join | YES | YES | YES | YES |
Array.pop | YES | YES | YES | YES |
Array.push | YES | YES | YES | YES |
Array.reverse | YES | YES | YES | Y |