汉中搬家公司费用联盟

CODING 技术小馆 | RN 在卖菜公司的落地之路

楼主:扣钉CODING 时间:2021-07-20 15:44:08

本文为 宋小菜大前端负责人及宋小菜资深前端工程师  Scott、陈锦辉 两位讲师在 CODING 技术小馆 · 上海站 的演讲内容整理。


Scott:大家好,今天我们的话题是讲讲 RN 在卖菜公司的落地之路,包括落地的方案,以及在落地过程中踩过的坑。在公司内部我们经常说自己是一个死卖菜的,这不仅是要在创业公司保持一个生死边缘的危机感,同时因为我们选择这个行业,需要保持足够的清醒,只有保持足够的清醒才能在线下的业务渠道或者线上的产品工具支撑上,在不同的阶段做不同的事情。




  行 业 现 状  



提到卖菜大家脑海中很容易浮现出来这样的画面,去选购也好,批发也好,我们希望蔬菜是规规矩矩分门别类摆放整齐的,但现实不是这样的,现实往往是在一个开放的大铁棚里面,无论是卫生还是氛围都是极其混乱的,这就是我们每天吃的菜它在线下真实发生交易的环境。


前面提到的死字,是我们需要死死咬住这个行业深挖深打,除了对现实要保持清醒外,是因为我们希望能够看清楚这个行业的真相。我们说上海也好,成都也好,请朋友到饭店吃饭,在家里做菜,我们不仅不知道这个菜来自哪个省份,哪个产区,哪个基地,在整个种植过程中用的农药化肥剂量,也不知道在蔬菜的运输流通过程中,为了保持蔬菜新鲜所用的冷藏冷冻手段包括化学药水药水是否合规等等,这些都是我们看不到的真相。


到这里大家可以发现中国蔬菜的整个交易流通体系非常非常原始,也非常也非常传统。所以我们想要优化和重构整个中国蔬菜的供应链体系,就决定了我们必须在刚才看到的线下场景中跑通一些业务模型,而跑通这些业务模型就需要在线上给到一些包括产品或者工具的支持。




  线 下 场 景  



我们做的第一件事就是把蔬菜从基地最快的运到各个城市端的批发市场,做这个事情只有两个目的,我们想跳过批发商,让大家吃到的菜更实惠,跳过这些环节,我们吃到的蔬菜会更加新鲜。以上海为例,我们在上海的姜蒜,20% 的姜和 40% 的蒜是我们公司运过来的。要保证这样的业务模型,需要建立一些线上产品,或者是线上偏工具类的产品,在线下跑通这些业务。



这是第一个场景,我们在各个城市端,各个蔬菜产区有采购团队,帮助公司采购各个省份质量好价格也实惠的蔬菜品类,这款 App 就是采秘工作台,帮助采购团队了解下游的订单,库存,便于他们做采购决策。



而蔬菜就来源于我们的供应商,我们开发了第二款 App 就是宋小菜供应商,帮助供应商了解蔬菜在各个城市端的销售情况和价格行情,提早做好进货和出货准备。接下来的 App 是开发出来给宋小菜的司机使用,当蔬菜从基地出来以后,通过这个 App 可以让整个公司了解到蔬菜的一个在途情况,提前做好接货准备等等。



蔬菜运到了各个城市的批发站以后,我们有对应的销售团队以及合作工人帮助把蔬菜运到蔬菜老板的摊位上,这个 App 就是我们的四款 App,宋小福,上面包含一些跟销售有关的核心模块,比如说销售规模绩效等等,这个可以看做是一个公司内部各个团队进行订单数据协同的 CRM 管理工具。最后一个 App 是帮助我们摊位老板提前 1 天、2 天订购到他想卖的蔬菜,订购后,就等着蔬菜送上门就可以了。


