從0到1,IDE如何提升端側研發效率?| DX研發模式

語言: CN / TW / HK

DX全稱DinamicX,目前是在淘寶乃至整個阿里集團內廣泛使用的Native動態化方案,核心優勢是效能和穩定性。過去幾年一直有其他淘寶/集團的外部文章中有涉及到DX,但DX一直沒有對外做過完整介紹,對外界來說這兩個字母頗有些神祕色彩。本系列文章《DX研發模式》我們就將拉下它神祕的面紗,看看過去兩年 DX 在做什麼。

本文主要闡述 DX 在追求極致的效能體驗過程中,所突破的效能瓶頸與實踐經驗。

《DX研發模式》系列文章預告如下,歡迎持續關注:

  1. 《淘寶Native研發模式的演進與思考》

  2. 《列表容器&事件鏈如何助力業務快速迭代》

  3. 《如何持續突破效能表現?》

  4. 本文:《從0到1,IDE如何提升端側研發效率?》

背景

隨著應用DinamicX(簡稱DX,下同)技術的場景和團隊愈加複雜與廣泛,持續保障DX核心競爭力,支援團隊級別協同開發,助力複雜業務場景的訴求愈發強烈。之前的DX開發基於模板平臺,其核心為基於開源的Monaco編輯器(驅動VScode的開原始碼編輯器)定製開發的前端工程。雖然模板平臺在過去一定程度上滿足了業務開發需要,但其編輯體驗,除錯體驗和效能保障等愈發難以滿足開發者要求。

面對上述這些問題,從DX業務研發的需求角度看,我們需要一站式的開發環境,提供從建立,開發,編譯,除錯,到釋出的全研發週期保障。

全研發週期保障

技術方案選型與設計

基於上述考慮,我們需要的是一個IDE。不同於模板平臺這樣的Editor,IDE提供了完整的開發週期支援。目前業界主流的VSCode,不僅提供了豐富的API用於做擴充套件,也包含了極其豐富的外掛市場,可通過開發VSCode外掛的方式來提供DX IDE。

VSCode生態

  • 模板平臺運行於Web環境,受限於瀏覽器, IDE運行於本地環境,擴充套件豐富容易,環境可控相容性好;

  • 編輯器可用來做豐富的編輯期支援,其LSP API除部分API(呼叫棧,快速修復,展示所有引用,動態計算表示式,內聯值計算,類繼承關係,符號表)不支援外,提供了豐富的編輯補全文件等功能;

  • 相較於純粹的編輯器,IDE則提供了完整的開發週期支援,包括專案系統,程式碼歷史上下文理解,除錯,同其他功能的結合(如腳手架,編譯等),應用研發週期管理,平臺相關的內容(如Swift, Kotlin, Faas)等。

雖然VSCode提供了諸多能力及擴充套件,包括但不限於檔案樹及選單,工程體系,編輯器與語言服務(智慧感知),除錯服務,更好的整合構建與開發生命週期管理,平臺工具相關等,但在面向開發者的互動層面,仍存在諸多限制與不便。與此同時,發源於阿里經濟體內部的IDE框架--OpenSumi框架 ( 阿里&螞蟻自研 IDE 研發框架, 已開源 ),既可相容 100% VS Code API,也擴充套件了諸多API,提供了豐富的UI自定義支援,大大簡化了自定義外掛的互動開發,因而我們採用OpenSumi作為IDE最終的技術選型。

OpenSumi定製擴充套件

如上,下圖簡要說明了OpenSumi對於自定義檢視的支援。

結合上述的開發目標和技術選型,我們有了如下的設計。

設計大圖

分層設計

總體來看IDE分為以下幾個層次:

1 IDE容器(CLI)

如上我們使用了基於OpenSumi框架的IDE基座,其不僅相容了VSCode生態,還提供諸多API等擴充套件,形成了ide-framework。再通過針對經濟體場景下的定製,如登入態,前端開發工作臺等,打包構建了O2這一最終的交付產品。對於我們而言,就是通過開發相容VSCode API的OpenSumi外掛,通過在O2上安裝外掛以達到最終的產品交付。

考慮到命令列呼叫、程式碼複用的原因,我們設計了基於Node.js的CLI用於支援諸多基本功能,如建立模板,編譯模板,釋出模板等。這裡也有一個兩級分層。即提供通用的除錯服務,靜態檔案服務的utbd-devtools,以及基於utbd-devtools的各個不同CLI/IDE外掛(通過DaemonInterface同utbd-devtools進行互動)。

2 底層能力

這裡主要抽象了一些同模板開發沒有直接關係的一些公共服務,包括除錯協議(通道)、資料的儲存與持久化、單例物件的管理池、Git服務、資料埋點服務等。

3 基礎服務(模板開發)

這裡主要是模板開發所需要的一些基礎服務。

