admin 发表于 2022-7-25 03:46:38

框架设想:RN端的框架如何设想取落地-SegmentFault思否

  App 的版本更新,RN 除了保守的 App 更新外还有一个热更新的可选项(保守 App 更新也有热更新,其道理就不太一样了),社区大大都人都保举使用codepush来进行热更新,至于其后端处理方案 貌似已经有了一个code-push-server,我们是使用本人的热更新方案,其道理就是在不更新原生代码的根本上更新 JS 代码和静态资源文件。
  同时,如果对react-navigation进行合理的定制,接管其路由管理,那么我们还能实现保管用户退出 App 之前最初浏览的页面的形态,用户鄙人次打开 App 仍然能够从之前浏览的地方继续使用 App,当然,这个功能要谨慎使用!
  我们在建立工程时尽量将所有的配置笼统统一放置在一个地方,这样便于查找和修改。但是由于大大都配置都统一放在同一个地方,那么就不免有部门文件要使用某个配置时其援用路径比较长,好比:
  除了 RN 本身版本,还有第二个问题,环绕着 RN 有很多业界优良的组件,但这些社区组件以至官方组件,都不必然能及时跟进最新的 RN 版本,同时还能兼容到较老的 RN 版本,所以 RN 升级导致的组件不兼容性,会引发你 Fork 修改组件的感动,但这样会带来额外的开发成本和版本维护成本,选择会成为版本升降的终极问题。
  这样,我们就能很便利地将分离在项目遍地的图片资源统一到一个地方进行管理了,使用起来也很是便利。
  这些稠密的需求队列对我们的代码质量有很是高的挑战,一个组件用 5 分钟思考如何笼统和用 50 分钟思考,实现后的不变性、兼容性都是不一样的。如何包管产物按期交付上线,会是摆在我们面前一个很是环节的命题,而这个难题之外,还有一个更难的命题等着我们,那就是如何包管交付不延期的同时,还能包管交付质量。
  RN 的 App 工程骨架,全部笼统完毕,再搭配上组件化,就能够称为一个基于 ReactNative 定制的 App 框架了,而 RN 涉及到原生层面的技术细节太多,我们暂不做会商,只专注在工程取业务的封装上。
  组件规范指的是 UI 设想规范,我们能够取设想同学交换划定好一套特定的规范,然后将通用的样式属性(如主题颜色,按钮轮廓,前往按键,Tab 根本样式等)定义出来,便于所有的组件让开发者在开发时使用,而不是开发者各自为政在开发时反复写样式文件,这里保举一个比较好用的用于样式定义的三方插件react-native-extended-stylesheet,我们能够使用这个插件定义我们的通用属性:
  做为工程师,我们有很强的自大心和不容挑战的代码洁癖,但在一个创业公司里面,以至大公司的一个创业团队里面,我们需要对接一些环节的业务节点,冲刺一些特定的时间窗口,而且要及时响应多变的业务,和业务背后多变的产物形态,这城市带来很是稠密的需求队列。
  使用 RN 开发 App 本身效率就比较高,如果想要继续进阶就要考虑组件化开发,一旦涉及到组件化开发,就不成避免地会涉及到组件管理的问题,这里的组件管理比较宽泛,它实际上该当指的是:
  当图片需要在多处使用时,我们可能会将这些可能会被反复使用的图片统一管理到assets文件夹中,统一管理和使用,但是当需要使用图片资源的文件嵌套较深时,援用图片就变得麻烦:
  React只是视图层的处理方案,对于复杂使用,需要涉及形态之间的共享、各层级组件之间的通信、多接口之间调用的同步等等,就需要进行使用形态管理,Facebook最早提出了Flux架构想想,后来社区又出现了Redux、Mobx等很多种模式。颠末调研比较,我们选择了Redux进行使用形态管理,Redux的核心概念主要是通过Store、Action、Reducer、Dispatch实现单向数据流动,具体概念请参考官方文档。Redux通过middleware机制,能够对Redux进行各类能力加强,这个加强其实是在action分发至任务处置reducer之前做一些额外的工做,dispatch发布的action先顺次传送给中间件,然后最终到达reducer,所以使用middleware机制我们能够拓展很多能力,例如我们使用了形态持久化插件redux-persist,形态记录和沉播插件redux-logger,而异步操做插件我们经历了两轮技术选型redux-thunk和redux-saga。
  线下越沉,线上需要越轻,这个轻指的是轻便轻巧和简洁易用,B2B2C 生鲜范畴在线下是如此之沉,那么在买卖场景线上化的过程中,端的移动化就势在必行,试想一下,让菜市场摊位老板人手一台笔记本点开网页选购领取,让采购发卖抱着电脑去拜访客户,一边聊蔬菜行情,一边打开笔记本进行记录,有没有一种回到世纪初的感受。
  既然需要缓存的数据可能是会在 App 很多地方使用到的全局数据,那么我们能够将这些全局数据使用redux来进行管理,而利器redux-persist则能让我们很文雅地读写我们的缓存数据。
  制定一整套组件开发尺度的是很主要的,由于很多组件开发可能是多人维护的,有一套既定的规范就能够降低维护成本,组件使用的说明文档的完善也同样主要。
