前言
随着公司业务的不断发展,团队不断壮大的同时,项目也随之臃肿起来,如何保障团队协作的高效,自然的想到了组件化这个话题。下面总结下本人的梳理和思考。
组件化
- 为什么我们需要组件化 项目模块间的解耦、模块实现可重用、提升团队成员之间团队之间的协作开发效率、更方便单元测试。
- 并不是所有的项目都适合组件化 如果你的项目较小,模块之间交互简单,耦合很少;模块没有被外部模块引用,只是一个单独的小模块;模块不需要重用,代码也很少被修改;团队规模很小。那么,你对项目就没有必要做组件化。
如果你的项目有以下三个特征以上,就要考虑下进行组件化了:
- 模块
逻辑复杂
,多个模块之间频繁互相引用
; - 项目
规模逐渐变大
,修改代码
变的越来越困难
(这里可以理解为:修改一处代码,需要同时修改其他多个地方); - 团队
人数变多
,提交的代码经常和其他成员冲突
; - 项目
编译耗时较长
; - 模块的
单元测试
经常由于其他模块的修改
而失败
。
- 组件化的8条指标
一个项目经过组件化后如何来评判项目组件化是否彻底或者说是否优秀,可以通过以下几个方面:
模块之间没有耦合
,模块内部的修改不影响
其他模块;模块可以单独编译
;- 模块间
数据传递明确
; - 模块可以
随时
被另一个提供了相同功能的模块替换
; - 模块对外接口清晰且易维护;
- 当
模块接口改变
时,此模块的外部代码
能够被高效重构
; - 尽量
用最少
的修改和代码,让现有的项目实现模块化; - 支持
OC和Swift
,以及混编。
前4条
主要用于衡量一个模块是否真正解耦
,后4条
主要用于衡量在项目实践中的易用程度
。
组件化分层
一般一个项目主要分为三层:业务层、通用层、基础层
组件化封层之后,需要遵循一下原则:
- 只能 上层对下层 依赖, 不能 下层对上层 依赖(下层是对上层的抽象);
- 项目公共代码资源下沉;
- 横向的依赖尽量少有,最好下称到通用模块或者基础模块。
cocoapods组件化
1.创建远程私仓
- 从git等代码托管平台或者公司的git仓库创建远程代码仓库
- 本地仓库和远程仓库关联,并作为组件化工程目录。
建议使用公司的git仓库,可以公开给需要的人员使用,也避免代码泄露问题。
具体操作参考git的使用
2.创建组件模块工程
打开终端,cd到工程目录下执行命令:pod lib creat 组件名
如我的组件名称为:component-test, 命令:pod lib create component-test
创建完成工程的目录如下:
编译成功之后,就可以把自己整理的组件化相关的代码拖入到对应的目录Classes下
路径如下:
测试组件化代码如下
IWComponent.h文件如下/* IWComponent_h */IWNStringRegex.h文件如下NS_ASSUME_NONNULL_BEGIN@interfaceIWNStringRegex : NSObject+ (BOOL)isValidEmail:(NSString*)email; @endNS_ASSUME_NONNULL_ENDIWNStringRegex.m文件如下@implementationIWNStringRegex+ (BOOL)isValidEmail:(NSString*)email{ NSString*emailRegex=@"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"; NSPredicate*emailTest= [NSPredicatepredicateWithFormat:@"SELF MATCHES %@", emailRegex]; return [emailTestevaluateWithObject:email]; } @end
3.使用示例应用程序测试组件功能
- Classes 中的文件修改后,打开终端cd到Example下进行 pod install (刚才添加到 Classes 中的文件夹 pod 进来)
- 引入头文件,使用相应的功能
@interfaceIWViewController () @end@implementationIWViewController- (void)viewDidLoad{ [superviewDidLoad]; // Do any additional setup after loading the view, typically from a nib.NSString*email=@"fan@iw.com"; BOOLisEmail= [IWNStringRegexisValidEmail:email]; NSLog(@"是否是邮箱:%d", isEmail); } - (void)didReceiveMemoryWarning{ [superdidReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}
- 测试结果:
2022-10-1020:50:29.628168+0800component-test_Example[1448:25782] 是否是邮箱:1
4.修改 podspec 文件
- 编译示例应用工程,测试组件通过,开始修改 podspec 文件。
一般修改一下几个内容:
- 修改版本号
- 修改项目的简单概述和详细概述
- 修改 homepage 和 source 地址
- 添加依赖库
podspec常用字段含义和修改如下
## Be sure to run `pod lib lint component-test.podspec' to ensure this is a# valid spec before submitting.## Any lines starting with a # are optional, but their use is encouraged# To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html#Pod::Spec.newdo |s| s.name='component-test's.version='0.1.0's.summary='组件的简介'# This description is used to generate tags and improve search results.# * Think: What does it do? Why did you write it? What is the focus?# * Try to keep it short, snappy and to the point.# * Write the description between the DESC delimiters below.# * Finally, don't worry about the indent, CocoaPods strips it!s.description=<<-DESC 组件的详细描述 DESC# s.homepage 作者主页地址 s.homepage = 'https://gitee.com/taijuios' # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' #license 开源协议 s.license = { :type => 'MIT', :file => 'LICENSE' } # author 作者信息 s.author = { 'wangtaiju' => 'wang.taiju@iwhalecloud.com' } # source 组件地址,需要组件的git远程仓库地址一致 s.source = { :git => 'git@gitee.com:taijuios/component-test.git', :tag => s.version.to_s } # s.social_media_url = 'https://twitter.com/' # ios.deployment_target 平台和运行最低系统 s.ios.deployment_target = '10.0' # source_files 组件源代码路径 s.source_files = 'component-test/Classes/**/*' # resource_bundles 组件所需资源路径,如图片 # s.resource_bundles = { # 'component-test' => ['component-test/Assets/*.png'] # } # public_header_files 对外公开的头文件 s.public_header_files = 'Pod/Classes/IWComponent.h' # s.frameworks = 'UIKit', 'MapKit' # dependency 依赖的第三方库 # s.dependency 'AFNetworking', '~> 2.3'end
具体语法参考pod官方:https://guides.cocoapods.org/syntax/podspec.html
5.验证podspec文件
编译通过后,终端cd到组件应用根目录, 提交代码到远程仓库,并打tag
git add . git commit -m"description"git push origin master git tag 版本号 (注:这里的版本号必须和 podspec 里写的版本号一致) git push --tags
执行一下命令:
pod spec lint --verbose --allow-warnings --use-libraries
备注:如果远程仓库和podspec文件中的source地址不一致会报错,远程仓库先打tag,tag需要和podspec文件version一致,否则也会报错不通过。
编译常用的一些命令如下:可以根据需求来选择
--use-libraries 开启库编译
--allow-warnings 允许告警
--sources=3rdlib 第三方依赖
--skip-import-validation 跳过验证
--skip-tests 跳过测试
--verbose 输出日志,
终端显示:component-test.podspec passed validation. 表示成功。
6.提交podspec文件索引
- 添加pod repo
pod repo add 'repo名称' 远程仓库地址
pod repo add gitee git@gitee.com:taijuios/component-test.git
- 验证并提交podspec到远程仓库
pod repo push gitee component-test.podspec --verbose --allow-warnings --use-libraries
- 备注:pod repo 都远程仓库和podspec文件source需要一致。
完成后可以在本地cocoapods中看到版本索引了
7.测试
- 新建一个pod管理应用工程
- Podfile指定组件源和tag
pod'component-test', :git=>'git@gitee.com:taijuios/component-test.git', :tag=>'0.1.0'
- pod install,并正常使用则成功。