從編輯的角度而言,主要是自定義的DSL下的程式碼智慧感知,核心是要一方面去實時分析原始碼的語法樹結構,一方面要結合DSL本身的約束與規範來判斷各個樹節點(及屬性)是否合法等,再結合VSCode本身提供的語言伺服器協議,實現最終的程式碼智慧感知。從DX的角度而言,我們需要考慮以下DSL的分析:

  1. xml: 即main.xml,其描述了檢視的結構與樣式,對其分析有成熟方案;

  2. json: 包括event_chain.json和mock.json, 用於描述事件鏈和mock資料,對其分析有成熟方案;

  3. 表示式: 基於模板設定的資料來源(data),開發者可通過表示式的形式來描述屬性,如:

<ImageView
width="match_content"
height="14"
scaleType="fitXY"
imageUrl="@{data.picUrl}"
visibility="@{data.picUrl?'visible':'gone'}"
/>

此處的imageUrl和visibility屬性即通過表示式書寫,表示式不僅可用於XML,也可用於事件鏈檔案。表示式語法是一個刪減版的TypeScript語法,通過書寫antlr4語法檔案(Lexer.g4和Parser.g4),使用antlr4ts工具即可自動生成對應的Lexer.ts,Parser.ts,ParserListener.ts和ParserVisitor.ts檔案,從而用於後續AST分析。

分析獲得DSL的AST後,通過元資料(平臺約束的控制元件、表示式、原子能力等)的約束,結合VSCode LSP下支援的程式碼智慧感知API,我們即可實現包括補全、懸浮文件、診斷、跳轉定義、程式碼格式化、摺疊、高亮等在內的程式碼開發支援。

4 Feature開發與研發模式組裝

我們按照研發模式包括一條工作流,工作流又可以分為多個階段(準備階段、建立階段、編輯階段、除錯階段、測試階段、釋出階段),每個階段又包括多個Feature(如建立階段包括建立工程與建立模板)這樣的層次關係,通過開發Feature最終組裝成DevelopPattern。

5 研發模式擴充套件

實踐中,不僅存在各類研發模式等的訴求,因為各種原因,還存在不少基於研發模式的自定義擴充套件,如訊息業務域有基於DX模式的指令碼擴充套件,菜鳥和CBU有基於DX模式的容器搭建擴充套件。為此,我們還設計了研發模式擴充套件外掛,容許外掛對上述的研發模式進行自定義擴充套件以滿足各自訴求。

IDE功能與使用

本文只介紹DX研發模式相關功能。

功能區圖示

建立階段

建立階段包括DX工程與模板。

建立工程

  1. 設定GitlabToken(僅一次,以便自動建立Gitlab專案)

  2. 點選建立工程入口

  3. 選擇研發模式(此處應為DX)

  4. 配置引數,建立專案

建立模板

【新建模板】

  1. 點選建立模板入口

  2. 配置引數,建立模板

【克隆模板】

  1. 選擇需要克隆的模板對應的cola.build並右鍵

  2. 點選克隆模板

編輯階段

匯入模板

其中包括通過關鍵字搜尋模板,搜尋結果可以直接開啟(如本地存在),也可以選擇匯入。

匯入時,我們可以選擇針對單模板的匯入,也可以通過應用名+業務名的方式檢索到相關的所有模板,一併匯入。

模板匯入過程中,會挨個查詢各個模板的所有版本號,已經對應的內容,將這些內容作為Git記錄,加以提交。對於正式版本號,會打上形如: release/templatename/templateversion這樣的tag。

模板依賴管理

目前IDE中並不支援編譯基礎元件,僅支援引用基礎元件。如需編輯基礎元件需在模板平臺上操作,然後本地更新元資料獲取最新版本號後更新依賴以生效。這是因為,我們希望未來Import可以由Template標籤來替代,Template相關的編輯,引用和編譯IDE中都是支援的。

因而,這裡只包括基礎元件的依賴管理以及批量版本變更。

對於基礎元件的依賴管理,實際上是視覺化地編輯cola.build中的dependencies欄位。

批量版本變更則適用於一個基礎元件被一組模板引用時,批量地更新這些引用模板對於被引用的基礎元件的版本依賴描述(原始碼),通過選擇預釋出,我們也可以在更新原始碼的同時,將引用模板批量預釋出。

類似基礎元件依賴的批量修改,IDE也支援了Slot引用的批量修改。

程式碼幫助

此處主要包括事件鏈格式化、表示式格式化、本地檔案搜尋、以及程式碼樣例搜尋。

其中本地檔案搜尋可通過簡單的規則精準搜尋到檔案如並點選開啟,如s/s/m可匹配到:  sub_main/src/mock.json。

