专注收集记录技术开发学习笔记、技术难点、解决方案
网站信息搜索 >> 请输入关键词:
您当前的位置: 首页 > 移动平台

基于React Native的腾挪平台研发实践分享

发布时间:2010-05-30 21:20:03 文章来源:www.iduyao.cn 采编人员:星星草
基于React Native的移动平台研发实践分享

转载:http://blog.csdn.net/haozhenming/article/details/72772787

 

本文目录:

 

一、React Native 已经成为了移动前端技术的趋势

二、基于React Native 进行移动平台研发过程中的一些思考

三、基于React Native 进行移动平台研发过程中的一些实践

四、小结

 

 

一、React Native 已经成为了

移动前端技术的趋势

从2014年年底,Facebook计划开源React Native 的时候,我就已经开始关注TA了,关注的主要原因是,我们在2012年的时候,将我们的移动平台前端开发技术确定为“DSL->JavaScript->Native Mobile”这个技术流派。要知道在那个时代,绝大多数的友商要么选择Hybrid,要么选择HTML5作为移动平台的跨平台前端解决方案。

 

然而,这两种方案最终的UI渲染,本质上都需要依赖Webkit,通俗点说就是UI最终是通过浏览器内核渲染。我们当时在技术选型的时候实在无法容忍Webkit在Andriod上的体验,而选择了驱动原生(注:这个名字是我起的,也是为了区别于传统的Hybrid技术)的方式。

 

当时的这个技术抉择,在当时是冒着巨大的风险的,现在看来,我们是非常幸运的。

后来Facebook 推出React Native 后,阿里系也推出了自己的Weex,甚至Gartner针对这类技术在2016年的报告(IT Market Clock for Mobile App Development, 2016 )中首次出现并并为这个技术流派起了一个名字——Javascript Frameworks for Native Mobile。

 

 

Garnter将这个技术流派当如了“Advantag”中,可见Gartner对这个技术流派的认可。

Javascript Frameworks for Native Mobile这类技术的几个特点:

 

  • 开发期基本采用类Web语言,比如React的语法。

  • 运行期并不是采用Webkit做渲染,而是采用Native的渲染方式。

  • 与Native 进行交互的通道是采用Javascript的方式。

 

当然,因其技术的先进性让各大互联网公司纷纷进行实践上的尝试,取得了不错的效果,包括天猫、腾讯QQ、手机百度、美团点评、携程等等。React Native 也建立了很好的生态,大家对案例如果有兴趣可以关注一下https://facebook.github.io/react-native/showcase.html

 

二、基于React Native 进行移动平台

研发过程中的一些思考

尽管React Native 在移动前端存在着无可比拟的优势,但每一家在工程化的过程中还是存在各自不同的思考。而作为移动平台,不是简单的解决单一的一个App的问题。

 

移动平台是支撑企业全面移动信息化的平台,需要解决企业面向不同场景下的各种诉求。针对移动App的使用者的场景不同,存在面向人和面向组织两种不尽相对的要求:

 

 

面向人:每个人对应的App功能是基本相同的。人与人是平等的,就如今天在线的各位和我一样,在支付宝里看到的功能是相同的。这种情况多出现在面向最终消费者的时候。

 

面向组织:是指功能因其所属的组织和职级决定了其所见和所能用的功能。当事人所处的组织机构发生了变化,功能也随之产生变化。

 

针对面向组织,需要举个例子来说明一下:假如我本人之前是一名普通的manager,其实对于产品线的经营报告并无权阅读(图一);当我被Promote 为产品线总经理的时候,我的App里就应该有“智能报表”的微应用(图二);当我调岗到别的团队(比如从事行政工作),我就不应该再具有“智能报表”的相关功能(图三),如下图所示:

随着岗位和职级的变化,功能从图一到图二再到图三,我还是我,而我App内的功能却发生了变化,这在企业中是非常常见的诉求。

 

实现上述的功能,从技术方案角度看,有多种方式,但是怎么更合理呢?我们可以思考一下。

 

