中文站

知物由学 | 易盾“验证码”互联互通的背后,小程序SDK的跨平台转换技术

一、多平台背景

小程序是一种无需安装即可使用的应用。从2017开始,小程序增速加快,潜力巨大,因此许多互联网平台都拥有都加快了小程序发展步伐,出现了如微信小程序,支付宝小程序,百度小程序等。

易盾的行为式验证码功能自从推出微信小程序SDK后,受到许多客户的好评,并接到大量其他平台的咨询。从产品和业务的发展角度考虑,支持更多平台的小程序能更好地满足客户的需求,增强自身产品亮点。

二、为什么做转换工具

当SDK需要支持多个平台时,若每个版本都单独维护则会增加大量维护成本,因此我们需要一个方案来解决跨端输出问题。

经过调研,市场上关于多平台的方案主要有两种,一种是使用跨端框架,如Taro等;另一种是使用转换工具转换后再修改,如百度提供的wx2。我们分析了两种方案的优劣势,结果如下:


综上,跨端框架更适用于应用,对SDK来说太重;转换工具更适合SDK,但市场上的转换工具存在平台缺失等限制。为了解决这一问题,易盾通过自研转换工具,实现一份源码一键输出多端小程序的SDK。

三、功能及实现

经过各家小程序的文档对比,多家小程序的语法、接口等与微信小程序相似,主要差异在于一些功能支持度、模板属性的命名规则等细节。

为了实现多平台转换,转换工具基于微信小程序的源码,包括以下支持功能:

• 转换文件目标类型

各平台相似功能的文件后缀并不相同,需要将相似功能的文件转成目标平台的后缀。

• JS/模板 API替换

各平台相似的功能API可能命名不同,需要替换成对应的API

• JS API polyfill

各平台相似功能的API可能存在使用或功能细节上的区别,可以利用polyfill抹平差异

• 环境变量

类似process.env,可以区分平台。针对某平台实现时可使用环境变量

• 语法兼容检测

检测是否存在其他平台不支持的特性


整体流程

四、模板/样式/JSON转换

由于模板语法差异较小,对于文件内容可直接用替换的方式实现模板转换,例如wx:if替换成s-if,模板数据格式转换,实现微信转成百度小程序。

需要注意的是,支付宝组件没有做样式命名隔离,为了防止命名冲突,对组件的样式加前缀处理实现隔离。

JSON文件组件命名规则需要转换,使用内容替的方式处理。例如对于微信转百度小程序进行如下图所示的处理:


值得注意的是,不同平台间的小程序模板标签、属性支持程度不一,对于平台无法支持的TAG、属性尽量不使用。在转换前,先使用语法兼容检测功能检测下是否存在目标平台不支持的属性。同样的方式可以使用于样式文件的处理。

除了内容需要处理,模板文件及样式文件后缀都需修改成对应平台的文件后缀。

五、JS转换

转换工具对于js的处理主要是基于babel的语法抽象能力,主要经过如下步骤,最终处理成目标平台的js文件:

1. 抽象生成语法树

2. 遍历并处理节点

3. 将语法树转换成文本


babel三部曲

处理js的第二步是js转换的关键,利用babel的插件机制,对不同的节点进行处理。js的处理有统一的处理流程,如环境变量的处理,API的替换等。此外,各平台独立也可以根据自己需求对节点进行处理。

如下图所示,所有平台都会对属性节点执行全局变量替换,并支持各平台做额外的处理。


值得注意的是,SDK类产品存在一个雷区,即修改全局性的属性容易对客户的应用产生影响。为了防止该情况的发生,转换工具对各平台差异的API使用runtime transform的方式进行polyfill,不更改全局上、变量上的任何方法。

因此,转换工具除了转换部分的功能,还包含一个polyfill库,这个库支持客户自定义,如项目中已存在的polyfill。

六、落地遇到的坑

转换工具第一个落地项目是验证码小程序SDK,落地后流程如下:


在落地过程中,开发者不可避免地陷入一些“坑”中。一是,由于转换工具的polyfill不完整,影响部分API的转换。二是,原来的代码存在不可转换的兼容性问题。三是,小程序转换工具不能完全抹平平台之间的差异。

其中,最大的问题就是prop的差异。如果子孙组件共享一个对象,原先在微信上的方案无法在其他平台实现,索性可以通过环境变量区分平台,以支持另一种方案。

当然,先用工具提供语法兼容检测功能,并检测可能存在的不兼容API,也是一种方式。但这仅作为一个参考,毕竟官方的API处在不断补全的过程中。

七、成果

在改造验证码小程序SDK原项目后,我们实现了一份原始代码,支持一键输出微信、百度、字节跳动、头条小程序版本,实现验证码支持更多平台,且一定程度上降低维护成本。