程式碼樣例搜尋可通過關鍵字搜尋到當前Aone程式碼庫(Gitlab)上有哪些引用,如@getEngineStorage結合event_chain.json可以瞭解到時間鏈中getEngineStorage的具體用法。

表示式支援

此處的主要作用是實現表示式的一鍵格式化。

事件鏈視覺化

此處主要是通過視覺化的方式將事件鏈描述的原子能力的呼叫與轉移表現出來,目前支援了多種轉移關係,包括顯式的轉移以及隱式(表示式)的轉移關係。

點選節點或者邊也可以自動選中對應的程式碼區域。

程式碼智慧感知

  1. 程式碼補全: 支援main.xml中的控制元件名,屬性,屬性值;event_chain.json中的原子能力名,原子能力引數,事件鏈節點;表示式(名稱/data欄位/事件鏈名稱)等;

  2. 懸浮文件: 支援main.xml中的控制元件名、屬性名;event_chain.json中的原子能力名,原子能力引數;表示式名;

  3. 程式碼診斷: 包括main.xml中的控制元件名,屬性名,屬性值;event_chain.json中的原子能力名(原子能力引數暫不支援,主要原因是平臺上的約束不夠完備);表示式名;

  4. 跳轉至定義: 主要是跳轉到mock.json(即data表示式,從main.xml或event_chain.json)和event_chain.json(從main.xml);

  5. 程式碼格式化: 包括main.xml的格式化,event_chain.json的格式化,表示式格式化;

  6. 程式碼摺疊: 包括main.xml, event_chain.json, mock.json以及表示式的摺疊;

  7. 程式碼高亮: 主要指的是表示式名的高亮。

除錯階段

預覽

這裡主要包括除錯服務掃碼、預覽頁單模板預覽和業務容器多模板預覽。開發者通過掃碼連線除錯服務,當有裝置連線時,當前選中的模板的變更將會編譯並將產物實時推送到手機並生效,當前沒有裝置連線時,模板變更會實時編譯,並將編譯產物以二維碼方式透出,可直接掃碼預覽。

其中預覽頁單模板預覽同之前模板平臺。

業務容器多模板的預覽核心是解決預覽頁預覽的一些問題,包括缺少對於自定義組建的良好支援,只能預覽單模板,資料Mock不真實等,使用這一特性,開發者可以在任意包含DX模板的頁面中預覽IDE中的模板檔案,程式碼變更並同步到裝置成功後,重新整理頁面重新渲染模板即可生效。

這裡也包括通過Command+Shift+P喚起命令面板,執行切換預覽模板從而快速切換到指定模板的功能(僅預覽頁預覽下有效)。

檢視審查

檢視審查主要用於排查佈局顯示上的問題,比如節點丟失,屬性值不對等。

假設已經掃碼連線了除錯服務,下同,不贅述。

  1. IDE上開啟啟用檢視審查開關

  2. 裝置側渲染DX模板

  3. IDE上選中某條檢視審查記錄(也支援模糊搜尋)

  4. 開啟對應模板的main.xml檔案

  5. 點選main.xml中的某個標籤,可以自動展開三棵樹中的對應節點,並且將裝置側的對應檢視高亮。

  6. 點選展開樹節點,或者展開樹節點屬性節點,即可自動選中對應的原始碼。

表示式回放

表示式回放主要用於排查複雜表示式執行的問題。

  1. IDE上開啟啟用表示式回放開關

  2. 裝置側渲染DX模板

  3. IDE上選中某條表示式回放記錄(也支援模糊搜尋)

  4. 點選回放按鈕,即可看到整個表示式執行的時序

  5. 選中某個被執行過的節點,可以看到其執行的上下文。

事件鏈回放

事件鏈回放主要用於排查事件鏈執行的問題。

  1. IDE上開啟啟用事件鏈回放開關

  2. 裝置側渲染DX模板

  3. IDE上選中某條事件鏈回放記錄(也支援模糊搜尋)

  4. 點選回放按鈕,即可看到整個事件鏈執行的時序

  5. 選中某個被執行過的節點,可以看到其執行的上下文。

裝置管理

主要用於同iOS模擬器(Mac上)的深度融合,這樣開發者即使沒有一個iOS裝置,或者裝置商沒有可用於測試的包,也可以方便地安裝並使用IDE的各個功能。

釋出階段

模板釋出

  1. 選擇需要釋出的模板(支援搜尋)

  2. 選擇需要釋出的分支

  3. 填寫釋出描述

  4. 選擇部分配置項(其中校驗版本衝突主要用於防止模板平臺上存在一些更新的版本號;預先提交變更可使開發者訊速地修改校驗變更(尤其是簡單模板的變更);跳過Git檢查可以不用檢查是否有待提交的內容,尤其是當開發者需要釋出另一個分支,且當前分支的變更不需要提交時;預釋出則用於配置是否正式釋出)

  5. 釋出即可

