京东技术:跨端移动应用开发解决方案 | ARES小程序转换工具1.0 正式发布

35岁的程序员 2018-12-25 13:15:23 ⋅ 1159 阅读

来这里找志同道合的小伙伴!

 导 语 

ARES是商城技术与数据中台推出的跨端移动应用开发解决方案,包括五大产品板块:ARES Engines、ARES Websits、ARES Studio、ARES Store、ARES Console。经过不断的技术完善,目前已经在手机京东客户端累计接入150+业务,稳定支撑千万级DAU,并对外支持20+个独立APP,拥有完善的API和功能强大的开发IDE工具。

ARES小程序转换工具用来打通ARESEngines和微信小程序生态,它包含两个部分,一部分是我们之前已经发布的小程序转JDReact工具,另一部分就是本次隆重推出的JDReact转微信小程序工具,通过这两部分我们就可以完全实现ARES引擎和微信小程序的互通。



样例展示


1、APIDemoes



2、实际业务


下面是前端组件部的通用交易组件项目,包含个人中心、订单、商详、购物车、结算,可快速组合接入不同的APP,项目同时具有原生、RN端、h5、小程序端,详情请查看链接(http://docs.api.jd.com/),其中小程序端就是由本引擎转化而来。


我的京东


订单业务

使用方式


1、命令行


可以通过安装@jdreact/to-mp-engine直接使用

npm install-g@jdreact/to-mp-engine

JDReactAPIDemos为例:

jdreact-rntomp -i jdreact-jsbundle-JDReactAPIDemos/jsbundles/JDReactAPIDemos -JDReactAPIDemosWP

这样就会在当前目录生成一个JDReactAPIDemosWP目录,也就是小程序的源码目录。


jdreact-rntomp命令有三个参数:

  • -v 打印jdreact-rntomp 版本

  • -i React Native 源代码目录

  • -o 转化生成的小程序源代码目录

2、ARES IDE


ARES小程序转换工具将会集成在最新的ARES IDE中,大家就可以不用命令行, 而是以可视化的方式方便的使用转化引擎了。


原理简介


首先:微信小程序是什么?


关于这个问题,大家可以直接查看微信小程序官方文档:

https://developers.weixin.qq.com/miniprogram/dev/


这里简单总结一下:

  • 数据驱动UI = f(data)

  • 无法直接操作节点,模版结构必须预先在wxml文件定义好

  • 变量绑定不能是函数调用


小程序实现了一套框架,并给出了很多规则,限制开发者必须以一种“静态”的方式组织代码。


那么,React Native是怎样的呢?React Native使用的是JSX来组织UI,由于JSX本质上是JS,所以React很自由动态,它就是代码,最终运行时会给你结果。


从“静态”到“动态”相对简单,之前我们发布过一个工具:

http://npm.m.jd.com/package/@jdreact/to-jdreact-engine,就是把小程序的代码转化为React Native。


那么如何把“动态”的React Native代码转化为“静态”的小程序代码呢?


AST操纵代码


先解决一个前置问题:我们必须能够理解代码语义进而能够“操纵代码”。想想看,由于变量绑定方式的不同,至少我们需要把 React Native的 <Text>{txt}</Text>转化为小程序的<text>{{txt}}</text>。,因为小程序的变量绑定形式是双大括号。


AST(抽象语法树)是源代码的抽象语法结构的树状表现形式,我们通过修改AST结构使之符合我们预期,然后根据修改之后的AST结构重新生成代码。比如,我们需要把var a=1,这句代码修改为const x='你好'。首先我们先看下这句代码的AST结构:


修改这个AST结构,比如把上面的结构改为:


重新生成代码就变成了const x='你好'


总的来说,通过AST这个工具,我们可以理解源代码语义,并且具有了修改源代码生产新代码的能力。


那么当我们遇到这样的React Native代码时


可以通过AST修改代码,变成index.wxml


React运行时


回到我们一开始提出的“动态”与“静态”的问题。


比如这样的React Native代码:


这里的xthis.f()这个函数的返回值。但是这个函数具体返回什么呢?这个需要在运行时才能够确定下来。可能是JSX结构<Text>1</Text>也可能就是null。显然这里对这个x到底怎么处理,AST是没有办法的。AST本质也是“静态”分析代码,不是它不够强大,而是有些信息只有在代码运行时才能获取到。那么如何转化这种情况,让其在小程序上同样正常呢,也就是之前的问题:如何把相对“动态”的React Native代码转化为小程序代码呢?


只有一种方式就是让React代码跑在小程序环境,这样所有的运行时信息也就能够处理呢。而我们之前也提到了JSX本质上就是JS,而小程序就是运行在浏览器的, 需要再这个小程序环境上让React跑起来。所以,我们在小程序上实现了一套React 运行时,它是一个mini-react,总的思想设计思想基于React,又适配了小程序。


首先,我们知道JSX语法本身是不被浏览器识别的,直接在小程序里面写JSX语法那肯定就是语法错误了。所以第一步需要把所有的JSX会被转化JS(基于babel现有插件)。


然后就像React一样,这里有一个Render入口函数,负责去构造整个React环境, 包括实例对象,context,ref等等,还记得之前说“小程序的组件属性不能是方法”这个限制了吗?这里也是不存在的,因为所有的属性传递都在React这一层进行。同时需要在调用setState的时候,重新构建这样的环境,这里面会涉及到 state 合并,组件声明周期,实例复用,context计算等等。与React是一样的,通过这样的一个过程把小程序渲染需要的数据都准备好。


最后一步:把运行时结果更新到页面上,刚才我们说了React执行环境会准备好所有小程序渲染需要的数据。这些数据最终会交个对应的小程序组件实例,然后小程序调用自己的setData方法,把数据更新到页面上。


大家可以简单的理解为:React Native在小程序上运行,一切以React的方式进行,只是最后实际更新UI的时候,是交个了小程序实例来更新。


这里有一个Instance manager模块,这个模块是小程序实例和React实例交互的关键。小程序环境和React环境在构建的过程中都会和这个模块交互,每当有新的实例生成时,都会向这个模块注册。同时实例销毁的时候,也会通知这个模块移除这个实例。它打通了React环境和小程序环境,使之可以双向交互。


组件/API对齐


接着上面的过程,假设是这样的一个页面:


当我们React Native‘运行’结束,把数据交给小程序更新UI的时候,小程序这里也必须存在一个‘FlatList’实例去接受这份数据。所以在小程序上我们需要预先把FlatList,ScrollView等这些组件实现一下,实际上由于差异的存在,即使时View, Text,Button这些基本组件,在小程序上也有对应的组件存在。


另外,正如之前APIDemos演示的一样,常用的JDReact的组件也是有对应的小程序版本的。


最后,如果你有自己的组件库,我们会提供很方便的扩展机制,那么就不仅仅是JDReact应用可以转化为小程序了,你自己的React Native应用也是可以无损转化了。


第三方库集成


对于第三方库这里以redux和react-redux这两个库来说明。这两个库分别代表了两个类型的库,redux与React毫无关系,就是一个数据管理库。而react-redux其实是通过高阶组件的方式对React组件进行扩展,是和React紧密相关的。


对于redux这种于React运行无关的库,直接就可以集成到小程序。


对于react-redux我们需要解决的是怎么在我们的mini-react上创建高阶组件。前文已经说明在React运行时和小程序运行时之间有个 InstanceManager 管理实例之间的关系,高阶组件本身也会生成一个React实例,需要把高阶组件的这个实例通过InstanceManager管理起来,我们提供了一个很方便的HocComponent方便大家创建高阶组件。react-redux就是基于这个组件实现的。


经典的TodoList:


美好的世界,总有遗憾


话说回来,由于小程序和React Native两个平台还是有很多差异无法抹平,有些使用上的限制必须提前说明。


对于这些差异,你可以使用平台判断的方式针对不同平台做不同处理,
Platform.OS === 'wx'时表明是小程序平台,某些情况可以通过这个平台判断做相关处理。


1、路由


第一个差异点是路由系统。小程序的路由是内置的,而对React Native来说路由本身也就是一个组件,没有什么特殊的,而且Facebook官方也没有提供一个靠谱的实现。这里我们提供了一个路由组件@areslabs/wx-navigator来抹平差异。

在React Native端它基于社区的react-navigation,转化为小程序之后则直接使用小程序的内置路由。


这个路由组件简单易用,具备了大部分你需要的功能。

2、动画


第二个差异点时动画,相比与React Native来说,小程序的动画能力相对较弱,完全把RN的动画转化为小程序的是不可能的,这是平台限制。但是动画能力是一个app必不可少的能力,所以我们提供了一套RN的动画API@areslabs/wx-animated


这套API基本参考了小程序的动画API,可以直接查看小程序的动画文档:

https://developers.weixin.qq.com/miniprogram/dev/api/ui/animation/wx.createAnimation.html


3、转化其他限制


  • 转化之后的代码最终是跑在小程序引擎上,必须符合小程序的规范,比如最终压缩的代码小于2m,路由深度不大于5层等

  • 只支持ES6模块文件系统,也就是只支持import/export,不支持require。不过,require图片是可以的。

  • 一个文件最多只能有一个组件,不管是class组件还是函数式组件。原因是这样的:在小程序端一个组件对应4个文件,如果在React Native的一个文件中写了多个组件(n),那么小程序端将会出现4n个文件,对于这些文件如何命名才能让开发者方便的二次修改呢?而且函数式组件的识别就是一个问题。这里为了避免混乱,这里要求一个文件最多只能有一个组件,而且我们认为这是一个好习惯

  • 基本组件的属性展开不支持,比如<View {...x}/>这样是不支持的。但是自定义组件是OK的,比如A是一个自定义组件,那么可以<A {...x}/>

  • ref必须是方法,不支持字符串

  • 不支持onLayout方法,在浏览器环境好像没有支持的途径

  • 自定义组件属性类型是React Element或者方法返回React Element,属性名必须是 xxComponet。类似 FlatList 的ListHeaderComponent,ListFooterComponent等

  • 在React Native里面,使用map方法返回组件数组是很常见的操作,比如

    在React Native中,如果Text没有指定key,将会报警告。但是转化引擎要求这里的key是必须传递的。

    同样 FlatList,SectionList的key/keyExtractor 也是必须指定的,如果不指定,我们不会好心的用index代替,而是直接报错。

  • 怎么判断一个函数是不是组件声明呢?我们对定义方式有要求:函数式组件必须在定义的时候导出,例如:

  • 不支持外部JSX方法,可以用函数式组件,具体是指:

    需要改写为:


最后


希望给大家提供一个方便好用的工具,也希望大家可以积极给我们反馈,工具的完善离不开大家的反馈。感谢前期试用的同学,给我们提了很多建议和BUG。


商务合作:liujiaxu@jd.com

---------------END----------------

后续的内容同样精彩

长按关注“IT实战联盟”哦




全部评论: 0

    我有话说:

    开源资讯】Electron 10.1.4 发布平台桌面应用开发工具

    简介 Electron 是 GitHub 发布平台桌面应用开发工具,支持 Web 技术开发桌面应用,其本身是基于 C++ 开发的,GUI 核心来自于 Chrome,而

    微信程序页面通信解决思路

    为大家列举三种比较常用的方案~

    京东到家订单中心系统mysql到es的转化之路

    原文:https://www.toutiao.com/i6796507988602389006 京东到家订单中心系统业务中,无论是外部商家的订单生产,或是内部上下游系统的依赖,订单查询的调用量都非常

    A3Mall v1.5.2 发布,免费开源的 PHP 程序商城系统

    项目介绍 A3Mall商城系统是基于ThinkPhp6.0+Vue开发的一套移动电商系统, 支持微信公众号商城、H5商城、程序商城,支持多种营销活动,优惠劵、订单活动、团购、秒杀、会员特价、积分

    京东技术京东风格的移动Vue组件库NutUI2.0来啦

    移动 Vue 组件库 NutUI 自发布以来受到了广泛的关注。据不完全统计,目前至少有30多个京东的 web 项目正在使用 NutUI 。

    京东技术:使用JDReact程序双向转换

    JDReact是京东商城前台产品研发部推出的多融合开发框架。

    开源资讯」Atom 1.52.01.53.0-beta0发布平台文本编辑器

    Atom 同时发布1.52.01.53.0-beta0 版本。Atom 是 GitHub 专门为程序员推出的一个平台文本编辑器。具有简洁和直观的图形用户界面,并有很多有趣的特点:支持

    Taro 3.0.17 发布,BAT 程序、H5 与 RN 统一框架

    Taro 3.0.17 发布了。Taro 是一套遵循 React 语法规范的多统一开发框架,支持用 React 的方式编写一次代码,生成能运行在微信程序/百度智能程序/支付宝程序、H5 与

    Taro 3.0.22 发布,BAT 程序、H5 与 RN 统一框架

    Taro 3.0.22 发布了。Taro 是一套遵循 React 语法规范的多统一开发框架,支持用 React 的方式编写一次代码,生成能运行在微信程序/百度智能程序/支付宝程序、H5 与

    微信程序电商实战-入门篇

    程序开发工具有新版本更新啦!开发体验更好了,接下来一起为电商程序做一下准备前期准备工作~~

    开源资讯」BookChat v2.4 发布,通用书籍阅读微信程序

    BookChat - 面向程序员开源书籍和文档阅读学习程序

    WebMIS 1.0.0 beta.3 发布,全栈开发基础框架

    ,为企业提供一套完整的技术解决方案,满足快速开发...

    Dapr 1.0 发布,分布式应用运行时

    Dapr 1.0 正式发布。 Dapr 是一个开源、可移植的、事件驱动的运行时,可以帮助开发人员构建在云和边缘上运行的弹性的、微服务的、无状态和有状态应用程序,并且关注于业务逻辑而不用考虑分布式相关

    微信程序实战篇:如何解决https域名问题 ?

    开发自己的微信程序绕不开https问题,为了能在程序中调用我们自己的API服务请打开看一看吧!!!

    精品推荐:JDFlutter | 京东技术中台新一代平台开发框架

    DFlutter 是商城共享技术部-多融合技术部推出的新一代平台开发框架,可快速集成至现有 Android/iOS 工程开发者可借助 JDFlutter 平台快速完成 Flutter 业务开发

    微信程序实战篇:基于wxcharts.js绘制移动报表

    微信程序图表插件(wx-charts)是基于canvas绘制,体积巧,支持图表类型饼图、线图、柱状图 ......

    SpringBoot2.0填坑(一):使用CROS解决域并解决swagger 访问不了问题

    公司后台是采用SpringBoot2.0 搭建的微服务架构,前端框架用的是vue 使用前后分离的开发方式,在开发联调的时候需要进行域访问,那么使用CROS解决域问题,但是swagger 却用

    Taro 1.2.9 发布,BAT 程序、H5 与 RN 统一框架

    一套 React 语法规范的多开发解决方案 Taro