贝贝的组件化之路

2024-02-24 18:40
文章标签 组件 贝贝 化之路

本文主要是介绍贝贝的组件化之路,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

 

为了更好满足各种业务快速迭代

解决代码依赖和构建速度慢的问题

提升产品的质量

贝贝组件化系统应运而生

 

1

贝贝APP组件化的好处

 

组件化的实现不仅给我们带来开发上的便利,也让我们的业务模式发生了巨大的变化。

 

  1. 按月迭代加快到按周迭代,可以采取火车头方式进行发布版本,迭代速度更快,不再因为业务耦合情况,在发版时候,由于互相等待而迟迟不能发布版本。

  2. 稳定的公共模块采用依赖库方式,提供给各个业务线使用,减少重复开发和维护工作量。

  3. 迭代频繁的业务模块采用组件方式,各业务线研发可以互不干扰、提升协作效率,并控制产品质量。

  4. 为新业务随时集成提供了基础,所有业务可上可下,灵活多变。

 

2

贝贝组件化的诞生

 

随着贝贝的迅猛扩张,我们也不再满足于单一模式,业务与日俱增,业务间的关系日趋庞杂。

贝贝原始工程结构

 

模块的数量越来越多,代码也越来越多,千丝万缕的相互依赖,长达8分钟的代码构建时间,困扰着贝贝的工程师,也极大的限制了贝贝工程师的开发效率。

 

为了更好满足各种业务快速迭代,解决令人头疼的代码依赖和构建速度慢的问题,并提升产品的质量,贝贝组件化系统应运而生。

 

3

贝贝组件化系统简介

 

贝贝组件化系统由代码业务模块、自动构建系统、配置文件管理、Maven库四个部分组成。

 

其中Maven库用于存储组件模块,配置系统用来以“火车头”的形式进行版本的发布。

 

不同模块的代码在自动构建系统中以aar的形式生成中间包,代码以模块的形式插入贝贝的壳工程中,以事件总线的方式将不同的模块集合在一起,组合形成不同的待发布的贝贝版本(其中贝贝壳工程为必选组件)。

 


    贝贝组件化系统

 

4

贝贝事件总线

 

按业务拆分之前,各个业务之间不同页面之间页面跳转、页面之间的数据传递就成了首要解决的问题,而为此我们也经历了比较痛苦的过程。

1

臃肿时代

在这个时期,所有的页面都在同一个项目中。

 

  1. 页面跳转:   

    所有的跳转都是通过直接的Class类型来进行跳转

    Intent intent = newIntent(this, xxxx.class);

     

  2. 数据传递:

    直接页面startActivityForResult返回获取, 间接页面通过存储或者变量 。

     

优点:方便,简洁

缺点:目标页面接收的参数需要看代码(没有文档化),每一个目标页面

的跳转都需要跟开发人员沟通,沟通成本过高。

2

拆SubModule时代

此时贝贝的业务已经有3~6个了,在Project下面已经各自拆分成了submodule, 不同的业务开发人员进入自己所属的业务中。

 

  1. 页面跳转:

    通过公共的BeiBeiSdk(被业务引用)里面建立一个IntentUtils文件来处理,由于此时已经在各个业务模块里面加入了host, name,如下图

     

     

    打开通过url打开

  2. 数据传递:

页面之间通过EventBus来传递数据

优点:android,iOS与H5客户端可以通过一些简单的url来实现跳转了,通                   过文档来约束各个页面的参数。

      缺点:多个业务组的人共同改同一个文件,导致文件的冲突率异常高,经常                 两端data不一致导致H5只能跳转到android或者iOS.

3

组件化

此时已经通过各个业务组输出aar deploy进主工程了,主工程不用感知各个业务的具体变化,并且各个业务已经是不透明的了,无法通过上面的方式来做页面跳转或者数据传递。

 

为了统一客户端的所有跳转,做了统一URL的动作