釋出的結果彈窗也會提示開發者這次釋出產生了哪些版本號,產物cdn地址等。

模板歷史版本查詢

這裡包括: 模板url拷貝、模板zip下載、模板預覽、釋出資訊、原始碼檢視、程式碼Diff、內容回滾、Diff連結分享(CR使用)等。

批量內建

這裡將會完成雙端產物的內建,以及Android側所需要的presetTemplateInfos.json構建。

設定

這裡主要是Gitlab Token的配置,以及基於GitDiff的模板釋出所以來的Diff基線配置。

IDE演進思考

針對過去模板平臺的不足,我們實現了從編輯器到IDE的轉變,顯著提升了開發者的研發體驗。面向未來,我們有以下方面的演進思考:

擴大應用場景/團隊

1 IDE直接收益

  • 工程化支援,開發者可在一個工作區內開發相關業務的一組模板;

  • 程式碼託管到Gitlab,多人協同,提交歷史,回滾,搜尋,CR,資料統計,直接打通集團程式碼服務;

  • 更簡單的批量模板管理,如批量修改基礎元件依賴,批量釋出,批量內建等;

  • 對標高階語言編輯的程式碼智慧感知體驗(補全,文件,診斷,跳轉,格式化,摺疊,高亮等),涵蓋main.xml, 表示式,事件鏈等。不僅如此,針對事件鏈,IDE還提供排序,一鍵摺疊所有和視覺化預覽;

  • 更好的預覽體驗,開發者可結合IDE的業務容器預覽直接在當前業務容器動態替換模板(IDE中模板即時修改編譯生效);

  • 豐富的問題排查工具箱,針對檢視異常排查,IDE提供了檢視審查和原始碼關聯,可以建立動態的原始碼同實際檢視結構(屬性)的雙向關聯;針對表示式執行復雜的問題,IDE提供了表示式回放以跟蹤表示式AST的結構和,執行順序,輸入輸出和上下文;針對事件鏈執行復雜的問題,IDE提供了事件鏈回放以跟蹤事件鏈中原子能力之間的執行順序,輸入輸出和上下文;

  • 更好的模擬器融合,Mac上IDE深度融合了iOS模擬器,開發者可快速安裝/啟用應用,連線除錯服務並預覽頁面。

2 IDE潛在收益

  • DX IDE提供了研發模式層面的擴充套件,基於DX衍生出來的技術方案可便捷地融合到IDE;

  • 目前我們正在移動小組層面同研發體驗CoE團隊討論客戶端研發效能的度量模型和指標,基於IDE對於研發過程的多維度細粒度感知,我們將有機會幫助團隊度量研發效能,進一步改善研發體驗。

3 IDE使用成本

  • 開發者需安裝O2和DX IDE外掛,之後會有自動化的指令碼,工具和命令以保證環境符合要求;

  • 既有模板遷移成本的問題,目前IDE支援了基於搜尋關鍵字(或ID)的單模板匯入,以及基於app&biz的一組業務模板匯入,一鍵遷移所需模板到DX工程;

技術迭代

目前,IDE已實現DX工程化和全研發生命週期支援,包含優秀的程式碼編輯體驗,諸多問題排查手段,豐富的工具箱以解決研發痛點,後續我們將圍繞以下方面開展技術迭代。

1 既有設計的完善

  • 補齊Android SDK中檢視審查功能。

  • 效能方面,提供包括編輯期Linter,執行期的實時效能採集,釋出期的Benchmark,運維期的效能大盤等資料以改善模板效能。

  • 相容性方面,打通手機中臺等裝置服務,開發者可以快速預覽在不同裝置上的渲染效果和效能。

2 技術演進與探索

  • 目前的技術架構下,開發者依需安裝IDE和外掛,存在接入成本高的問題。通過將IDE遠端部署,開發者使用Web連線遠端服務,不僅可避免安裝成本,也便於共享工作區等;

  • 過去客戶端業務研發往往是客戶端與服務端分離,面對不斷增加的業務挑戰,更快的迭代速度要求,以業務為中心的端雲一體化開發有了更多價值,Faas本身的日益成熟也使得客戶端開發後端邏輯更為便捷可行。IDE作為一個統一的程式設計平面,能更好地支援一體化工程下的前後端邏輯(頁面)開發,加速業務價值交付;

  • 目前業界主流生態越來越多地使用宣告式UI,不論是技術先進性還是技術同學成長,我們都應更多地擁抱這一趨勢。探索DX DSL同聲明式UI(JetpackCompose, SwiftUI,Flutter,ArkUI)的結合,通過升級DSL,結合Jetpack Compose/SwiftUI/Flutter,配合以相關的分析解析編譯執行等工具鏈配套,開發者可更貼近原生(友好)地開發跨平臺業務。

關注我們,阿里前沿移動乾貨&實踐給你思考!