Why RN
之所以要选择RN,一方面是因为效率问题,另一方面则是历史问题,因为我们公司在刚开始创立的时候只有一个web前端和一个安卓开发。这样的人员配置要想开发App,iOS端就会面临很大的挑战,起初我们采用的方案是Hybrid,但是在iOS产品上线后发现这样的方式表现效果不是很好。综合考虑下最终我们还是采用了React Native进行开发。
RN版本
在使用React Native的过程中首先遇到的就是版本问题。RN的版本更新非常频繁,从0.14更新到0.15用了20天,看起来时间很长,但是这其中发布了5、6个补丁版本,整个的更新频率大致是2、3天一次。要是每次更新都使用新版本开发,就会非常麻烦,而且作为一个新兴的框架,每次更新不仅会修复以前的BUG,同时还会产生新的BUG。我们最终的解决方案是在每段时期使用固定的版本,在使用RN的两年时间里一共采用了4个版本。
组件化
React 的一个重要的特性就是组件化,不仅是在web上,在RN上也可以使用组件化。刚开始使用RN开发iOS的时候我们对js的组件都做了一些简单的包装,不过RN组件不仅仅局限于js,它还有Naïve组件。
对某些特殊的功能其实还是要用到Native原生的能力,所以基于RN的组件化相对web可能对开发者的java或Object-C方面的能力有些要求。
在使用RN开发后效率有了很大的提升,因此不仅是iOS,我们还将RN迁移到了Android,并且不是采用混合开发,而是纯RN形式。
工程结构不统一
不管是RN开发还是web开发都会遇到工程结构不统一的问题,RN的工程结构对比普通React web的工程结构很相似,同时在RN开发中也一样会遇到路由管理组件选择的问题,工程结构的统一主要解决的就是这方面的问题。
RN开发中我们使用的组件是官方提供的react-navigation,并对它进行了自定义的包装实现自己的脚手架来生成RN App框架,当然这里的框架并不局限于路由组件的自定义,还包括部分基础 JS 组件和原生组件(包括定位、地图、相机等)的集成。
热更新
无论是使用RN还是原生开发App,都需要通过应用商店来更新应用。为了应对业务快速迭代问题,就需要用到React Native的热更新特性。对React Native有初步了解的开发人员应该都知道RN实际上可以简单地被分为两部分,一部分是Js ,一部分是Native(Java/OC)。
因此我们自己开发了一个热更新框架,可以通过后端服务与前端特定SDK的配合来做到不通过应用商店更新安装包也能更新业务代码的效果,与此同时我们在针对更新包大小问题做了优化,引入了增量更新方案以减少更新服务器的压力。
对于想要做热更新的朋友,一定要了解APK的应用目录结构以及iOS应用沙盒结构。同时还要了解到RN 中Android和iOS静态资源引用方式,Android端还需要清楚它的安装过程。如果对更新速度有要求,那就需要制定比较详尽的差分策略来支持增量更新。
打包
在解决了业务方的更新迭代需求后,接下来要解决的就是打包的问题。在打包方面我们其实已经有比较完整的生态链路,但是当时所有的5个App打包起来还是非常麻烦。因为最初都是单人维护一个App,打包某个App时需要找到相应的开发者,且针对不同的类型都有自己的包,使得包的数量逐渐增多,同时不同的开发者配置环境也不一样,造成开发者之间无法帮助打包。
为了解决这些问题,我们基于RN自定义一个打包系统。它由三部分组成,首先是配置管理,其次是RN的packager,这个packager相对于原生分为了js打包和原生打包两部分,最后就是安装包管理部分。
发布流程
使用打包系统一键打包后可以手动在热更新平台上上传更新,完成后就能应用到线上。整个过程中其实还是有着人工上传发布的步骤,就有可能会出现发布的错误,比如发错包文件、填错版本号之类的情况。
因此针对打包的发布的流程还需要有自动化的连接,以此来避免人工上的错误。
前面提到过在热更新的时候有增量更新的特性,利用这一特性就能实现预发布和白名单的功能,这样就可以定向的测试针对部分用户的特定业务。
线上App健康状态
App开发完成上线后,还需要花费时间和工具维护,基于这一需求我们实现了一个针对上线App的数据收集功能。之所以要自己开发这样的功能,是因为目前市面上的产品都无法满足我们的定制化需求,而且大多数产品不能将数据的分析维度下沉到用户维度。
上线了数据收集系统后,我们发现上线的App中很多BUG都是测试以后遗留下来的,当时由于人手不足测试总会有些遗漏。针对这个问题我们开发出了基于RN的测试系统,它的大致流程如下。
首先通过可视化的业务流程生成相应的测试用例,根据该用例再生成简单的测试脚本,这个测试脚本会应用到打包的系统上,使得测试和打包被连接在一起,接着打包系统会生成一个针对测试用例的安装包。实际测试功能则会交由第三方完成,因为他们有着充足的真机做兼容性和功能性测试,最后生成的测试报告就会反馈给开发者和相关人员。
数据报表
虽然已经使用RN做了很多事,但是并不局限于此,我们还基于RN的组件化思维以及数据的抽象思维做出了一个可定制化的报表系统。
类似报表这样的数据都有着一定规范,足够的抽象后可以将数据和UI绑定,只需要对指定UI内的数据进行插拔就能实现数据的动态展现。
整个系统的客户端还是使用React开发,后端服务则是 NodeJs 开发的,它以我们现有的数据仓库作为数据源,后端服务消费数据仓库的数据,将其生成特定的数据格式,然后使用 Facebook 开源的GraphQL做UI和数据的绑定,最后展现在App上。这样就做到了在后端编辑添加了报表以后,客户端就能看到相应的报表了,不用特意去更新 App。这对我们公司的报表开发有着极大的提升,在这个系统上线应用之前,我们开发一个报表的周期大概是 1 周左右,当这个系统上线以后,我们开发报表的周期已经缩短到了大概半天左右,效率提升很明显。