bb     /  base/ product

[app]   [业务名]    [页面]

 

目前支持的URL如下,H5页面可以通过URL跳转到任何页面

beibei://bb/base/product

beibei://product

http://www.beibei.com?Beibeiapp={"target":"product", "desc":"desc"}  

beibei://action?target=product

4

新总线的调用方法:

  1. 页面跳转:booleanresult = HBRouter.open(this, “beibei://bb/base/product?name=zs”);

  2. 数据获取:Object  o=HBAction.open(this, “beibei://bb/base/product?name=zs”);

     

如何设置TargetURL 与页面(Activity, Controller)的对应关系,我们设计了一套Router系统,

当时考虑了两种建立关联的方式:

  1. 每个业务初始化时注册一个服务,在运行的时候让 url与页面建立关联。

  2. 在页面编译的时候让URL与页面建立关联。

 

由于第一种会存在业务人员同时改同一个文件的问题,以及文档维护性的问题;最后选择了第二种,通过编译时与页面建立关联,通过在页面上写编译时注解让每个业务人员只需要关心自己的页面,并且通过服务器公共JSON文档来约束以及生成测试Router来判断业务人员是否写入正确。

 

页面注解以及服务注解(获取某一业务的数据)格式

页面注解:注解添加在页面上(Activity)业务组的开发人员通过后台的文档确定页面的URL,通过HBRouter.open(url)来打开其他业务的页面

 

服务注解:注解添加在对应的Action类上,类似于数据的API库,里面实现各个服务的具体逻辑。

 

优点:业务之间相互不影响,每个业务都可以很happy的开发了,想获取数据,想进入页面,进入后台看api文档。

缺点:页面暂时不支持fragment级别的,只能传入进去。

 

5

贝贝拆包之路

1

拆分标准

贝贝拆包设计原则

横向按照业务粒度, 纵向依照复用依赖

2

如何整合

每个业务打包成aar(依赖一个BeiBeiSDK),在APP层做集成。

3

如何管理业务库

开发中使用snapshot快速集成;集成测试前转成版本号迭代,git tag标记具体版本号,兼顾版本开发和持续集成。

Jenkins提供模板,各业务搭建各自的2个任务(dev分支的snapshot版本, master上tag的稳定版本)。

APP层,通过共同编辑的各个aar版本号文件,做整体打包,制作最终apk。

4

优点

业务之间界限清晰,隔离修改,使review实施简单。

App编译速度提高;各业务嵌入到APP开发时,不需要编译其它业务源码。

每个版本的发布组合可控,每个子业务的改动在开发阶段不互相感知,在集成阶段简单可控。

 

6

贝贝自动构建系统

 

现在贝贝的完成了组件的分拆,将贝贝APP拆成了许多独立的业务组件,也完成完成了业务之间的通信标准和方案,那剩下的问题就是我们如何使这套系统运转起来。最简单的方案是基于我们已有的Jenkins系统改起,建立一套简单易用的构建系统。

 

该系统自动构建流程如下:

  1. 子模块自动构建aar包。

  2. 子模块通过gradle内的task自动上传aar包(或者aar-snapshot包)到Maven库。

  3. 主工程通过配置系统决定将那个版本的tag打入主工程。

 

7

版本配置文件管理模块

 

   

版本的配置文件管理模块由配置文件和配置文件管理两个部分组成,配置文件决定了壳工程将要集成的每个子模块的版本,在开发工程上配置使用snapshot配置。

 

8

 

Maven库

 

用于存储组件的aar文件,为私有仓库。

 

 

9

我们是如何解决构建速度问题的

 

 

阶段

优化前

组件化后

实时更新snapshot

组件化后

不实时更新snapshot

交易线构建时间

8分

1分40秒

1分钟以内,最快12秒

 

贝贝代码编译速度对比

 

 

到此为止组件化系统已经完成,那我们是如何将开发代码的编译速度由8分钟提升到1分钟以内的呢?

 

答案就在上面的整个系统中,我们在实际开发业务代码的时候只会修改一个模块并且只编译该模块的代码,所需依赖的模块直接从Maven库获取并通过aar-snapshot的形式进行更新。

这篇关于贝贝的组件化之路的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/743009

相关文章

SpringQuartz定时任务核心组件JobDetail与Trigger配置

《SpringQuartz定时任务核心组件JobDetail与Trigger配置》Spring框架与Quartz调度器的集成提供了强大而灵活的定时任务解决方案,本文主要介绍了SpringQuartz定... 目录引言一、Spring Quartz基础架构1.1 核心组件概述1.2 Spring集成优势二、J

Vue中组件之间传值的六种方式(完整版)

《Vue中组件之间传值的六种方式(完整版)》组件是vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用,针对不同的使用场景,如何选择行之有效的通信方式... 目录前言方法一、props/$emit1.父组件向子组件传值2.子组件向父组件传值(通过事件形式)方

Spring组件初始化扩展点BeanPostProcessor的作用详解

《Spring组件初始化扩展点BeanPostProcessor的作用详解》本文通过实战案例和常见应用场景详细介绍了BeanPostProcessor的使用,并强调了其在Spring扩展中的重要性,感... 目录一、概述二、BeanPostProcessor的作用三、核心方法解析1、postProcessB

kotlin中的行为组件及高级用法

《kotlin中的行为组件及高级用法》Jetpack中的四大行为组件:WorkManager、DataBinding、Coroutines和Lifecycle,分别解决了后台任务调度、数据驱动UI、异... 目录WorkManager工作原理最佳实践Data Binding工作原理进阶技巧Coroutine

Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)

《Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)》文章介绍了如何使用dhtmlx-gantt组件来实现公司的甘特图需求,并提供了一个简单的Vue组件示例,文章还分享了一... 目录一、首先 npm 安装插件二、创建一个vue组件三、业务页面内 引用自定义组件:四、dhtmlx

Vue ElementUI中Upload组件批量上传的实现代码

《VueElementUI中Upload组件批量上传的实现代码》ElementUI中Upload组件批量上传通过获取upload组件的DOM、文件、上传地址和数据,封装uploadFiles方法,使... ElementUI中Upload组件如何批量上传首先就是upload组件 <el-upl

Vue3中的动态组件详解

《Vue3中的动态组件详解》本文介绍了Vue3中的动态组件,通过`component:is=动态组件名或组件对象/component`来实现根据条件动态渲染不同的组件,此外,还提到了使用`markRa... 目录vue3动态组件动态组件的基本使用第一种写法第二种写法性能优化解决方法总结Vue3动态组件动态

四种Flutter子页面向父组件传递数据的方法介绍

《四种Flutter子页面向父组件传递数据的方法介绍》在Flutter中,如果父组件需要调用子组件的方法,可以通过常用的四种方式实现,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录方法 1:使用 GlobalKey 和 State 调用子组件方法方法 2:通过回调函数(Callb

Vue项目中Element UI组件未注册的问题原因及解决方法

《Vue项目中ElementUI组件未注册的问题原因及解决方法》在Vue项目中使用ElementUI组件库时,开发者可能会遇到一些常见问题,例如组件未正确注册导致的警告或错误,本文将详细探讨这些问题... 目录引言一、问题背景1.1 错误信息分析1.2 问题原因二、解决方法2.1 全局引入 Element

vue解决子组件样式覆盖问题scoped deep

《vue解决子组件样式覆盖问题scopeddeep》文章主要介绍了在Vue项目中处理全局样式和局部样式的方法,包括使用scoped属性和深度选择器(/deep/)来覆盖子组件的样式,作者建议所有组件... 目录前言scoped分析deep分析使用总结所有组件必须加scoped父组件覆盖子组件使用deep前言