前言
随着公司业务的不断发展,团队不断壮大的同时,项目也随之臃肿起来,如何保障团队协作的高效,自然的想到了组件化这个话题。下面总结下本人的梳理和思考。
组件化
- 为什么我们需要组件化
项目模块间的解耦、模块实现可重用、提升团队成员之间团队之间的协作开发效率、更方便单元测试。
- 并不是所有的项目都适合组件化
如果你的项目较小,模块之间交互简单,耦合很少;模块没有被外部模块引用,只是一个单独的小模块;模块不需要重用,代码也很少被修改;团队规模很小。那么,你对项目就没有必要做组件化。
如果你的项目有以下三个特征以上,就要考虑下进行组件化了:
- 模块逻辑复杂,多个模块之间频繁互相引用;
- 项目规模逐渐变大,修改代码变的越来越困难(这里可以理解为:修改一处代码,需要同时修改其他多个地方);
- 团队人数变多,提交的代码经常和其他成员冲突;
- 项目编译耗时较长;
- 模块的单元测试经常由于其他模块的修改而失败。
- 组件化的8条指标
一个项目经过组件化后如何来评判项目组件化是否彻底或者说是否优秀,可以通过以下几个方面:
- 模块之间没有耦合,模块内部的修改不影响其他模块;
- 模块可以单独编译;
- 模块间数据传递明确;
- 模块可以随时被另一个提供了相同功能的模块替换;
- 模块对外接口清晰且易维护;
- 当模块接口改变时,此模块的外部代码能够被高效重构;
- 尽量用最少的修改和代码,让现有的项目实现模块化;
- 支持OC和Swift,以及混编。
前4条主要用于衡量一个模块是否真正解耦,后4条主要用于衡量在项目实践中的易用程度。
组件化分层
一般一个项目主要分为三层:业务层、通用层、基础层
组件化封层之后,需要遵循一下原则:
- 只能上层对下层依赖, 不能下层对上层依赖(下层是对上层的抽象);
- 项目公共代码资源下沉;
- 横向的依赖尽量少有,最好下称到通用模块或者基础模块。
组件化方案
目前常用的组件化方案主要有两种:
- 本地组件化:主要是通过在 工程中创建 library, 利用 cocoapods 的 workspec 进行 本地管理, 不需要将项目上传git,而是直接在项目中以 framework 的方式 进行调用。
- cocoapods组件化:主要是利用 cocoapods 来进行 模块的远程管理,需要将项目上传 git (这里的组件化模块分为 公有库 和 私有库 , 对公司而言, 一般是私有库)
本地组件化
创建主工程
- 新建项目主工程
- 集成 cocoapods , 进行本地管理,执行命令 pod init
- 编辑 Podfile, 并执行 pod install
创建组件
可以创建 自己的模块:
- 主工程:主要实现表层业务代码
- Base:基类封装
- Tools:工具(字符串,颜色,字体等)
- Service:服务层,封装业务工具类,例如网络层服务、持久化服务等
- Pods:第三方依赖
其中,各个模块间的关系如下所示:
cocoapods组件化
下面我们开始组件化的一些概念学习:远程索引库、本地索引库、远程代码库、本地代码库;我们逐一进行介绍。
远程索引库
概念:每创建一个组件都会带一个 xxx.podspec 的索引文件。专门用来存放这些索引文件的库就叫做索引库。我们需要将这些索引文件上传到远程索引库才能保证其他的同事能够拿来用。
我们接下来就创建远程索引库:登录GitHub
本地索引库
与远程索引库对应,本地索引库用来存放本地索引文件的库。
创建本地索引库:
- 打开终端,通过命令 pod repo 查看你本地已经有哪些本地索引库(这里我已经添加了 WJHSpecs 所以可以看到有)
- 通过 pod repo add 本地索引库的名字 远程索引库的地址 命令 创建本地索引库并和远程索引库做关联(注:本地索引库的名字建议和远程索引库起的名字一样)
- 在Finder中如下路径已经可以看到创建成功。
远程代码库
用来存放准备组件化的代码,创建方式和创建远程索引库方式一样。这里我们把 自己整理的 相关代码组件化,我们创建一个 WJHBaseWidgets 的远程代码库。
- 如下图:
本地代码库
我们在这里 创建 WJHBaseWidgets 本地代码库
pod lib creat 组件名
注意这里创建本地代码库是可以选择路径的,也就是说你想创建在哪里(cd 到路径就可以),后面会用到路径。
pod lib create WJHBaseWidgets
- 之后会创建一个工程,目录如下
注意这个工程就在你创建代码库路径下
- 编译成功之后,把我们 自己整理的 组件化相关的代码 拖入到本地代码库下面路径
添加组件化代码到 Classes 文件夹
- Classes 中的文件修改后,我们cd到Example下进行 pod install (刚才添加到 Classes 中的文件夹 pod 进来)
修改 podspec 文件
- 编译组件不报错的话,开始修改 podspec 文件:
- 一般修改一下几个内容:
- 修改版本号
- 修改项目的简单概述和详细概述
- 修改 homepage 和 source 地址
- 添加依赖库
编译通过之后,提交组件到远程代码库并打tag
- git add .
- git commit -m "description"
- git remote add origin 远程代码仓库地址
- git push origin master
- git tag 版本号 (注:这里的版本号必须和 podspec 里写的版本号一致)
- git push --tags
验证podspec索引文件
通过 pod spec lint --verbose --allow-warnings --use-libraries 命令验证 podspec 索引文件
提交索引文件到远程索引库
验证通过之后, pod repo push 本地索引库 索引文件名 --verbose --allow-warnings --use-libraries 提交索引文件到远程索引库。
pod repo push WJHSpecs WJHBaseWidgets.podspec --verbose --allow-warnings --use-libraries
在 Finder 中可以查看是否成功
使用组件化代码
使用的话和通过 cocoapods 引入第三方一样, 在需要引入改组件的工程里修改 Podfile。
Podfile文件修改如下:
pod install 后, 项目中就把 WJHBaseWidgets 组件 pod 到项目中了。
报错解决
ERROR | xcodebuild: *** /BaseModel.h:13:9: error: include of non-modular header insideframeworkmodule'wLib.BaseModel'[-Werror,-Wnon-modular-include-in-framework-module]
出现场景:pod验证podspec文件的时候,如果.h文件里面有引用第三方pod,会出现这个错误
解决方式:在命令后面添加 --use-libraries 就可以了 (本篇文章中的校验和提交均以添加)