作者:騰訊 - 小德(koudleren 任曉帥)
存在的問題
為了使用Flutter,剛開始的時候為了快速上線,採用將Flutter和Native程式碼混合開發的模式,具體的工程目錄如下:
可以明顯的看到工程目錄很亂,android目錄下有多個程式碼目錄,lib目錄下是dart程式碼,images目錄下是Flutter所用到的圖片等資源,而且竟然還包含了iOS的程式碼。如此混亂的目錄給我們帶來了四個問題:
- 需要對Native工程進行了大量的改造
為了將Flutter整合到Native工程裡,對Flutter和Native的目錄和編譯指令碼都進行了大量的改造,對原來Native的工程影響比較大。
- 不開發Flutter的同學也必須得配置Flutter的SDK
因為Flutter的開發需要Flutter SDK的環境,但是團隊內並不是所有人都做Flutter的開發,如果要求每個人都安裝Flutter SDK的環境,無疑帶來了額外的開發成本。
- 無法做持續整合
因為Flutter編譯需要Flutter的編譯環境,但是現有的持續整合的環境沒有Flutter的環境,使得Flutter無法做到持續整合。
- 本地編譯環境無法統一
因為第三點的原因,Flutter是本地編譯的,可是每個人Flutter SDK的環境很不容易統一,例如SDK版本的差異或者系統的差異,會導致Flutter編譯產物不一致,從而影響現網的表現,出現iOS和Android表現不一致的情況,甚至會因為SDK版本不匹配造成App的crash。
改進開發模式
針對上面的問題,我們轉而採用瞭如下的開發模式:
- Flutter工程和Native工程分開
將Flutter和Native剝離,Flutter是單獨的工程,Native也是單獨的工程,這樣從工程上面就將Flutter和Native徹底分開,兩者互不影響,Native工程不在需要改造,單獨開啟Native工程也不需要配置Flutter SDK的環境。在Flutter工程裡編譯Flutter的產物,然後整合到Native工程裡。
- 本地開發,服務端構建
在本地開發Flutter,但是將編譯構建的工作交給服務端來做,因為服務端的Flutter SDK的環境是唯一的而且可控的,這樣不管有幾個開發者,本地環境有多複雜,Flutter的構建都在服務端,保證了Flutter構建產物的一致性。
- Flutter構建產物自動同步
在服務端觸發Flutter的編譯,如果編譯成功,會自動將最新的Flutter產物同步到Native工程裡,保證Native的工程裡的Flutter產物是穩定的而且是最新的,可以及時看到最新的更改的Flutter頁面。
這裡持續整合服務是用QCI搭建的。
改進後的效果
經過以上的改造,工程目錄如下:
可以明顯看到工程目錄清晰了很多,fluttersdk目錄下是Flutter的構建產物,對於原來的Native工程來說就是一個module,flutternew目錄下是Flutter的業務程式碼,flutternew依賴fluttersdk,flutternew也是Native工程的一個module。經過改造,可以達到如下的效果:
- 實現Flutter對原來Native工程的非侵入式整合
Flutter只是Native工程的一個module,和其他Native的module是平級的,Naitvie也不需要關心Flutter model的環境,對原來的Native工程沒有影響。
- 保證Flutter編譯環境的唯一性
因為Flutter的編譯都是在服務端進行的,這樣就保證了Flutter編譯環境的唯一性,iOS和Android都是在同一份程式碼同一個編譯環境下構建的,也就保證了Flutter產物的穩定性。
- 實現了Flutter的持續整合
Flutter的程式碼提交之後,會自動觸發Flutter的構建,可以很容易知道此次的變更是否有問題,最新的Flutter構建產物也會自動同步到Native的工程裡。
結語
經過改進Flutter的開發模式,目前已經實現了對Flutter的敏捷開發和持續整合,實現了多團隊協作遠端構建產出的模式。