为了达到能够重构优化整个中国蔬菜供应和流通体系的目的,我们需要在线下把上面这些场景串起来,所以对应开发出这 5 款 App。大家知道开发 App 的成本很高,为了降低成本,在整个 2017 年,我们从 3 名工程师增加到 5 名工程师,从 2017 年开始正式学习和切换 RN 开发,一年之内沉淀出来 5 款 App,这 5 款 App 的代码量大概是 20 多万行,发布 300 多次,但这个不是重点,重点是基于在技术上的储备和尝试,我们所开发的这 5 款 App ,支撑整个公司线上线下,让协同效率最大化,基于这个协同效率,2017 年我们在全国卖了 20 多万吨蔬菜,这也是我们作为工程师感觉很引以为豪的地方,就是技术结合产品最终所实现的业务价值。接下来就由我的同事陈锦辉给大家分享我们的 App 在我们团队是如何一步步落地的。




  关于 React Native  


陈锦辉:大家好,我叫陈锦辉,由我来和大家聊聊我们为什么要使用 RN 以及使用 RN 时遇到的问题以及解决的方案?宋小菜创业之初前端以及移动 app 的开发人员,只有两个工程师一个 Web 前端一个 Android 工程师,而我们当时需要开发的 App 是要面对安卓和 iOS 两端的,没有 iOS 的工程师怎么办?我们在最开始的时候开发出了一版 Hybrid 的 iOS App,上线后发现以后效果不是很好。我们虽然是创业公司,但是对 App 要求还是挺高的,经过多方面的考察,我们选择了 Facebook 开源的 React Native 框架来开发我们的 iOS 版本的移动应用。


其实我们入了一个大坑,因为我们使用的时候 RN 刚出来,遇到的第一个坑就是 RN 版本不稳定。我们在最开始用的时候,版本更新非常频繁。比如从 v0.14 到 v0.15,两个版本之间只相差18天,听起来很正常,但是两个版本之间还有补丁版本,平均几天一个版本,每个版本修改了上一个版本的 bug 以后会几乎都会出现新的 bug,所以是 bug 堆 bug,我们用的时候也非常激进,出一个版本都想着去更新,每次更新以后又会出现新的问题,非常麻烦。所以后面我们控制住想去更新的欲望,最后选定了一个相对稳定的版本长期支持生产环境。我们使用 RN 两年多,总共用的版本其实只有 4 个。


使用 RN 做 iOS 的开发非常的方便,我们充分利用了 React 可组件化的优势,在开发期间沉淀了很多的组件,包括下拉刷新、定位、地图等等。这大大地提高了我们的开发效率,同时有新人进来时不用关心怎么去实现那些有着复杂的交互的组件,比如一些动画,或者是一些选择框的逻辑等等,我们会在通用组件里做好,新人可以先熟悉这个框架然后再进行再逐步提高尝试开发组件,这对新人来说是一个渐进式的效果。


我们整个 RN 开发人员只有 5 个,有 5 款 App 要开发,早期一般是单人开发一款 App。所以大家在写代码的时候往往是按自己的习惯去写的,代码风格出现了百花齐放的盛况,这导致了一个比较看起来很小实际上很大的合作问题,当有多个人合作写一个 App 就会发现代码的阅读非常困难,大家都习惯于自己的开发模式和代码风格,看着别人的代码很多时候是一脸懵逼的。这个看起来很小的小问题,实际上是会在人员扩张和项目增加和迭代时给团队造成很大的麻烦,与此同时如果任由开发者随性写码、野蛮生长也会造成代码质量参差不齐的情况,这在创业公司应该是比较常见的,所以在团队成立之初就制定好代码规范是很重要的,不然就会走得像宋小菜一样磕磕绊绊。与代码规范相关的合作问题还有仓库协同规范,也是需要及早指定的规则。




  路由、热更新与打包流程  


对于 App 来说,最重要的结构是它的路由,我们在做 SPA 的时候需要考虑选择什么样的工具、路由框架,对于纯 RN App 来说也是如此。早期宋小菜每一个 App 工程结构不统一,使用的路由组件也不相同,这对于我们后面去做自动化是很不方便的。所以之后我们对 RN 工程进行了重构,路由框架使用了 Facebook 官方推荐的 react-navigation,我们使用的时候这个组件才刚出,只提供几个简单的路由跳转 API ,所以我们在这个基础上做了一些定制化,支持了大部分路由操作,现在已经非常的成熟,如果大家在使用 RN 做开发,建议使用这个框架,非常好用,特别容易继承 App 的埋点,第三方的库也很容易集成到这个工程里面。


