你在使用哪种编程语言?快来投票,亲手选出你心目中的编程语言之王 了解详情
写点什么

知乎 iOS 客户端工程化工具 Venom

2019 年 6 月 25 日

知乎 iOS 客户端工程化工具 Venom

前言

知乎 iOS 客户端从一开始围绕问答社区到目前涵盖 Feed,会员,商业,文章,想法等多个业务线的综合内容生产与消费平台。项目的复杂程度已经在超级 App 的范畴。单周发布与业务并行开发也逐渐变成主流。同时在知乎 iOS 平台,技术选型一直也都比较开(sui)放(yi)。较早了引入了 Swift 进行业务开发,列表引入了需要 OC++ 的 ComponentKit 作为核心引擎。所以在这种多业务方团队,技术形态复杂,组件仓库数量多等场景下,也同样遇到了各种超级 App 团队都面临的一些问题。


问题如下:


  • 如何统一开发环境

  • 提高编译速度

  • 提高打包速度

  • 二进制组件调试

  • 多组件联合调试

  • 多组件联合打包

  • 约束组件依赖关系等


当然在思考解决上面这些问题前,知乎 iOS 项目也同样经历过组件化的工作。与众多组件化拆分方案殊途同归,进行了业务划分,主仓库代码清空,业务线及 SDK 进行独立仓库管理。引入基于路由,基于协议声明的组件间通信等机制等,这里就不多赘述了。


简介

核心介绍的项目名称为 Venom,灵感来源于电影《毒液》。Venom 的用户端是一款为开发人员打造 Mac App,应用内置了工程构建需要的全套 Ruby Gem 和 Cocoapods 等其相关构建环境。核心目标是解决工程构建,二进制构建,组件管理,调试工具等一系列开发过程中的繁琐耗时任务。



所以当一台全新的 Mac 电脑希望运行工程时, 只需要 3 步:


  1. 安装 Venom For Mac 客户端。

  2. 使用 Venom 打开工程点击 Make 按钮。

  3. 构建完成点击 XCode 按钮打开工程。(当然默认己装 XCode )


从此告别 ruby,cocoapods 版本不对,gem 问题,bundle 问题以及权限问题等困扰。因为构建环境内置,使得构建环境与工程师本地环境隔离,极大的降低了工程 setup 的成本。


完整的 Venom 包含了 3 个部分:


  1. Venom App

  2. Venom 内核

  3. Venom Server



下面会着重介绍客户端和内核相关的技术方案,数据服务目前仅为组件的附加信息提供 API 支持。


Venom 内核介绍

在引入 Venom 前,一直使用 Cocoapods 的 Podfile 进行组件的引用。但如果希望对 pod 命令的 DSL 进行扩展,发现是不够方便的。索性在 Cocoapods 上层建立自己的组件描述文件,每一个描述文件最终都会被转化为一次 podfile 的 pod 调用。



如上图,使用 Venom 方式集成的项目,由在 VenomFiles 目录内的组建描述文件组成。


组件描述文件

VenomFile.new do |v|  v.name = 'XXModuleA'  v.git = 'git@git.abc.abc.com:Team-iOS-Module/XXModule.git'  v.tag = '1.0.0'  v.binary = false  v.use_module_map = true  v.XX...end
复制代码


组件描述文件可以理解是 pod 命令的一个超集,在包含了 pod 的原有功能基础上,扩展其他功能(胶水代码创建,二进制化与源码切换等)。


组件调试

同时在与 VenomFile 同级别还设计了一个 Customization.yml 的文件。当开发过程中,需要对某个组件进行源码二进制的切换,或者源码路径的切换,版本引用的切换等,不会直接改动 VenomFile,会改动 Customization.yml 来进行。在构建过程中的优先,Customization.yml > Venomfile 。为了每个工程师的改动不会互相影响,Customization.yml 是非 git 托管的。而 VenomFiles 内的文件只有更新版本号或其他配置改动,才会更新。


构建过程

所有组件都通过一个个 Venomfile 文件方式管理在主工程仓库中,通过目录对组件进行层级划分管理。



