# Antmove 是如何实现小程序跨平台开发的

蚂蚁搬家工具(Antmove)是一个小程序开发辅助工具,致力于解决小程序跨平台开发的难题,借助于 Antmove,你只需要编写一套微信小程序代码(或是支付宝小程序代码)就可以达到运行于多平台的目的,无需关心如何适配多平台的难题。

# who?

Antmove 起源于高德小程序团队的一个内部项目,在高德小程序平台建立之初,有许多的企业合作商希望将他们的小程序应用上线到高德小程序平台(支付宝小程序平台),但他们已经有了自己的微信小程序应用,再开发一套高德的(或是支付宝的)对企业来说是一种资源的负担。基于这个需求,内部实现了一个微信小程序到高德小程序的转换工具,通过这个工具帮助这些企业用户快速的将他们的应用上线到高德上。

基于初始的微信小程序到高德小程序转换的需求,我们发现虽然解决了用户的第一步需求,但还没有完全解决他们的痛点,去真正的实现小程序的跨平台开发,提供小程序跨平台能力解决方案,这也是蚂蚁搬家的目标,要去解决的问题。

# what?

蚂蚁搬家工具,提供一种小程序跨平台开发统一解决方案

Antmove 的目标是提供一套成熟稳定的小程序跨平台开发解决方案,那么它到底是什么样的一个工具,适合什么样的场景?

  • 如果你没有小程序跨平台的需求,那么你是不需要用到 Antmove 的

    Antmove 做的是将小程序应用编译为其它平台的小程序应用,它不是一个小程序框架,不定义新的小程序语法,我们认为目前的小程序框架发展的已经很成熟,功能完备。基于原生的小程序就已经足够开发者去开发小程序应用,引入第三方的库,框架反而会增加技术风险,是应用变得过于复杂。小程序就应该小而美,技术层也应该是这样。

  • 目前支持哪些平台的搬家

    目前 Antmove 对外开放版本释放了微信小程序转支付宝小程序的功能,这也是我们在调研中发现需求最多的。支付宝到微信以及支付宝到百度头条的转换目前正在测试中,很快就会与大家见面。

  • 为什么是支付宝到百度头条?而不是微信到百度头条的直接转换?

如下的转换链路图可以让我们更加清晰直观的了解 Antmove 的跨平台支持情况

antmove

在 Antmove 的转换链路中,我们实现了微信小程序与支付宝小程序的双向转换,从而实现了以微信小程序为核心或者支付宝小程序为核心的跨平台解决方案。

  • 微信小程序与支付宝小程序的作为可选转换链路的设计

    支付宝小程序的推出要落后于微信小程序,所以在整个框架能力支持上,支付宝是向微信小程序对齐的,然后在框架的底层设计上,两者是有差异的。从笔者的了解来看,微信小程序框架原理更接近于 Vue.js,而支付宝小程序更接近于 React.js。基于此,在开发体验上,两个平台也有许多的不同。这也是 Antmove 支持两者作为转换支持核心的原因之一,让用户可以选择自己或是自己团队搭的开发体验。

  • Antmove 能做到百分百的转换支持吗?

    很遗憾的是,经过整个团队的努力,还是有部分差异是工具无法解决或是我们不想解决的,无法解决的部分是不同小程序平台的能力差异化导致的;而工具没有去刻意支持的部分是因为我们不希望过多的去影响编译输出的代码,我们希望编译输出的还是可编程的、人性化的原生的小程序代码,尽量低的性能损耗。 虽然有部分需要开发者自行去处理,不过完全不用担心,工具提供了一套机制,让开发者可用尽量低成本的实现差异化的兼容

# why?

从小程序发展至今,社区也出现了许多的小程序相关的框架、工具等生态工具,比如 mpvue、taro、uni-app等工具。它们也提供了跨平台的解决方案,Antmove 与它们相比有什么异同,有什么优势呢?

# 采用原生小程序的开发方式

wepy、mpvue 小程序框架最初的目的是提升小程序的开发体验,它们是最早的一批框架,因为那时候微信小程序刚推出不久,功能不稳定,API 经常变更,功能也不够完善(不支持组件式开发)。所以那时迫切的需要提升小程序的开发体验,不过到目前为止,小程序框架已经发展的很成熟而且推出了许多小程序场景的功能。

原生小程序的开发体验已经足够好,语法扩展功能就显得有些鸡肋,这也是 Antmove 选择原生小程序开发方式的原因。能够享受小程序框架的完整的功能特性,同时无需额外的学习成本。

# 简化开发流程

从技术工程的角度来看,引入第三方框架是有风险的,如果对框架有了强依赖,比必须保证对框架有足够的了解,否则就会出现框架层引入潜在 bug 的可能。开发流程的增加,开发体验也会下降,开发调试变得困难。这也是 Antmove 与框架类小程序跨平台解决方案相比的优势,无论是转换前还是转换后得到的都是原生的小程序代码,只需要引入部分的 polyfill 代码即可。

# 应用性能

基于 Antmove 的跨平台方案,基本可以达到和原生小程序一样的性能体验。而如果使用了第三方框架的话,无论框架再怎么优化,与不引人相比,性能肯定会有损耗。

# 使用体验

Antmove 基本可以达到一键转换的使用体验,同时还配套了开发模式的编译日志、运行时日志帮助用户完善应用,了解不同平台之间的差一点,得到很适合目标平台的代码。

团队有资源优势,对支付宝小程序框架从外到内有深入的了解,可以做出更多的优化。

# how?

Antmove 工具为了提供更好的跨平台解决方案,主要在编译时、运行时以及编译运行时的结合处理,做了许多的转换处理工作。

如下以微信小程序转支付宝小程序为例,对应 Antmove 的 wx-alipay-plugin

# 编译时处理

Antmove 在编译时会将整个应用的目录结构、文件结构等转换为对应平台的结构,对文件命名规范、样式、模板、逻辑文件、配置文件等按照特定平台输出。

框架相关的特定语法如 wxs 语法、模块依赖系统(路径解析规则差异处理)也会在编译的过程中处理为目标平台语法。

# 编译示例

  • 微信小程序
<!--index.wxml-->
<view class="container">
  <view class="userinfo">
    <button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button>
    <block wx:else>
      <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
      <text class="userinfo-nickname">{{userInfo.nickName}}</text>
    </block>
  </view>
  <view class="usermotto">
    <text class="user-motto">{{motto}}</text>
  </view>
</view>
  • 支付宝小程序
<view class='container'>
  <view class='userinfo'>
    <button a:if='{{!hasUserInfo && canIUse}}' open-type='getUserInfo' onGetuserInfo='getUserInfo'>
      获取头像昵称
    </button>
    <block a:else=" ">
      <image class='userinfo-avatar' src='{{userInfo.avatarUrl}}' mode='cover' onTap='bindViewTap'>
      </image>
      <text class='userinfo-nickname'>
        {{userInfo.nickName}}
      </text>
    </block>
  </view>
  <view class='usermotto'>
    <text class='user-motto'>
      {{motto}}
    </text>
  </view>
</view>

# 运行时处理

运行时处理主要是对 API,开放能力以及 App/Page/Component 构造函数进行差异抹平处理。

# 编译运行时结合处理

有许多功能是编译时和运行时单独无法处理的,以自定义组件事件传递为例,微信是以 triggerEvent 的形式,类似于自定义事件,而支付宝则是类似于 react 的机制,基于 props 的形式来实现组件之间的方法传递,这就需要在编译时将事件转换为支付宝 props 的形式,并需要在运行时对 props 函数更改为 triggerEvent 调用的形式。