Flutter混合工程改造實踐

做者:閒魚技術-字平前端

背景

閒魚技術團隊於2018年上半年率先引入了Flutter技術嘗試實現客戶端開發的統一,併成功改造和上線了複雜的商品詳情業務。這一過程當中,因爲原有的iOS和安卓工程都已至關龐大,如何將Flutter無縫橋接到這些大工程並保證開發效率不受影響成爲優先要解決的問題。
本文針對項目實踐人員給出了一種通用的工程改造方案,但願爲準備轉型Flutter的團隊提供參考。android

問題

Flutter的工程結構比較特殊,由Flutter目錄再分別包含Native工程的目錄(即ios和android兩個目錄)組成。默認狀況下,引入了Flutter的Native工程沒法脫離父目錄進行獨立構建和運行,由於它會反向依賴於Flutter相關的庫和資源。 ios

典型的Flutter目錄結構git

很顯然,在擁有了Native工程的狀況下,開發者不太可能去建立一個全新的Flutter工程重寫整個產品,所以Flutter工程將包含已有的Native工程,這樣就帶來了一系列問題:
__1).構建打包問題:__引入Flutter後,Native工程因對其有了依賴和耦合,從而沒法獨立編譯構建。在Flutter環境下,工程的構建是從Flutter的構建命令開始,執行過程當中包含了Native工程的構建,開發者要配置完整的Flutter運行環境才能走通整個流程;
__2).混合編譯帶來的開發效率的下降:__在轉型Flutter的過程當中必然有許多業務仍使用Native進行開發,工程結構的改動會使開發沒法在純Native環境下進行,而適配到Flutter工程結構對純Native開發來講又會形成沒必要要的構建步驟,形成開發效率的下降。app

目標

針對以上問題,咱們提出瞭如下的改造目標,力求最小化Native工程對Flutter相關文件的依賴,使得:
1).Native工程能夠獨立地編譯構建和調試執行,進而最大限度地減小對相關開發同窗的干擾並使打包平臺再也不依賴Flutter環境及相關流程;
2).Native工程處在Flutter環境中時(即做爲ios或android子目錄)可以正確依賴相關庫和文件,正常執行各種Flutter功能,如dart代碼的構建,調試,hot reload等,保證Flutter環境下開發的正確性。機器學習

方案的制定

兩種模式

首先定義Native工程處於獨立目錄環境下稱爲Standalone模式,處於Flutter目錄下稱爲Flutter模式。目標中純Native開發或平臺打包就處於Standalone模式,Flutter對開發人員和打包平臺來講是透明的存在,不會影響構建與調試;而Flutter的代碼則在Flutter模式進行開發,其相關庫的生成,編譯和調試都走Flutter定義的流程。 工具

兩種模式學習

理清依賴

從上面的定義來看,改造的核心就是把Standalone模式提取出來,那麼就要理清Standalone模式對Flutter的依賴,並將其提取成第三方的庫,資源或源碼文件。以iOS爲例,經過閱讀Flutter構建的源碼,可知Xcode工程對Flutter有以下依賴:
1).App.framework:dart業務源碼相關文件
2).Flutter.framework:Flutter引擎庫文件
3).pubs插件目錄及用於索引的文件:Flutter下的插件,包括各類系統的和自定義的channels
4).flutter_assets:Flutter依賴的靜態資源,如字體,圖片等測試

依賴引入的策略

改造過程當中閒魚嘗試過兩種依賴引入策略,如下分別進行闡述。
1).本地依賴: 經過修改Flutter構建流程將其庫文件,源碼和資源直接放置到Native工程的子目錄中進行引用,以iOS爲例,就是將Flutter.framework及相關插件等作成本地的pod依賴,資源也複製到本地進行維護。 由此,Standalone模式便具有了獨立構建和執行的能力,對於純Native開發人員來講Flutter只是一些二方庫與資源的合集,無需關注。 而在Flutter模式下,dart源碼的構建流程不變,不影響編譯和調試;同時因爲是本地依賴,Flutter模式下的各類改動也實時能夠同步到Native工程的子目錄中,提交修改後Standalone模式也就擁有了最新的Flutter相關功能。
__優勢:__Flutter相關內容的改動同步到Standalone模式也比較方便;
__缺點:__須要對Flutter原有的構造流程進行稍嫌複雜的改動,而且與後續的Flutter代碼合併會有衝突,且Native工程與Flutter的內容仍是耦合在本地不夠獨立。
2).遠程依賴: 遠程依賴的想法是將Flutter全部依賴內容都放在獨立的遠端倉庫中,在Standalone模式下引用遠程倉庫中的相關資源,源碼和庫文件,Flutter模式下的構建流程和引用方式則不變。
__優勢:__對Flutter自身的構建流程改動較少而且較完全第解決了本地耦合的問題;
__缺點:__同步的流程變得更繁瑣,Flutter內容的變更須要先同步到遠程倉庫再同步到Standalone模式方能生效。 PS. 閒魚最終選擇了這個策略。 字體

遠程依賴

改造的實現

目錄的組織

Flutter模式下父工程目錄下的ios和android的子目錄分別包含對應的Native工程,代碼管理上子工程可使用git的submodule形式,保證目錄間的獨立。

遠程依賴的實現

在Standalone模式下,Flutter的依賴內容都指向遠程倉庫中的對應文件,而在Flutter模式下依賴的方式不變。
1)向Standalone模式同步Flutter的變動
因爲遠程依賴的問題是同步變更比較麻煩,爲此閒魚開發了一系列腳本工具使該過程儘可能自動完成。 假設Flutter的內容(多是業務源碼,引擎庫或某些資源文件)發生變化,那麼在Flutter模式下構建結束後,腳本會提取生成好的全部依賴文件拷貝到遠程倉庫,提交併打tag,而後依據打出的tag生成新的遠程依賴說明(好比iOS下的podspec),最後在Standalone模式下修改Flutter的依賴至最新的版本,從而完成整個同步過程。

同步流程

2)同步的時機
建議在提測及灰度期間,每次Flutter業務的提交都可以觸發同步腳本的執行和app打包;開發期間保持每日一次的同步便可。

總結

爲解決引入Flutter後的工程適配問題,咱們抽取了Flutter的相關依賴放到遠程供純Native工程進行引用,從而保證了Flutter與純Native開發的相互獨立與並行執行。
該方案已在閒魚施行了幾個版本,並反向輸出給了Flutter團隊,爲其後續的hybrid工程組織計劃提供了方向和參考。同時,相信該方案也能夠爲轉型Flutter的團隊提供幫助,固然項目間的差別也會致使方案的不一樣,所以若有更好的方法和意見也指望多多交流!
最後,閒魚技術團隊廣招各種方向的達人,不管你是精通移動端,前端,後臺,仍是機器學習,音視頻,自動化測試等,都歡迎投遞簡歷加入咱們,一同用技術改善生活!

簡歷投遞:guicai.gxy@alibaba-inc.com

相關文章
相關標籤/搜索