https://segmentfault.comhttps://cdn.nlark.com/yuque/0/2019/png/87555/1564651585718-f1d0eee6-75be-4ea0-bd52-731d183c3e03.png#align=left&display=inline&height=1194&originHeight=1194&originWidth=2144&size=0&status=done&style=none&width=2144
  这个问题取配置管理的问题一样,能够首先将图片资源按照类型进行分类,好比 assets 文件夹下有 button/icon/img/splash/svg 等,每一个类型的布局如下:
  路由管理做为整个 App 的骨架,它是这几个部门中最主要的一部门,合理地定制和使用路由管理能够极大地简化我们的开发复杂度。
  然后再在assets文件夹下编纂index.js,将所有的图片资源做为assets模块暴显露去,为了避免和其他模块冲突你能够修改模块名为xxAssets
  什么是通用组件?即能够在 App 范畴内使用以至于跨 App 使用的组件,这里能够对这个类别进行细分,我们将能跨 App 使用的组件上传到了本人的搭建的私有 npm仓库,便利我们的 App 开发者使用,同时,具有 App 本人特色的组件则放到工程中统一管理,同样合用providesModules暴显露去。
  此中asset文件夹保管我们的图片资源,在index.js中对图片进行援用并表露为模块:
  古典互联网时代,由于要兼容 IE678 而痛苦不胜,Hack 黑魔法经验基本代表前端程度,如今互联网早已移动化,我们抱负中的移动端开发,看上去是能够斗胆使用新语法特性,只需要做好尺寸兼容就好了,但现实并非如此,不只在移动端的浏览器不是如此,在移动端开发 RN App 也是如此,这是我们某一款 App 一段时间内,所收集上来的手机厂商分布:
  关于组件类型我们会抛开三方组件以及原生组件,由于一旦涉及到这两者,需要写的工具就太多了,我们将组件按使用范畴分为通用组件和业务组件两大类。
  这样就形成了阅读性很差且代码不美妙,因而我们能够使用 Facebook 的fbjs模块提供的一个功能providesModule:
  回到本文的开头,我们在长链路的 B2B 生鲜场景中,为了更快更轻,开发出了 7 款 App,并且将来跟着业务场景的拓展会诞生更多独立 App 以至是集大成的 App,所以技术选型不太可能选择原生的 Java/Object-C 开发,特别对于创业公司,7 款 App 得需要多少名原生开发工程师才能搞定,高屡次沉的业务变化又怎样靠堆人来包管?
  要晓得,如果一个项目代码赶的太毛糙,后期维护起来的成本会是巨大的,以至只能用更高的成本沉构沉写。本质上,再次沉构就必然是公司在为晚期的猛冲买单,为这些技术债买单,如何不去买单或者如何用最小的成本买单,这跟我们晚期的业务稠密程度,交付周期,质量把控有很大的关系。
  静态资源泛指会被多次调用的图片或 icon,我们一般在 RN 使用图片时是间接援用的:
  产物的移动化,这将是我们展开这篇文章的布景,我们会先了解小菜的产物托管在哪些端上,然后感触感染这些端带来的挑战,最初是我们聚焦如何做移动端的框架封装,包含必要的基建部门。
  我们晓得有一个词叫做主观能动性,表示没有条件缔造条件也能够上。这个词的主体就是人,聊完移动端设备现状和社区现状后,我们来聊聊人的问题。RN 在国内真正开始普及使用,是从 2015 年开始,也就意味着,到 2019 年,一个 RN 工程师最多也就只要 4 年的工做经验,而 RN 的 “Learn once, write anywhere” 也刺激着一切 Care 人员开支, Care 产物研发投入性价比的公司纷纷跳水研究 RN,争抢 RN 人才,RN 是前端中的移动前端,前端有多抢手,那么 RN 工程师就比它还要抢手。
  这些避不开的现实,是绕不外去的坎儿,必需通过人才储蓄和技术基建来缓解,接下来我们进入到本文的沉点 - RN 框架的封装。
  当然,Networking的功能不止于此,还有很多其他有味的功能能够发掘,能够间接用它来包装本人的网络请求东西,还支撑abort,能够参考源码来具体把玩。
  综上,移动端碎片化所带来的兼容难度,RN 框架的局限性,版本间差别带来的不不变性,技术社区资源的匮乏和前端团队技术能力掣肘,再叠加上高密度的业务排期,让前端开发这个本来很酷的工作,变得晴雨不定。
  能够发觉 Android 的碎片化很是严沉,每一个厂商下面有不一样时期推出的不一样型号的手机,这些手机有着不一样版本的操做系统,不一样的分辩率和用电策略,不一样的后台进程管理方式和用户权限,要让一款 App 在哪怕头部 40% 的手机上兼容,都是一件艰难的工作,这个客观物理现状叠加下面的社区现状,App 质量包管这件工作会变得雪上加霜。
  总结一下,一个 RN App 架构该当要包管 App 的运转不变以及开发的便利。运转不变这一方面,除了从 JS 层面(如单元测试,JS 错误上报等)包管之外,很大程度上还要依赖于原生层面的处置,所以团队里面要有同学的精力能够投在原生研究上面,至于开发便利,我们尽量将复杂主要或者简单繁琐的操做在建立工程时就做掉,这样也能够大幅度提高我们的开发效率,降低开发者之间的合做沟通成本。
  前 7 款 App 都是基于 ReactNative 开发的 iOS/Android App,最初两个是微信小法式,它们涵盖了公司几乎所有的协同场景和工做流。
  这就导致基本上 RN 工程师很难靠外部聘请,只能靠内部培养。这也是小菜前端的成长过程,我们有2 名资深 RN 工程师,一个是从办事端 Java,一个是从原生 Android 开发转过来的。如果 RN 人手不足,产物支撑的力度和速度就必然会遇到瓶颈,这就是我们已经面临的问题,就是人才现状,外招数量不足,内培速度无限,RN 工程师的数量和能力就时不时成为公司业务扩张的瓶颈。