解决了所有工程化合作方面的问题以后,还有一个非常现实的问题:业务是非常多变的。一个业务公司,当前业务第一天发布,二、三天后马上会有变化。我们开发传统 App 的时候,例如大家发布安卓,如果有自己的渠道发布可以即发即用;iOS 就比较麻烦,会有一天甚至超过两天的审核,非常慢。我们的业务要求是快,有改变可能要马上应用到线上,但是 iOS 审核慢就带来了这么一个非常现实的问题,虽然安卓和 iOS 有热更新方案,但是苹果官方已经禁掉类似于 jsPatch 一类的热更新方案。针对这个问题,我们利用了 RN 可以进行热更新的特点,开发出热更新服务:我们在苹果商店上线一个 App,如果可能需要修改到某一个展示页面,只需要在我们的平台上发布,用户打开 App 的时候就可以应用到我们想要的更新。这样推广的速度很快,如果是普通的更新,苹果不会强制更新,还需要用户去主动下载更新,这就会出现更新覆盖不全面的问题,但是如果使用热更新的方案就可以避免这个问题。这是我们热更新的流程,按照 RN 的框架特点来说我们可以将 App 分为 Native 部分和 JS 部分,热更新不会去更新 Native 部分,而是去更新 JS 部分,因为我们的主要业务逻辑几乎都写在 JS 部分,当我们需要去更新的时候,在我们发布平台上上传一个新的版本的 JS,可以替换到之前的版本的 JS,可以做到热更新的效果。



处理完热更新的问题以后,还有一个对开发来说很麻烦,对我们人力消耗非常大的问题——打包。如果大家做 App 开发,会知道打包非常耗时耗力,平均一个 App 打包时间至少在 10 分钟左右。我们也会遇到这个问题。如果是针对原生的 App 打包,其本身就有成熟的解决方案,例如安卓的分渠道打包。但是基于 RN 的 App 打包就没有现成的方案,所以我们根据自己的实际情况,利用我们在前面做工程结构统一的时候集中工程配置的便利,开发出了一个基于 RN 应用的打包系统,做到了分类型和渠道打包,这样打包的问题就得以解决了。我们的打包系统除了打包之外还兼有一些管理功能。例如我们的开发者 commit 的管理,根据 commit 生成 App 开发周报;例如安装包管理,每一次打包都可以绑定就近的几次 commit 信息,让使用者清楚到底增加修改了哪些功能,然后所有想下载我们 App 的用户都可以通过安装包管理下载到相应的安装包。当然,打包可以不局限于我们的开发者,有权限的打包的用户只需要简单地点击按钮,选择几个相应的选项就可以打包了。



将热更新和打包做完以后,这两个系统实际上没有什么联系。我们的打包流程是自动的,但是打包后的发布却是人工的:打包人在打包平台上打好包以后下载下来,传给发布人,发布人在发布平台上传,然后发布——有人手动参与那么就有可能会有差错,为了避免出现人为操作的失误,我们将两个系统连系起来形成统一的打包发布流程,让系统去做打包和发布的动作,这样就可以减少差错。同时在发布的时候再加上人工审核,填写必要的发布清单,就可以做到自动打包发布了。




  数据搜集及自动化测试  



这样的话,打包发布我们都做完了,就像卖了东西会有售后服务一样,对于 App 开发者来说发布了的 App 也不应该放任不管的,所以我们有了一个迫切需要解决的需求,那就是应用上线后使用情况的搜集和健康状态的监控。虽然现在市场上针对原生安卓和 iOS 的埋点和错误收集有很多的成熟方案,也有基于 RN 的一些解决方案,如 MixPanel、友盟、countly 等,但这些产品要么没办法满足我们的定制化需求,要么就是不对我们开放数据权限。所以我们就自己开发了一个基于 RN 的 App 埋点搜集统计工具,这样我们就能实时查看到 App 的使用情况,以及 App 在运行时出现一些问题,反馈给我们的产品和开发者。