原来的 Podfile 文件通过嵌入 Venom 进行构建职责的接管。



使用 Venom 后 pod install 的实际过程就如下图:



整体上来看, Venom 内核提供了一套扩展 pod 属性的描述文件,开发阶段通过 customization.yml 进行可配置的构建。构建过程中,依赖 Venomfile 文件的唯一标识进行二进制库和源码的关联。通过对 Cocoapods 构建过程的 hook 实现二进制与源码的引用切换。二进制化方案可参考 :


Xinyu Zhao:知乎 iOS 基于 CocoaPods 实现的二进制化方案​


命令接口

Venom 内核除了主要的构建职责,还提供了一系列的 ipc 命令。通过这些 ipc 命令,上层的 Venom 客户端就可以更容易的操作每个组件,进行定制化的开发组织。来构建工程。


例如:


// 修改组件二进制使用方式,使用二进制venom ipc customization \    --path /Users/abc/Developer/zhihu/abc/def \    --edit \    --name ZHModuleABC \    --binary// 修改组件二进制使用方式,使用源码venom ipc customization \    --path /Users/abc/Developer/zhihu/abc/def \    --edit \    --name ZHModuleABC \    --source// 修改 yml 文件中指定组件的路径venom ipc customization \    --path /Users/abc/Developer/zhihu/abc/def \    --edit \    --name ZHModuleABC \    --pod_path /path/to/ZHModuleABC// reset 某个组件在 customization 中的 change,不指定 name 参数会给整个文件置成空venom ipc customization \    --path /xxx \    --reset \    --name ZHModuleABC
复制代码


Venom App 介绍

通过对 Venom 内核的简单介绍,其实可以认为,只通过命令行版的工具,就可以达到用到的大部分功能。但因为实际开发情况一般不会一个人一次只处理一个模块,所以希望以一种所见即所得方式来让业务工程师不用关心下层的逻辑,学习命令。可以快速建立起开发环境是我们的主要目标。



客户端主要模块


Venom App 内置了全套的 guby gem 环境来运行命令。通过 CLITask 来访问 Venom-core 以及 git 等其他命令(venom 内核一样内置在 Venom App 内)。



这样很好的控制了执行命令的环境,特别是对新入职的员工是十分友好的。


核心功能

开发组件关联

正常情况下 clone 下来的主工程(壳工程)内是没有代码的,只有空的工程文件和组件描述文件。Venom 工具划分了 2 个区域,普通组件和定制组件。



因为每个开发者维护的组件其实是有限的几个,一般都会将源码放在固定目录,所以通过设置客户端的自动扫描路径。在 Venom 界面上,如果在扫码路径下发现了相关组件,则可以一键关联本地目录组件,这样组件会切换到定制组件的模式进行开发。


特定版本关联


在开发过程中,有时需要对某一个依赖库的特定版本进行调试或连调。所以也支持通过 tag,commit,branch 等方式,进行特定源码的切换和关联。


源码与二进制切换


某些特殊场景下,可能希望工程以所有组件都是源代码方式构建,排查问题。那么也可以通过 2 种不同的构建模式一键切换。(当然全源码构建一次需要十足的耐心)


二进制模式下搜索与调试

二进制化后,大部分情况下都工作在二进制模式下,但有时在进行源码搜索时,希望可以全局搜索。所以在构建过程中,会把当前版本的源码目录也引用到工程目录下。



所以在工程进行检索代码时,是完全没问题的。有了源码,在云端进行二进制打包时,通过 fdebug-prefix-map ( Clang command line argument reference )这个参数重新在二进制文件中改写 Debug 模式的源代码路径。这样即使在二进制模式下,也可以直接关联源码进行断点调试。


组件依赖关系分析

当组件很多后,就会出现一些工程师对组件所处层级不够了解,导致出现依赖混乱的问题。所以在构建结束后会通过对组件层级的检查,进行组件依赖层级的判断。



总结

在推进所有工程师使用 Venom 客户端后,相当于在开发环节有了一个强有力的抓手。由于 App 的自动更新功能,可以在平台下提供给开发者更多的工具,而开发者只需要更新客户端使用。通过工具化客户端的开发,我们重构了原有散落在各处的脚步,工具集中整合在一起。使得开发工具维护更统一,更新也更及时,开发人员上手成本也更低。


Venom 核心承担的是开发环境管理,工程组织与构建管理,提高工程效率工作。但上线后,我们还陆续在此基础上提供了一些其他功能。


  • 多仓库 MR 自动填充提交

  • 本地非独立业务仓库单元测试

  • 个人开发者账号真机调试

  • 无用图片扫描工具

  • 轻量的 app 网络和日志查看等


本文转载自知乎技术专栏


原文链接


https://zhuanlan.zhihu.com/p/69526642


2019 年 6 月 25 日 08:0019428

评论

发布
暂无评论
发现更多内容

阿里内部首发1000页涨薪面试宝典:Spring+SpringMVC+MyBatis框架整合开发实战

Java架构追梦

Java 源码 架构 面试 SSM框架

真香!天天996进不去阿里?看5年苦逼程序猿怎么逆袭阿里P7

小Q

Java 学习 架构 面试 程序猿

分析和解决JAVA 内存泄露的实战例子

AI乔治

Java 架构 JVM 内存泄露

直播带货大战在即:账号交易灰产猖獗

石头IT视角

第6周学习总结

饭桶

如何获取变量token的值

测试人生路

软件测试 接口测试

解惑“高深”的Kafka时间轮原理,原来也就这么回事!

华为云开发者社区

中间件 消息队列

极客大学 - 架构师训练营 第六周作业

9527

数字货币交易所系统开发解决方案,撮合交易平台搭建

WX13823153201

数字货币交易所系统开发

架构师训练营第二周课后作业

天涯若海

极客大学架构师训练营

Netty源码解析 -- 零拷贝机制与ByteBuf

binecy

Netty 源码剖析

天呐!价值2980元Java成神面试题竟在Github开源了

996小迁

Java 学习 架构 面试

小白学算法:买卖股票的最佳时机!

王磊

Java 算法

数字“异化”生存

脑极体

技术实践丨PostgreSQL开启Huge Page场景分析

华为云开发者社区

数据库 管理 内存

码农会锁,synchronized 对象头结构(mark-word、Klass Pointer)、指针压缩、锁竞争,源码解毒、深度分析!

小傅哥

小傅哥 虚拟机 synchronized mark-word Klass Pointer

深度对比Apache CarbonData、Hudi和Open Delta三大开源数据湖方案

华为云开发者社区

hadoop 开源 数据处理

当 TiDB 与 Flink 相结合:高效、易用的实时数仓

Apache Flink

flink #TiDB

gRPC服务注册发现及负载均衡的实现方案与源码解析

网管

go 负载均衡 gRPC etcd 服务注册与发现

频繁操作本地缓存导致YGC耗时过长

AI乔治

Java 架构 JVM GC

第6周作业

饭桶

为产业AI去障:联想的边缘突破

脑极体

ConcurrentHashMap核心原理,彻底给整明白了

AI乔治

Java 架构 分布式 线程

零基础IM开发入门(三):什么是IM系统的可靠性?

JackJiang

网络编程 即时通讯 IM

狼人杀背后的秘密,实时语音你不知道的那些事

anyRTC开发者

音视频 WebRTC 语音 RTC 安卓

企业级RPC框架zRPC

万俊峰Kevin

go RPC microser

在阿里内部,做Java到金字塔顶端的人平时都如何学习源码?

小Q

Java 学习 架构 面试 程序猿

Vidyo独特的互联网适应性

dwqcmo

音视频 集成架构 解决方案 智能硬件

DeFi流动性挖矿系统开发技术方案

薇電13242772558

区块链 defi

极客大学 - 架构师训练营 第六周

9527

web worker的介绍和使用

程序那些事

多线程 Web Worker 异步模型 异步编程 web技术

云原生场景下企业API 网关选型及落地实践

云原生场景下企业API 网关选型及落地实践

知乎 iOS 客户端工程化工具 Venom-InfoQ