首先,“智能报表”功能是否可以将UI已经打入App中,通过权限控制对应的前端“智能报表”是否显示?回答是不可以。主要原因有三:

 

  • 类似这种功能在企业中非常多,如果要将UI全都打入到App中,这需要所有功能的全集,没有三四百M下不来。而用户实际上只有权限使用几分之一甚至是十分之一的功能,却要每次为此多更新两三百M,这是不合理的。

  • 如果智能报表这个功能在用户安装ipa或者apk的时候,尚未开发完成,而是后续才迭代上线的,那么这个用户就无法及时使用到这个功能。

  • 如果失去了相关的功能权限,需要的是相关的功能清除,甚至包括其相关的数据,而不是简单的隐藏,这既不安全又不合理。

 

这就意味着,移动平台必须能够动态的方式更新应用内功能,而且必须能够结合权限提供按需的热更新能力。

 

其次,在企业中不得不面对的是多供应商的问题,智能报表功能跟其他功能(比如:审批)是一个开发团队开发的吗?

显然,在企业中完全有可能是不同的供应商进行的开发。不同供应商之间,不

 

可能做到代码级的共享的,拿到所有移动项目的代码再进行打包,这是一件非常难以推动的事情。

 

移动平台必须保证对于多团队、跨地域的方式也能支持并行研发。这就意味着必须提供开发期的隔离。

 

移动平台需要支撑上述的业务场景,显然直接使用React Native 是难以满足要求的,这就引发了我们对于React Native实践的一些思考。

 

思考一:React Native 的学习成本和可替换性

 

作为移动平台,不得不考虑的是学习成本,在企业的供应商中是否能够对React Native的技术储备达到相关的要求,如何能够屏蔽对于技术实现的细节。

 

众所周知,React Native 发布版本非常的频繁,一个周之前已经发到0.44,对于大规模使用时,如何屏蔽版本的频繁升级导致的业务代码的重构,方便进行版本的可替换性。

 

如果能够将React Native实现换成其他实现(比如Weex),而上层业务代码能否不需要调整,真正做到实现的可替换性。

 

基于这一点的思考,移动平台采用了基于传统Web语法的DSL,作为开发期语言,降低了RN的学习成本;同时DSL层可以隔离业务代码与平台实现相关性,为后续RN版本更新等提供了良好的隔离,大致的示意图如下:

 

这里需要说明的一点是,我们并没有真正考虑基于Weex作为移动平台的一种实现,而是从技术架构上成为一种可能性。

 

思考二:React Native 的单bundle VS 多bundle

 

在谈论React Native的单Bundle与多Bundle的问题之前,首先,我们先回头看一下React Native 默认的Bundle 机制。

 

在基于RN编写App时,无论开发期创建多少个文件,RN都会将这些文件一并打到一个bundle里去,简单说默认的RN就是一种单bundle的方式,其打包bundle的大概过程如下:

 

因React Native 默认采用的是单Bundle的模式,所以,其更新机制也就仅仅能够以替换这个Bundle的方式进行,虽然有一些通过diff的方式提供增量更新的方式,但这种方案仍然无法满足上面例子中的“智能报表”的按需获取的能力。

 

另外,在进行编译打包的时候,需要获取所有项目的源代码,这对于多供应商的情况下也不适用。

 

所以需要解决的两个问题是:

1、在打包Bundle时,必须提供以多Bundle的方式进行。

2、在开发期,必须解决多微应用每个能够独立以Project的方式存在。

 

思考三:React Native 的调试的首屏进入VS 当前屏刷新

 

对于开发工程师,很重要的工作就是调试,以RN默认的单Bundle模式,势必会带来另外一个挑战,就是当资源发生任何变化时,必须重复上述的打包Bundle的过程并进行加载,看到的UI界面永远是第一屏。

 

实际上,我们期望的绝大多数场景是看到当前修改的资源所在的屏的UI效果。从这个维度看,我们必须能够将Bundle控制在一个资源的粒度,并确保当前bundle的动态热更。

 

