native-adapter
是一套开箱即用,易于拓展,无需引入多余代码的多环境适配框架。使用它可以通过一个api适配不同平台,目前涵盖转转 app、找靓机 app、微信浏览器、微信小程序、快手小程序、头条小程序等多种环境。
旧方案主要是以适配器模式的设计架构,前期平台较少的情况下,扩展和兼容比较灵活。随着适配平台的增多,不断地增加平台代码,没办法按需引入,最后导致包体积会越来越大。
native-adapter
作为团队基础库中最重要的一个,在近几次的基建问题收集时,反馈 native-adapter
问题的不在少数。经过业务反馈和调研,主要问题如下:
针对以上问题,经过梳理和评估,确立以下目标:
对社区一些开源包的调研,发现针对包体积大,无法按需引用 这个痛点,基本上采用的是插件化架构。在此借鉴了一下 BetterScroll 插件体系以支持按需引用。
├── src
│ ├── all.ts // 全量包入口
│ ├── core // 核心
│ │ ├── conf.ts // 暴露的api方法
│ │ ├── index.ts
│ │ ├── native.ts // 核心插件化实现
│ │ └── utils // 工具方法
│ │ ├── ajax.ts
│ │ ├── compareVersion.ts
│ │ ├── cookies.ts
│ │ ├── events.ts
│ │ ├── index.ts
│ │ ├── urls.ts
│ │ ├── util.ts
│ │ ├── waitJsLoaded.ts // 进行异步加载初始化sdk和调用队列
│ │ └── wxAuth.ts
│ ├── index.ts // 核心包, 包括m站,转转app、找靓机app、微信浏览器、微信小程序、qq等
│ └── plugins
│ ├── base // 基础adapter
│ │ ├── BaseAdapter.ts
│ │ └── LoginAdapter.ts
│ ├── buildIn // 内置核心adapter
│ │ ├── QQAdapter.ts
│ │ ├── WechatAdapter.ts
│ │ ├── WechatMPAdapter.ts
│ │ ├── ZLJAdapter.ts
│ │ └── ZZAdapter.ts
│ ├── external // 扩展adapter
│ │ ├── BaiduMPAdapter.ts
│ │ ├── GAdapter.ts
│ │ ├── KrakenAdapter.ts
│ │ ├── KuaishouAdapter.ts
│ │ ├── QQMPAdapter.ts
│ │ ├── ToutiaoAdapter.ts
│ │ ├── WubaAdapter.ts
│ │ ├── ZZHunterAdapter.ts
│ │ ├── ZZSELLERAdapter.ts
│ │ └── ZZYigeAdapter.ts
│ └── index.ts
// ZZAdapter platform
static platform = [
{ rule: /58ZhuanZhuan/g, name: 'zz', scheme: 'zhuanzhuan://' },
{
// 找靓机新webview
rule: () =>
/zhaoliangji-v2/g.test(navigator.userAgent) &&
(getUrlParams().needNewWebview == '1' ||
getUrlParams().needNewWebView == '1' ||
compareVersion(getCookie('v'), '9.1.10') >= 0),
name: 'zlj',
isNewWebview: true,
},
// 转转门店
{
rule: /zzstore|offlinestorecomplex/g,
name: 'zzstore',
},
// 上门超人
{
rule: /zzupdoor/g,
name: 'zzupdoor',
},
]
static use(ctor: PluginCtor) {
const name = ctor.pluginName
const installed = NativeConstructor.plugins.some((plugin) => ctor === plugin.ctor)
if (installed) return NativeConstructor
if (isUndef(name)) {
console.warn(`插件必须有一个静态pluginName字段`)
return NativeConstructor
}
NativeConstructor.plugins.push({
name,
ctor,
})
return NativeConstructor
}
NativeConstructor.plugins.forEach(
(item: PluginItem) => (this.pluginsMap[item.name] = item.ctor)
)
Object.keys(this.pluginsMap).forEach((key) => {
const Ctor: PluginCtor = this.pluginsMap[key]
let currentPlatform = this.getCurrentPlatform(Ctor.platform)
if (currentPlatform) {
// 实例化plugin时会注入当前this,即native实例
this.plugin = new Ctor(this as unknown as Native)
this.currentPlatform = currentPlatform
}
})
// plugins没有匹配到平台、默认匹配baseAdapter
if (!this.plugin) {
let currentPlatform = this.getCurrentPlatform(MAdapter.platform)
if (currentPlatform) {
this.currentPlatform = currentPlatform
}
this.plugin = new MAdapter(this)
}
// 核心包:包括m站,转转app、找靓机app、微信浏览器、微信小程序、qq
import native from '@zz-common/native-adapter'
// 全量包:包含插件中所有平台
import native from '@zz-common/native-adapter/es/all'
// 按需加载, 已经默认包含核心包,可以扩展qq小程序、百度小程序、快手小程序、头条小程序、采货侠app、Kraken等
import { Native } from '@zz-common/native-adapter'
import QQAdapter from '@zz-common/native-adapter/plugins/external/QQAdapter'
Native.use(QQAdapter)
let native = new Native(options)
本次代码升级和优化一方面使得代码维护更加简单清晰,趋于稳定。另一方面对代码进行的瘦身和优化使得核心包代码体积减少了 40%左右。同时文档和 demo 对使用人员来说,更加方便快捷,提高了集团内开发人员的效率。