在使用了前面所说的数据搜集工具以后,我们发现我们的 App 存在很多在测试时没有被发现的 Bug。虽然我们尝试过通过手动测试发现并解决问题,但是我们本身开发和测试人员比较少加之 App 比较多、业务迭代比较快,所以我们不可能做到完整的测试,因此我们开发出了基于 RN 的自动化测试系统。



这是我们整个测试系统的大致流程,通过一个简单的可视化编辑,生成对应的测试脚本得到对应的安装包,然后上传到测试平台以后测试生成测试报告,然后反馈给产品经理,这一套流程能让我们在上线之前及时发现问题,并对它做出相应的解决方案,避免上线后 App 出现问题从而影响用户使用。



这里对我之前讲到的东西作一个总结:我们通过组件化来提高开发效率;通过规范工程结构和代码规范以及仓库协同来解决合作问题;使用热更新解决业务方业务变化的需求;使用打包发布流程避免无谓的人力消耗和发布失误;通过测试和埋点跟踪来提高 App 的产出质量。这就是我们整个 RN 落地的大致过程。


总结下来我们好像做了很多事情,其实我们总共只有 7 名开发者,RN 有 5 个开发,web 有 2 个,基建是 3 个。而我们整个大前端开发了 5 个移动应用,1 个 ERP 系统,3 个基础建设系统,还有 3 个内部管理系统。从图示可以看出我们的成员不会局限于某一个技术方向,而是在专注于某一项技术的同时也会兼顾学习其他技术,这样就能很好地提高开发者的自身素质,扩展技术视野。




  报表展示系统  


但仅仅做到这些对我们来说其实是远远不够的,因此我们又往前走了一步——开发出了一个可定制的报表展示系统。这个系统在以后端已有的数据仓库作为数据源的前提下,使用 GraphQL 对数据进行再加工然后展现到终端上,这个系统的核心就是 Facebook 开源的查询语言 GraphQL。我们可以在系统上通过简单的编辑查询条件和指定报表展示样式从而生成相应的报表,再配合客户端定制的 SDK 就能在我们的 App 上展现出相应的报表了。上线了这个报表系统后大大地提高了我们的开发效率,以前要开发一张报表需要至少 3 天的开发周期,而现在只需要一两个小时就能搞定了,而且开发报表的人不再局限于开发者,产品经理或者业务方也能生成报表,并且指定有权限的用户在客户端查看。


受报表系统的启发,我们发现其实我们可以去操作的数据不仅仅是报表,几乎所有后端提供给我们的可以用于展现的数据都可以进行一次加工然后被我们更好地使用。因此我们开发出了一个数据交互引擎,用于整合后端交给我们的数据,对它们进行二次抽象加工,变成符合我们 UI 展示的结构,这样不仅省去了后端面向页面开发这一步,同时也方便了前端对数据进行灵活运用,这里是我们的框架结构图,在做数据处理的同时我们也加入了缓存机制,避免 GraphQL 出现的慢查询问题。




  结 语  


Scott:我们前端工程师在业务场景当中,有两件事情要记住:第一不要怕,遇到很多业务压力以后不要怕,顶着上;第二是真正业务满足以后,要继续往前行,才有能力往下挖。前面提到我们公司去年一年的蔬菜销售数量是 20 多万吨,中国老百姓一天吃的蔬菜就是 20 多万吨,我们去年卖的一年的菜够中国老百姓吃一天,我们只做了 1/365。这是我们从今年开始最大的业务挑战,只要工程师保持对自我能力的挖掘,这些问题都能迎刃而解。谢谢大家。




  更多技术小馆文章  


CODING 技术小馆 | 前端美学 · 字体排印的道与术

CODING 技术小馆 | WebIDE 前端札记

CODING 技术小馆 | 快速设计和构建一个高可靠、高扩展性的直播答题系统

CODING 技术小馆 | 极光推送后台服务架构实践


朋友 图片 表情 草稿箱
请遵守社区公约言论规则,不得违反国家法律法规