https://segmentfault.comhttps://cdn.nlark.com/yuque/0/2019/png/87555/1564651585717-8c62b596-ea6b-47db-8c9a-f01773fa4de0.png#align=left&display=inline&height=996&originHeight=996&originWidth=1508&size=0&status=done&style=none&width=1508
  在国内开发,还有第三个问题,就是中文文档缺乏,社区资源匮乏,参考文献陈旧,可拿来主义的开源工程方案以至社区线上线下会议分享都很缺乏,一个不小心就会踩坑,这就是 RN 社区的现状,我们在刀尖浪花上独步,App 选型背后的技术栈不变性则成为悬在头上的一把铡刀,你不晓得什么时候会咔嚓一声。
  最初,关于使用形态管理,还有一个话题能够会商,就是形态的不成变性immutable。在redux中形态是不成变的,每个reducer城市产生新的不成变形态。那么这个不成变性能否需要不成变js库(好比immutable.js)的支撑呢?简单来说,immutable.js能够带来计算效率和存储效率的提升,但是它需要使用库支撑的数据类型,所以如果从头建立一个使用,能够选择。如果是对于一个已有的复杂使用进行沉构,那就需要分析考虑一下了。
  小菜晚期环绕着蔬菜销地以客户集单批发的模式摸爬滚打几年,从上游的蔬菜供应商到下游批发市场的摊位老板,在这个长长的链路中,我们诞生了这样几款线上产物来办事于不一样的人群和场景,之前文章中也有介绍,这里再汇总一下,共 9 款 App:
  首先什么是业务组件?即我们在开发某个业务产物常用到的组件,这个组件绑定了取业务相关的一些特殊属性,除了这个业务开发以外,其他地方都不合用,但是在开发这个业务时多个页面会屡次地使用到,所以我们有必要将其笼统出来,便利使用。
  网络请求这块,react-native 使用whatwg-fetch,我们也能够选择其他的三方包如axios来做网络请求。但有时候我们会在开发中遇到一个问题,那就是我们明明已经在代码里已经修改了 cookie, 但是每次请求可能还是会带上之前的 cookie 从而形成一些搅扰,所以这里保举一个实用的组件Networking:
  这样就能很便利地在 App 的任意一处使用 config 了,但是我们要避免滥用providesMoudle,由于使用了providesMoudle进行声明的模块的源码,想要在编纂器中使用跳转到定义的方式去查看比较困难,晦气于团队多人合做。
  开发 App 就不成避免地会遇到如何管理页面以及处置页面跳转等问题,也就是路由管理问题,自从 Facebook 打消了 RN 本身自带的 Navigator 以后,很多依赖于这个组件的开发者不得不将目光投向百花齐放的社区三方组件,FB 随后保举大师使用的是react-community推出的react-navigation,此刻这个路由组件已经独立出来了。我们在开发时就是使用的这个组件做为路由管理组件,只不外是在其根本上做了一些定制 ,使得使用愈加简单,部门跳转动做愈加合适我们的产物场景,保举大师使用这个组件。当然,除去这个组件还有很多其他的组件可供选择:
  想清楚这些,一开始我们就调研 ReactNative,并最终全部从原生切换到了 RN。通过跑过来的这 4 年来看,使用 RN 为公司节约了大量的人力成本同时,也尽可能的满足到了几乎所有的需要快速迭代的业务场景,又快又轻,成为宋小菜大前端团队干事的一个典型特征。
  一般情况下需要缓存的数据基本上就可能是我们会在 App 很多地方城市使用到的全局数据,如用户消息,App 设置(非使用层面的设置)等,RN 提供一个AsyncStorage存储引擎,凡是的使用方式是对这个数据引擎进行包装后暴显露合适我们要求的读写接口。这里保举别的一种使用方式:
  这样,我们就能在开发的任意插件或者 App 中间接使用这些根本属性,当某些属性需要修改时只需要更新mystyle组件即可,别的还能够衍生出主题切换等功能,使得开发愈加灵活。
  但换一个角度看,就是带来的问题。又快又轻的背后是 RN 版本的飞速迭代,截止到目前,也就是 2019 年 4 月份,RN 还没有推出一个官方的正式的持久维护的不变版本,什么意义?就是 RN 目前仍然处在不不变的研发周期内,我们仍然站在刀尖上起舞,用不不变的 RN 版本试图开发不变的使用。四年走来,我们在 RN 的框架里,多少次面对旧版本局限性和新版本不不变性都进退不得,旧版本的 Bug 可能会在新版本中修复,新版本引进则会带来新版本本人的问题。
  汇集的 App 使用数据(包含非常数据)并对此阐发,按照阐发来定位问题是包管 App 质量的有用手段之一。你能够选择本人搭建一套数据汇集办事,包含客户端 SDK 和办事端汇集办事,或者选择市场上已有的东西,目前较为成熟的收据汇集东西比较多,如友盟,mixpanel,countly等等,在此不做赘述。
  Redux-thunk的实现很是简单,使用也很是灵活。我们能够在action中处置各类异步操做,也能够做任何工作,但是它的错误谬误是它缺乏对异步的间接处置,异步操做分离在各个action 中,而同步接口等操做依赖使用者本人的实现。
  于是我们进而选择了支撑generator的redux-saga。Redux-saga通过一个类似于独立线程的方式管理你的使用法式中的副感化,这意味着你能够通过普通的redux action开始、暂停或者打消saga线程。Redux-saga使用ES6的generator来管理异步流,使得业务逻辑的读写和测试变得更简单。在我们最新的架构中,我们其实使用的是蚂蚁金服开源的dva-core。之所以选用dva-core,主要是由于dva-core整合了redux和redux-saga,而且使开发者能够通过一个定名的model文件集中管理一个业务逻辑的state,通过定义的effects管理副感化操做,通过定义reducers管理其他处置函数。一个完整的model大要是这样的:

搁浅i 发表于 2023-3-7 20:42:03

:D我是第一个回的耶~
页: [1]
查看完整版本: 框架设想:RN端的框架如何设想取落地-SegmentFault思否