科技改變生活 · 科技引領未來
一前言Flutter一碼多端的特性,解放了端上同學的人力,帶來了研發效率的提升,淘特技術團隊因為早期雙端研發同學數量不匹配以及對研發效率的訴求,也是阿里集團內部比較早在業務上落地Flutter的團隊之一。雖然有了一碼多端的便利,但是伴隨而來
一 前言
Flutter 一碼多端的特性,解放了端上同學的人力,帶來了研發效率的提升,淘特技術團隊因為早期雙端研發同學數量不匹配以及對研發效率的訴求,也是阿里集團內部比較早在業務上落地 Flutter 的團隊之一。
雖然有了一碼多端的便利,但是伴隨而來的還有研發鏈路中的各種問題,例如研發環境搭建,雙端工程環境,集成發布流程繁瑣等等。為了深入了解開發同學們的痛點,我們在團隊內部發起了一份問卷調查。
我們針對研發幸福感指數以及研發鏈路中遇到的各種問題進行了調查。結果如下:
在研發幸福感指數的打分中平均得分是 3.38(5分制)。我們針對影響研發幸福感的問題進行了分析,篩選出了一些大家普遍認為影響研發效率的問題。其中排名最高的是研發環境+工程環境(Flutter相關)的搭建,開發調試(Flutter相關)等問題。
接下來我們就來看看這些問題的具體痛點,以及解決這些問題的時候面臨的一些挑戰。
二 問題與挑戰
1 問題
在影響研發幸福感的問題中,主要是以下三個方面的問題比較突出。
1)研發環境問題
研發環境配置是編碼的前置工作,它也會影響新人落地對團隊研發體驗的第一印象。由于 Flutter 涉及 Android 與 iOS 雙端的環境配置,導致不熟悉另一個端的同學配置起來,十分麻煩,上手難度高。另外,Flutter 本地版本不一致,缺乏 Flutter 版本管理工具,文檔零散更新不及時,這些都極大的耗費了團隊同學的精力。
2)工程環境問題
解決了研發環境問題,還需要解決工程環境問題,雙端工程架構復雜,不熟悉某個端的同學面對編譯問題難以解決。甚至很多同學就直接放棄了配置另外一個端的工程,平時開發只對著自己熟悉的端調試,違背了 Flutter 雙端開發的理念。
點評:從團隊的調研采訪來看,一個新人同學搭建 Flutter 的研發環境和工程環境,先需要一天時間搭建好基礎環境,后面的兩三天時間折騰各種編譯問題,特別是 iOS 的相關環境對于 Android 同學來說想要完整跑起來十分費力。
3)集成流程問題
等到代碼開發測試完成以后,集成步驟多,平臺間來回切換,集成流程割裂,沒有形成完整的 SOP。整個集成流程既費時費力,又容易引發質量問題。
點評:現有的 Flutter 模塊集成流程分為六步:1 模塊分支代碼合并 -> 2 模塊生成新Tag版本 -> 3 主工程修改模塊版本號 -> 4 主工程代碼合并 -> 5 主工程生成版本號 -> 6 摩天輪提交正式包打包,步驟繁瑣,需要在 Aone、MTL 等平臺來回切換,而且手工操作各種版本號,很容易引發線上質量問題。
2 挑戰
為了解決這些問題,之前也有沉淀一些文檔和腳本,但是文檔有很多步驟、命令,弄錯任何一個就可能導致環境搭建出錯,另外文檔有時候也沒有及時更新。
我們想如果能有一個桌面端 GUI 形式的研發工作臺,研發同學日常研發遇到的各種問題都可以在這上面解決,新來的同學也可以借助這個研發工作臺快速落地,那對研發的幸福感將是一個質的提升。
于是我們便決定打造一款桌面端的研發工作臺,在實現這個目標的過程中我們也遇到了很多挑戰。
1)如何降低開發同學的接入和使用成本
2)如何保障架構設計的合理性
我們想把研發工作臺打造成一個人人都可以參與進來共建的開放平臺,因為個人的時間是有限的,工作臺本身作為一個工具集的聚合,需要更多的同學參與進來,更多的 idea 落地,所以如何做好倉庫權限控制以及設計一個好的插件化框架就顯得很重要。
3)新技術的落地,相關問題需要自己探索解決。
在桌面端研發工作臺的開發中,我們使用的是 Flutter Desktop 技術(至于原因,技術調研部分會講),國內目前 Flutter Desktop 技術在生產環境落地的并不多,相關經驗還比較缺乏,遇到一些問題的時候,需要自己去探索解決。
接下來我們就來看一看我們為了解決這些問題,在 iBox 上設計了哪些核心的功能,以及這些功能是如何解決這些問題的。
三 技術全景
1 技術調研
業界的客戶端研發工作臺的發展現狀。如下所示:
整體上看是一個客戶端研發工作臺落地的契機,業界有團隊在嘗試,淘特在 Flutter 研發鏈路也有痛點和需求。既然要進行桌面端開發,選擇一個桌面端開發框架就成了首先要考慮的事情,當下比較流行的桌面端開發框架主要有以下兩種:
通常我們在做技術選型的時候會從問題解決,團隊現狀,技術領域,業務趨勢等幾個方面層層遞進去思考。
基于以上思考,我們最終選擇了 Flutter Desktop。有了開發框架,我們接著來看看 iBox 的架構設計。
2 功能設計
iBox 的核心定位
iBox 是一款基于 Flutter Desktop 技術棧研發的一站式、多樣化、可定制的研發工作臺。提供從研發環境到集成發布全流程的研發支持。核心功能包含工作臺、研發環境、工程管理、引擎管理、社區生態、變更單管理與工具箱等。
iBox 在功能設計上分為工作臺、研發、發布、工具箱四大板塊。其中研發、發布、工具箱又各自包含了很多子模塊功能。
我們著重介紹一下工作臺、研發環境與工程管理、社區生態、變更單管理等核心功能,讓大家對 iBox 的整體功能有一個基本認識。
工作臺
提供了最近變更單,常用平臺快捷入口等功能,讓常用功能一鍵直達。另外工作臺還預留了技術展示 Banner 位的功能,可以展示一些團隊內外的優秀技術產出。后續還考慮將值班提醒,集成提醒,發布提醒做在工作臺上。
研發環境與工程管理
研發環境 + 工程管理 解決的是如何快速進入本地開發的問題,如果是新人進入團隊開發,從拿到電腦到進入開發,一般需要經歷研發環境配置和工程環境配置這兩個流程。
在這個過程中需要去各個地方翻閱文檔,按照文檔進行操作,在操作的過程中,還經常伴隨著文檔更新不及時,操作報錯,出了錯誤又得去 Google 或者問身邊的同事,整個過程費時又費力。
而 iBox 的研發環境和工程管理者兩個功能模塊則通過操作一鍵化來解決上述的問題。
首先是研發環境提供了 Flutter、Android、iOS 研發環境的檢查和一鍵配置的功能,讓不熟悉某個端的同學更加便捷的配置自己的研發環境,如下所示:
然后是工程管理提供了混合工程下 Flutter、Android、iOS 等殼工程環境環境檢測,一鍵環境配置等功能,解決了環境配置復雜難以上手的問題,如下所示:
工程環境的復雜性在于它涉及 Flutter、Android、iOS 三個端的編譯,編譯的過程還會因為本地環境的差異而有所不同,各種編譯報錯,使得開發同學窮于應付。iBox 將從環境到工程的各種錯誤類型進行了梳理,并將錯誤信息展示出來,如下所示:
不僅讓開發同學知道自己的工程環境有什么問題,還提供了對工程環境問題的一鍵修復,一鍵修復功能會先刪除緩存(flutter clean,刪除lock文件等),然后按照以下流程重新跑整個工程,確保可以修復工程環境,如下所示:
研發環境和工程管理這兩個功能模塊相互配合,真正解決了開發同學環境配置難的問題,同時它還打破了 Android 與 iOS 之間的門檻,讓不熟悉另外一個端的同學也能進行這個端的調試和打包。
社區生態
集團內外針對 Flutter 都貢獻了不少功能組件,但是并沒有一個統一的地方展示這些組件,導致開發同學在需要用的時候,需要去 pub 庫里各種搜索。
而 iBox 的社區生態功能提供了 Flutter 社區(集團內外)引擎、UI 組件、路由、動態化等各個方面的技術沉淀的展示,特別是 UI 組件,由于 iBox 本身就是基于 Flutter 開發的,那么這些 UI 組件的 Dart 代碼可以直接在 iBox 上運行展示和交互,這種所見即所得的體驗是非常棒的,如下所示:
變更單管理
在以前的開發流程中,Flutter 的研發流程是比較繁瑣的,而且這些流程需要開發自己手工操作,如下所示:
而 iBox 的變更單功能,可以幫助 Flutter 研發同學快捷的完成研發流程的各種操作,如下所示:
這些一鍵式的操作不僅很好的提升了 Flutter 研發的效率,也規范了Flutter 的分支管理、集成方式,避免個人隨意操作帶來的工程問題。
以上便是 iBox 一期規劃和完成的功能,它從根本上解決了上面提到的團隊研發鏈路存在的種種問題,同時也感謝閑魚同學在集成發布這塊為我們提供的飛魚工作臺相關實踐參考。
3 架構設計
iBox 在架構設計上主要關注以下幾個問題:
通過對以上幾個問題的思考,我們對 iBox 采取了縱向分層,橫向模塊化的設計,具體說來:
整體架構大圖如下所示:
從上面的架構圖可以看出輔助功能作為基礎模塊,為其他核心功能提供基礎能力。接下來我們按照從工程到模塊的順序分別講一下具體的設計方案:
工程結構
在整體工程上采用多倉庫設計,之所以使用這樣的設計,是因為 iBox 會涉及跨團隊開發,多倉庫可以讓各個模塊的源碼彼此獨立,不同模塊之間不會相互干擾。
iBox 基于 git-repo 實現了多倉庫的管理,倉庫結構如下所示:
ibox 作為主工程,ibox_common 作為基礎模塊,其他模塊都依賴于 ibox_common。開發 iBox 的同學只需要幾行簡單的命令,就可以同步 iBox 的全部源碼工程。
然后在自己的模塊進行開發和代碼提交即可,彼此之間互不干擾。聊完了整體工程的設計,我們再來看看各個模塊的設計。
模塊設計
每個模塊的核心功能在于處理UI交互與邏輯交互,不同于傳統客戶端的命令式 UI 框架,Flutter 采用的是聲明式 UI 框架,驅動 UI 發生變化的是狀態(State),如下所示:
圖片引用自 Start thinking declaratively
Flutter 里的狀態指的是在 Widget 之間或者內部存儲和傳遞的數據或者信息,它可以分為短時狀態和應用狀態兩種。
所以狀態管理是編寫 UI 和邏輯核心要面對的問題,它也會影響我們組織源碼的方式,在 Flutter 狀態管理的官方文檔中,提供了 14 種狀態管理方案,我們著重討論官方比較推薦的前四種,至于其他的方案,感興趣的可以去查閱官方文檔。
我們先來看原生的兩種狀態管理方式:
setState 在應用場景上比較受限,InheritedWidget 對于開發者來說過于底層,使用起來比較復雜。既然官方的方案都有限制,我們再來看看社區提供的提供的比較推薦的方案。
事實上,Provider 和 Riverpod 的作者都是 Remi Rousselet,Riverpod 這個名字是 Provider 的字母重新排序后得到的,它的推出主要是為了解決 Provider 的一些功能缺陷,如下所示:
基于以上的比較,我們最終選擇了 Riverpod 這一套方案,并由此設計了模塊的源碼結構,如下所示:
iBox 模塊源碼結構 |----------------------------------------------------------- |--- provider 基于 Riverpod 實現的 State 管理方式(官方推薦) |----- xxx.provider.dart provider |--- service 接口請求、數據處理相關實現 |----- xxx.service.dart service |--- ui 頁面與組件 |----- xxx.screen.dart 頁面
一個常見的編寫 UI 邏輯的流程如下所示:
這種方式實現了 UI 與邏輯的解耦和分離,UI 部分可以自由迭代,邏輯部分也實現了復用。
以上便是 iBox 的整體架構設計,相當于是一個簡化版的插件化方案,如何后續有更豐富的插件生態進來,我們會考慮上架一個類似于 VSCode 的插件市場,不過目前對于我們來說,已經夠用了。
插件化的設計使得可以自由組裝各個模塊,不同團隊需要的模塊功能不一樣,我們推出了 app variant(變體)的功能。不同的 app variant(變體)擁有不同的 tab 欄配置,打包的時候就可以針對不團的團隊打出不同功能的包。
4 上線效果
iBox 在研發鏈路核心痛點上使用前后對比
iBox 用戶在使用一段時間以后,也給了不少不錯的反饋。
“一鍵安裝還是非常好用的,幫開發節省了不少時間。以前各個地方下載,安裝配置,還要解決版本沖突的問題,浪費不少時間。”
“這次版本集成全走的iBox, 用著很爽。”
“大幅簡化了 Flutter 環境配置、集成繁瑣等問題。”
此外,iBox 還處在一個剛起步的階段,我們希望把它作為一款產品去迭代和運營。為此我們也為 iBox 設計了不同視角下的運維指標,如下所示:
全局視角:整體數據
用戶視角:不同團隊/個人偏好的功能
業務視角:做的比較好,受歡迎的功能
運維數據體系需要長期建設,它對我們后續的功能迭代和體驗優化有著重要的指導意義,開發同學也是用戶,只憑著拍腦袋想出來的功能,不一定能獲得大家的認可。
四 技術總結
在做 iBox 之前,對于 Flutter 做過一些原理上的探究,之前整理編寫了《從架構到源碼:一文了解Flutter渲染機制》一文,但是沒有好的機會應用在生產實踐上。這次的 iBox 開發之旅讓我收獲頗多,借著這個機會,我們就來聊一聊 Flutter Desktop 技術在生產實踐上的應用。
1 Flutter Desktop 的發展歷程
從2018年2月15日Flutter 團隊發起的 flutter-desktop-embedding 項目到現在,已經四年過去了,中間的過程也是起起伏伏,從最初的不支持生產環境,到如今 Flutter 2.10 發布,正式宣布支持 Windows 平臺生產環境 app 的開發,Flutter Desktop 的發展歷程如下所示:
在 2022 年,Flutter 團隊計劃按照 Windows、Linux、MacOS 的順序逐個推進,將對主流桌面端平臺的支持帶入到 stable channel,最終實現 Flutter "write once, run anywhere" 的愿景。
2 Flutter Desktop 的社區生態
和對 Android 和 iOS 的支持一樣,Flutter 也實現了基于 Windows 等平臺的 Embedder,Embedder 的上層是 C++ Engine 和 Dart framework,它自己負責翻譯和發送 Windows 等平臺的消息。整體架構如下所示:
圖片引用自 Announcing Flutter for Windows
點評:Linux、MacOS 等其他桌面端平臺也是類似的實現結構,更深入的細節可以參見 platform 的實現。
移動端應用和桌面端的應用相比既有相同之處,例如:
這也使得大部分現有的 Flutter 社區組件都可以在桌面端使用,但兩者也有不同之處,例如:
基于這些不同,Flutter 針對桌面端平臺也提供了針對性的支持,如下所示:
在 iBox 的開發過程中,我們也使用了不少原生能力,這里針對 Flutter Desktop 常用的一些社區組件做個總結,如下所示:
現有的社區組件基本能滿足我們的開發需求。
3 Flutter Desktop 的應用場景
iBox 是對 Flutter Desktop 技術的一次有意義的探索,它為我們的產品帶來了更多的可能性,擴展了產品觸達的邊界。
那么,Flutter Desktop 適合哪些應用場景呢?
任何技術都有長短,Flutter Desktop 也有不適合的應用場景,如下所示:
當然技術也是不斷發展的,當前存在的問題,也許在將來就被解決了。筆者對 Flutter Desktop 技術的發展還是很有信心的。
五 結語
Flutter 一份代碼,在兼顧性能的同時上可以多端運行,是它的優勢所在,解放了端上的生產力。尤其是對于 iOS 和 Android 同學比例嚴重失調的團隊來說,這無疑是一個福音。
但是如果不注重 Flutter 開發周邊配套工具的建設,從最開始的環境搭建、開發調試、再到集成發布沒有好的工具去支撐,就很容易就演變成了 “Flutter 從入門到放棄”。這是因為業務團隊和技術團隊的訴求是不一樣的,技術團隊覺得解決 Flutter 各種問題的過程就是一個學習的過程,但是業務團隊業務壓力大,他們的第一訴求是快速開發,快速上線,如果周邊配套工具缺失,他們很有可能就會選擇放棄這個方案,這對于 Flutter 的推廣是十分不利的。
我們希望剛接觸 Flutter 的開發同學,他們的使用體驗是平滑的,能一鍵完成的就一鍵完成,例如我們提出的“一小時完成 Flutter 環境搭建”、“一鍵配置/修復工程環境” 等等,這些理念也與 Flutter 團隊最近發布的年度規劃中的“提升開發者體驗”不謀而合。
今年 2月10號,Flutter 團隊發布了他們 2022 年的年度戰略(Flutter 2022 Strategy)和路線 (Flutter 2022 Roadmap)。如下所示:
可以看到未來一年,Flutter 團隊將開發者體驗提到了非常重要的位置,他們將從 Flutter 的各個層面去改善開發者體驗,例如:
上述提到的一些理念,例如 “讓入門 Flutter 體驗更加平滑,降低入門門檻”,和我們做 iBox 的初衷不謀而合。另外在 iBox 后續的規劃中,我們除了降低開發同學的 Flutter 入門門檻,還希望降低新團隊接入 Flutter 的成本。
現有的 Flutter 接入方案以混合工程方案 add Flutter to existing app 為主,這套官方提供的方案有著不小的接入、重構以及維護的成本,而且這是一個重復踩坑的過程,很多相同的問題會被不同的團隊再次遇到,如果 iBox 可以提供一鍵接入的方案,那么將大大降低 Flutter 的接入和填坑成本,助力 Flutter 的推廣。
Flutter 團隊在年度戰略(Flutter 2022 Strategy)中提到 “以用戶(指 Flutter 開發者)為中心,其他一切都會隨之而來”。
We believe in "focus on the user and all else will follow". This manifests in our emphasis on developer experience. 引用自 Flutter 2022 Strategy
相信在新的一年,Flutter 的研發體驗會越來越好,iBox 也能為 Flutter 的推廣盡一份綿薄之力。
六 參考資料
作者 | 蘇策
原文鏈接:https://developer.aliyun.com/article/872997?utm_content=g_1000327190
本文為阿里云原創內容,未經允許不得轉載。
何夕遠