
原文地址: https://zhuanlan.zhihu.com/p/31445074?group_id=918537992134893568
支付宝小程序为了兼容微信小程序,在很多的接口定义和设计上都是一样的,方便程序的移植性,虽然初衷是好的,但是在最后的落地过程中,变化还是非常大的。
常规思路
对于大家能够很快想到的解决办法就是正则,通过强大的正则表达式来替换需要被替换的接口名和参数,这也是目前已经有的解决方案。这种方案有 3 个现象级问题,第一是开发者需要有强大的正则功底,第二是即使正则掌握度很好,对于特定的 case,正则也是不能解决的(写过复杂正则的同学应该了解),最后一点就是很难有精确的转换日志文件,帮助用户查看进行了哪些修改。
落地方案
只有通过预编译和分析得出来的结果才是真正我们需要的,所以我们必须得从 AST 来解决问题,分析相应的接口和参数,最终得到我们需要的结果。
转换流程图:

解决步骤
1. 设置对象匹配,用于 mapping 阶段
a. 对于 api,我们需要类型下面这样的一份转换对象。
/**
* 1.如果值为 null,表示不存在该接口
* 2.如果有值,
* a. 其中有 tips,表示给予的建议
* b. 有 mapping,需要转换相应的接口名
* c. 如果有 params,则需要转换相应的参数
*
*/
wx: {
request: {
mapping: 'httpRequest',
params: {
header: 'headers'
}
},
uploadFile: {
params: {
name: 'fileName'
}
}
}
说明:wx表示微信小程序的对象,request表示 wx 发送请求的接口名,而在支付小程序中,发请求的接口名叫httpRequest,在参数对象中,微信使用header来存放 http 头,而支付宝则变为headers。
b. 对于 view 模块,需要类似的 mapping
view: {
attrs: {
'hover-stop-propagation': null
}
}
说明:在微信小程序中,view组件的属性hover-stop-propagation在支付宝小程序的view组件中是没有的。
通过设置 mapping 对象,可以在转换过程中的 mapping 阶段进行转换。
2. 产生 AST
对于不同的文件类型,采取不同的工具进行分析,先通过 glob 工具进行选择,刷选后再进行处理。
a. 对于 js 部分
对于 js 文件,我们通过 babylon 来解析,再通过 babel-traverse 来遍历 js 文件,对于指定的表达式进行遍历,再通过第一步设置的 mapping 值来替换成目标接口及参数,遍历完成之后,最后通过 babel-generator 来生成想要的文件。
b. 对于 view 文件
对于 view 文件,我写了一个库html-tool,用于遍历 view 文件的,通过第一步设置的 mapping 值进行替换,最后生成想要的文件。
分析工具
分析工具目前已经集成在了vide编辑器的插件上。

说明:
项目路径:填写相应的小程序路径。
转换日志:转换过程中的日志,可以清晰看到哪些变化,哪些提示等。
转换前后文件比较
微信小程序下的一个 js 文件

转化后的支付宝小程序

注意点
对于转换后的代码,并不能一定能运行,还需要根据转换日志进行修改,因为程序不能很深入了解具体业务,只能尽可能帮助开发者进行快速修改和运行。
参考
- html-tool: 用来分析 view 文件
- transform-miniprogram: 用来转换小程序的接口,包括如何转换 js 文件和 view 文件,其引用了 html-tool 和 babel 工具
- vide / vide-plugin-toolbar-miniprogram: 安装 vide 编辑器后,选择安装 vide-plugin-toolbar-miniprogram 插件就可以运行