另外,虽然React Native 默认不承诺跨平台,但跨平台(即一套代码同时支持iOS、Andriod)是移动平台的必备特性了。如何能够支持多屏同时调试,也将是一个必须考虑的问题。

 

思考四:React Native 的热更新VS 按需更新

 

说到热更新,这里不得不提的是几个月前,一堆的App被苹果拒掉的事情,这个事情曾一度让React Native 等Javascript Frameworks for Native Mobile 技术流派背黑锅。

 

其实这件本质上还是因为某些热更方案调用了私有的API而引起的,后来导致的局面时一堆三方的SDK都受到牵连,最终导致了使用这些SDK的App被拒。插一句,我个人觉着第三方的SDK在没有让使用它们的App知晓的情况下就进行热更新,就是耍流氓,谁又能保证更新后的SDK不做点什么呢。

 

回到热更本身,我认为,基于React Native 进行热更应该是一个必须的特性,而实际上我们需要提高要求,提供按需更新的能力。

 

 

三、基于React Native 进行移动平台

研发过程中的一些实践

 

基于上面的一些思考,我们基于React Native进行了一些实践,这里挑出几点给各位做个简单分享。

 

实践一:引入DSL层

 

首先,我们引入了DSL层,这里的语法采用了传统Web工程师熟知的HTML、CSS、Javascript,而使用移动平台的工程师无须对React进行过多的深入。在HTML的标签定义中,从语义上尽量能够对开发人员亲切,从习惯上尽量保留原有开发人员的一些习惯,比如对state的封装以getter、setter的方式提供能力,而这些标签需要一一以React Component的方式进行了实现。我们以Label为例(后续出现的代码均为示例代码片段):

DSL语言会在开发期编译成JSX,然后再编译成可被React Native 运行的javascript(涉及到拆分Bundle和编译,这里暂不展开)。

DSL编译成JSX,主要的工作原理大致如下:

 

  • HTML 标签的处理,主要是与RN的render进行关联

  • CSS 的处理,主要是与RN的StyleSheet进行映射

  • Javascript的处理,主要是嵌入到JSX中


 

上面的代码示例左侧为基于DSL语言编写的代码,右侧是生成JSX后的代码。

实际上,在工程化过程中,并不是像上面的示例代码那么容易做好,无论标签的定义,还是从DSL转换成JSX都是一个巨大的工程,且会遇到很多的问题。

 

实践二:拆分Bundle

 

在拆分Bundle上,我们遵守两个原则:

1、将系统库作为一个bundle文件,独立存在。

2、将每个的Module作为一个独立bundle文件

 

这种拆分原则将bundle拆分成小粒度的针对Module级别的bundle,这带来的好处是,可以方便的跟DSL中HTML文件进行一一映射,其加载单元的粒度可以理解为Page级别,而非整个App。

 

我们以require 为例,下图为默认的加载方式,如果没有对应的Module Factory,就会以异常结束,如下图:

 

 

扩展后,当判断没有对应的Module Factory的情况下,并不是以异常退出,而是增加了加载对应的Module级别的bundle,如下图所示;

 

 

当然,这就必须需要移动平台自行实现RTC_PM_JSCExcutor用于加载Module级别的Bundle。这一部分代码需要采用原生的Object-C或者Andriod Java实现,下面以iOS的示例代码

 

 

实践三:引入微应用

 

在将每个Module打成一个Bundle后,会让项目内资源的关系不易管理,这时我们引入了微应用的概念,用于完善应用内逻辑关系。

 

 

 

1、将原有的一个App对应一个Bundle的模式,改成一个App对应多个MicroApp,一个MicroApp对应多个Bundle模式。

2、将原有的一个Bundle对应多个Module的模式,裁剪成一个Bundle对应一个Module的模式

 

实践四:多屏调试

 

多屏调试与当前屏刷新,在移动平台IDE端的产品的定义中还是占有很重要的地位,因其直接影响了开发期的效率。

