基于AST来转换微信和支付宝小程序

15 天前

支付宝小程序为了兼容微信小程序,在很多的接口定义和设计上都是一样的,方便程序的移植性,虽然初衷是好的,但是在最后的落地过程中,变化还是非常大的。

常规思路

对于大家能够很快想到的解决办法就是正则,通过强大的正则表达式来替换需要被替换的接口名和参数,这也是目前已经有的解决方案。这种方案有3个现象级问题,第一是开发者需要有强大的正则功底,第二是即使正则掌握度很好,对于特定的case,正则也是不能解决的(写过复杂正则的同学应该了解),最后一点就是很难有精确的转换日志文件,帮助用户查看进行了哪些修改。

落地方案

只有通过预编译和分析得出来的结果才是真正我们需要的,所以我们必须得从AST来解决问题,分析相应的接口和参数,最终得到我们需要的结果。

转换流程图:

miniprogram.d05e89b9fd60.png

解决步骤

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编辑器的插件上。

Jietu20171121-145803.767dbacb0aa4.jpg

说明:
项目路径:填写相应的小程序路径。
转换日志:转换过程中的日志,可以清晰看到哪些变化,哪些提示等。

转换前后文件比较

微信小程序下的一个js文件

wx.45db176af466.jpg

转化后的支付宝小程序

ali.58de506f7c30.jpg

注意点

对于转换后的代码,并不能一定能运行,还需要根据转换日志进行修改,因为程序不能很深入了解具体业务,只能尽可能帮助开发者进行快速修改和运行。

参考

2
推荐阅读