在web应用中,canIUse很少见,每次更新都会基础库,通用组件/插件都给更新出去,接口的更新跟得上业务的更新。
小程序或者Hybrid开发中,canIUse就显得很重要,宿主应用的更新和web的更新不同步,需要不同的版本进行降级。
以前最常见的判断方式是通过 xx.newApi
来新的接口存不存在,这种方式只能简单判断有没有新接口,而不能对接口中的参数返回值等进行判断,显然满足不了日益壮大的需求。
那该怎么实现呢?
我去网上找了下,通过把接口转为AST就能拆分出接口名,参数等信息。本文也是这个思路,但是通过解析器生成AST的方式有诸多难点(比如object.success回参,只针对一些接口等),我们手动维护一个简易的抽象树,如:
const map = {
showToast: {
object: {
title: true,
icon: {
none: true,
success: true,
loading: true
},
image: true,
duration: true,
mask: true
}
},
getStorageInfoSync: {
return: {
keys: true,
currentSize: true,
limitSize: true
}
},
getStorageInfo: {
success: {
keys: true,
currentSize: true,
limitSize: true
}
}
...
}
每当有新接口或者改变,都需要同步更新下抽象树。
接着封装下统一的调用方式就完成了:
function _canIUse(schema, parent) {
let arr = schema.split('.')
const key = arr.shift()
if (parent[key]) {
if (arr[0]) {
if (isObject(parent[key])) {
return _canIUse(arr.join('.'), parent[key])
}
return false
}
return true
}
return false
}
/**
* 判断接口可用度
* @param {String} schema 使用 ${API}.${method}.${param}.${option}
* ${API} 代表 API 名字
* ${method} 代表调用方式,有效值为return, success, object, callback
* ${param} 代表参数或者返回值
* ${option} 代表参数的可选值或者返回值的属性
*/
export function canIUse(schema) {
return _canIUse(schema, map)
}
有更好的方法,欢迎讨论。