一、多平台背景
小程序是一种无需安装即可使用的应用。从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原项目后,我们实现了一份原始代码,支持一键输出微信、百度、字节跳动、头条小程序版本,实现验证码支持更多平台,且一定程度上降低维护成本。