本篇文章来源于腾讯在线教育技术 ,作者 josephpan。
本文从 Cocos Creator 开发的角度出发,仔细探讨了关注 JavaScript API 兼容性的必要性,以及如何借助工具和 Polyfill 来规避 Cocos Creator 项目的兼容性问题。
一、引言:JavaScript 虚拟机的差异性
不同的浏览器和移动设备所使用的 JavaScript 虚拟机(VM)千差万别,所支持的 API 也大相径庭。我们来了解一下 Cocos Creator 在各个端所使用的 JavaScript VM :
对于 iOS 客户端和 Mac 客户端:在 Cocos Creator 1.6 及以前,Cocos Creator 一直是使用非系统原生的 SpiderMonkey 作为 JS VM ;从 1.7 开始,Cocos Creator 引入了 JSB 2.0 ,支持了 V8、JavaScriptCore 等多种 JS VM 。于是 Cocos Creator 便将 iOS 端和 Mac 端的 JS VM 都改为了系统自带的 JavaScriptCore ,以达到节省包体的目的;到了 2.1.3 ,Cocos Creator 又将 Mac 端的 JS VM 切换到了 V8,以提升应用性能。
对于 Android 客户端和 Windows 客户端:在 Cocos Creator 1.6 及以前,Cocos Creator 同样是使用 SpiderMonkey 作为 JS VM ;从 1.7 开始,得益于 JSB 2.0 ,V8 成了 Android 和 Windows 客户端的 JS VM 。
对于 Web 端:使用浏览器本身的 JavaScript VM 来解析 JavaScript 代码。
从上可见,由于 JS VM 不同,同一份代码在不同的平台上运行可能会有很大差异。为了让我们的产品能够给尽可能多的用户使用,我们在开发阶段就需要时刻注意 JavaScript 的 API 兼容性。
举个例子:fetch()
方法是一个用来取代 XMLHTTPRequest
的 API。相比后者,它的优点在于可读性更高,且可以很方便地使用 Promise 写出更优雅的代码。
fetch(
'http://domain/service',
{ method: 'GET' }
)
.then( response => response.json() )
.then( json => console.log(json) )
.catch( error => console.error('error:', error) );
然而, fetch()
方法不支持所有的 IE 浏览器,也无法在 2017 年以前的 Chrome、Firefox 和 Safari 版本上运行。当你的用户有很大一部分是上述的用户时,你就需要考虑禁止使用 fetch()
API ,而重新回到 XMLHTTPRequest
的怀抱。
在开发阶段,人工保证 API 的兼容性是不可靠的。更可靠的方式是借助工具来自动化扫描。例如下面要介绍的 eslint-plugin-compat 。
二、使用 eslint-plugin-compat
eslint-plugin-compat 是 ESLint 的一个插件,由前 uber 工程师 Amila Welihinda 开发。它可以帮助发现代码中的不兼容 API 。
下面介绍如何在工程中接入 eslint-plugin-compat 。
2.1 安装 eslint-plugin-compat
安装 eslint-plugin-compat 和安装其他 ESLint 插件类似:
$ npm install eslint-plugin-compat --save-dev
还可以顺便把依赖的 browserslist 和 caniuse-lite 一起安装了:
$ npm install browserslist caniuse-lite --save-dev
2.2 修改 ESLint 配置
之后,我们需要修改 ESLint 的配置,加上该插件的使用:
// .eslintrc.json
{
"extends": "eslint:recommended",
"plugins": [
"compat"
],
"rules": {
//...
"compat/compat": 2
},
"env": {
"browser": true
// ...
},
// ...
}
2.3 配置目标运行环境
通过在 package.json 中增加 browserslist
字段来配置目标运行环境。示例:
{
// ...
"browserslist": ["chrome 70", "last 1 versions", "not ie <= 8"]
}
上面的值表示 Chrome 版本 70 以上,或每种浏览器的最近一个版本,或者非 ie 8 及以下。这里的填写格式是遵循 browserslist (https://github.com/browserslist/browserslist )所定义的一套描述规范。browserslist 是一套描述产品目标运行环境的工具,它被广泛用在各种涉及浏览器/移动端的兼容性支持工具中,例如 eslint-plugin-compat 、babel、Autoprefixer 等。下面我们来详细了解一下 browserslist 的描述规范。
browserslist 支持指定目标浏览器类型,并且能够灵活组合多种指定条件。
2.4 指定目标浏览器类型
browserslist 收录了如下一些浏览器,可以在条件中使用(注意大小写敏感):
Android
:用于 Android WebView。Baidu
:用于百度浏览器。BlackBerry
或bb
:用于黑莓浏览器。Chrome
:用于 Google Chrome。ChromeAndroid
或and_chr
:用于 Android Chrome。Edge
:用于 Microsoft Edge。Electron