针对React Native 默认的编译核心框架,我们简单的可以总结为四件事情:

 

  • node-haste:主要是监听Module变化 ,把变化的Module从Module缓存中移除。

  • ModuleCache:Module编译缓存,把编译好的Module缓存起来,Module没有发生变化的情况下,直接使用缓存组装成bundle

  • Resolver:实现全局系统级库,语法级兼容实现,包括:ES5,ES6实现 兼容实现的引入 。实现Module factory的包装

  • JSTransformer:调用Babel编译JSX文件到JS。

 

其中1和2有很大原因是因为单bundle导致,当每个HTML文件对应一个Module,每个Module 对应一个bundle后,移动平台需要的就是监听HTML等文件的资源变化即可。如下图:

 

 

而这里的编译引擎基本上做的事情是:

1、DSL->JSX

2、JSX->js

 

其中后者主要的工作如下所示:

 

 

而为了能够更好的调试,需要对相关两种更新机制:

  • 批量更新

a)包括初次批量更新部署,下载所有文件

b)使用过程中检查文件更新部署,判断需要更新的文件列表

 

  • 单页更新

单页更新是确保其可以当前页保存,当前页刷新调试的主要机制

 

 

通过上述的方式,结合移动平台的IDE,可以提供

1、同时支持多手机终端的多屏调试(可以同时iOS和Andriod)

2、提供了当前屏动态刷新动态调试

 

实践五:按需热更

 

当上述的实践完成后,按需更新就成了一个相对较容易做到的事情。所以移动平台提供了两级打包编译机制,在无需调整代码的情况下,可以选择以微应用的方式出现其他的App内,还是以独立的ipa/apk的方式存在以移动设备中。其基本原理如下图所示:

 

四、小结

 

基于React Native进行移动平台研发是一个系统性的工程,上述的工作仅仅是其中的一小部分,期间的坑还有很多,这篇文章也仅是从大粒度的方面进行了分享。

友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。

其他相似内容:

  • atd指令拨号,怎么判断电话状态

    atd指令拨号,如何判断电话状态 在网上找了许久,终于找到一位仁心解决方案,这个指令是可以得到手机当时的状态,但是不管是空号、欠费、...

  • MTK添加应用程序解决方法

    MTK添加应用程序 添加好了模块之后(inc、lis、pth)在用VS2008编译时候报错 提示找不到我新添加文件的头文件,我在makefile里也添加了...

  • 资源编译有关问题

    资源编译问题 make p=d9128 m=resource 后 最后出现了几句话,不知道是什么意思,是否成功 generate resource bin successful! tota...

  • MTK11A怎么更换主菜单顺序

    MTK11A如何更换主菜单顺序? 在vappMainmenuDefaultOrder中更换联系人和通话记录的顺序,r cosmos后。没有更换过来,请问,怎样更换顺序? ...

  • MTK 画png图片 图片边缘有杂色,该怎么解决

    MTK 画png图片 图片边缘有杂色 我在MTK作图中,在处理png图片的时候总是会遇到图片边缘会有一些杂色或者是通透下一层背景图片的问...

  • MTK各种版本,该怎么解决

    MTK各种版本 大家好,我知道MTK有很多版本,但是通过原代码不知道怎么判断,我想请问大家版本怎么判断,还有就是各个版本之间编程有什么...

  • mtk模拟器联网解决思路

    mtk模拟器联网 刚接触mtk,想请教下高手mtk的模拟器是如何连接网络上的,之前有见过别人在模拟器上打开网页。需要修改什么? ------解...

  • 急怎设置让android内置浏览器无地址栏?该如何解决

    急!怎设置让android内置浏览器无地址栏? 想通过一个activity中的按钮链接到另一个网页,由于美观需要,不希望出现地址栏,怎么办? ------...

  • 关于手机浏览器显示谷歌地图的有关问题

    关于手机浏览器显示谷歌地图的问题 请问哪些手机浏览器能正常显示谷歌地图呢,我知道opera可以,safari可以,其他的呢。还有,网页正常显...

  • 怎么在mstar的idle界面画图

    如何在mstar的idle界面画图 怎么在idle上画图呢,比如说画点画线画一个图片上去等. 刚接触mstar,不熟悉。 mstar画idle是哪一个函...

热门推荐: