前言
知乎 iOS 客戶端從一開始圍繞問答社區到目前涵蓋 Feed,會員,商業,文章,想法等多個業務線的綜合內容生產與消費平臺。項目的複雜程度已經在超級 App 的範疇。單週發佈與業務並行開發也逐漸變成主流。同時在知乎 iOS 平臺,技術選型一直也都比較開(sui)放(yi)。較早了引入了 Swift 進行業務開發,列表引入了需要 OC++ 的 ComponentKit 作爲核心引擎。所以在這種多業務方團隊,技術形態複雜,組件倉庫數量多等場景下,也同樣遇到了各種超級 App 團隊都面臨的一些問題。
問題如下:
- 如何統一開發環境
- 提高編譯速度
- 提高打包速度
- 二進制組件調試
- 多組件聯合調試
- 多組件聯合打包
- 約束組件依賴關係等
當然在思考解決上面這些問題前,知乎 iOS 項目也同樣經歷過組件化的工作。與衆多組件化拆分方案殊途同歸,進行了業務劃分,主倉庫代碼清空,業務線及 SDK 進行獨立倉庫管理。引入基於路由,基於協議聲明的組件間通信等機制等,這裏就不多贅述了。
簡介
核心介紹的項目名稱爲 Venom,靈感來源於電影《毒液》。Venom 的用戶端是一款爲開發人員打造 Mac App,應用內置了工程構建需要的全套 Ruby Gem 和 Cocoapods 等其相關構建環境。核心目標是解決工程構建,二進制構建,組件管理,調試工具等一系列開發過程中的繁瑣耗時任務。
所以當一臺全新的 Mac 電腦希望運行工程時, 只需要 3 步:
- 安裝 Venom For Mac 客戶端。
- 使用 Venom 打開工程點擊 Make 按鈕。
- 構建完成點擊 XCode 按鈕打開工程。(當然默認己裝 XCode )
從此告別 ruby,cocoapods 版本不對,gem 問題,bundle 問題以及權限問題等困擾。因爲構建環境內置,使得構建環境與工程師本地環境隔離,極大的降低了工程 setup 的成本。
完整的 Venom 包含了 3 個部分:
- Venom App
- Venom 內核
- Venom Server
下面會着重介紹客戶端和內核相關的技術方案,數據服務目前僅爲組件的附加信息提供 API 支持。
Venom 內核介紹
在引入 Venom 前,一直使用 Cocoapods 的 Podfile 進行組件的引用。但如果希望對 pod 命令的 DSL 進行擴展,發現是不夠方便的。索性在 Cocoapods 上層建立自己的組件描述文件,每一個描述文件最終都會被轉化爲一次 podfile 的 pod 調用。
如上圖,使用 Venom 方式集成的項目,由在 VenomFiles 目錄內的組建描述文件組成。
組件描述文件
VenomFile.new do |v|
v.name = 'XXModuleA'
v.git = '[email protected]: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 網絡和日誌查看等
本文轉載自知乎技術專欄。
原文鏈接: