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

2017-11-27 21:53:35 +08:00
 softwang

原文地址: 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 文件

转化后的支付宝小程序

注意点

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

参考

1445 次点击
所在节点    前端开发
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/410038

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX