從0到1,IDE如何提升端側(cè)研發(fā)效率?
背景
隨著應(yīng)用DinamicX(簡稱DX,下同)技術(shù)的場景和團(tuán)隊(duì)愈加復(fù)雜與廣泛,持續(xù)保障DX核心競爭力,支持團(tuán)隊(duì)級(jí)別協(xié)同開發(fā),助力復(fù)雜業(yè)務(wù)場景的訴求愈發(fā)強(qiáng)烈。之前的DX開發(fā)基于模板平臺(tái),其核心為基于開源的Monaco編輯器(驅(qū)動(dòng)VScode的開源代碼編輯器)定制開發(fā)的前端工程。雖然模板平臺(tái)在過去一定程度上滿足了業(yè)務(wù)開發(fā)需要,但其編輯體驗(yàn),調(diào)試體驗(yàn)和性能保障等愈發(fā)難以滿足開發(fā)者要求。
面對上述這些問題,從DX業(yè)務(wù)研發(fā)的需求角度看,我們需要一站式的開發(fā)環(huán)境,提供從創(chuàng)建,開發(fā),編譯,調(diào)試,到發(fā)布的全研發(fā)周期保障。

全研發(fā)周期保障
技術(shù)方案選型與設(shè)計(jì)
基于上述考慮,我們需要的是一個(gè)IDE。不同于模板平臺(tái)這樣的Editor,IDE提供了完整的開發(fā)周期支持。目前業(yè)界主流的VSCode,不僅提供了豐富的API用于做擴(kuò)展,也包含了極其豐富的插件市場,可通過開發(fā)VSCode插件的方式來提供DX IDE。
VSCode生態(tài)

模板平臺(tái)運(yùn)行于Web環(huán)境,受限于瀏覽器, IDE運(yùn)行于本地環(huán)境,擴(kuò)展豐富容易,環(huán)境可控兼容性好;
編輯器可用來做豐富的編輯期支持,其LSP API除部分API(調(diào)用棧,快速修復(fù),展示所有引用,動(dòng)態(tài)計(jì)算表達(dá)式,內(nèi)聯(lián)值計(jì)算,類繼承關(guān)系,符號(hào)表)不支持外,提供了豐富的編輯補(bǔ)全文檔等功能;
相較于純粹的編輯器,IDE則提供了完整的開發(fā)周期支持,包括項(xiàng)目系統(tǒng),代碼歷史上下文理解,調(diào)試,同其他功能的結(jié)合(如腳手架,編譯等),應(yīng)用研發(fā)周期管理,平臺(tái)相關(guān)的內(nèi)容(如Swift, Kotlin, Faas)等。
雖然VSCode提供了諸多能力及擴(kuò)展,包括但不限于文件樹及菜單,工程體系,編輯器與語言服務(wù)(智能感知),調(diào)試服務(wù),更好的集成構(gòu)建與開發(fā)生命周期管理,平臺(tái)工具相關(guān)等,但在面向開發(fā)者的交互層面,仍存在諸多限制與不便。與此同時(shí),發(fā)源于阿里經(jīng)濟(jì)體內(nèi)部的IDE框架--OpenSumi框架 ( 阿里&螞蟻?zhàn)匝?IDE 研發(fā)框架, 已開源 ),既可兼容 100% VS Code API,也擴(kuò)展了諸多API,提供了豐富的UI自定義支持,大大簡化了自定義插件的交互開發(fā),因而我們采用OpenSumi作為IDE最終的技術(shù)選型。
OpenSumi定制擴(kuò)展
如上,下圖簡要說明了OpenSumi對于自定義視圖的支持。

結(jié)合上述的開發(fā)目標(biāo)和技術(shù)選型,我們有了如下的設(shè)計(jì)。
設(shè)計(jì)大圖

分層設(shè)計(jì)
總體來看IDE分為以下幾個(gè)層次:
1 IDE容器(CLI)
如上我們使用了基于OpenSumi框架的IDE基座,其不僅兼容了VSCode生態(tài),還提供諸多API等擴(kuò)展,形成了ide-framework。再通過針對經(jīng)濟(jì)體場景下的定制,如登錄態(tài),前端開發(fā)工作臺(tái)等,打包構(gòu)建了O2這一最終的交付產(chǎn)品。對于我們而言,就是通過開發(fā)兼容VSCode API的OpenSumi插件,通過在O2上安裝插件以達(dá)到最終的產(chǎn)品交付。
考慮到命令行調(diào)用、代碼復(fù)用的原因,我們設(shè)計(jì)了基于Node.js的CLI用于支持諸多基本功能,如創(chuàng)建模板,編譯模板,發(fā)布模板等。這里也有一個(gè)兩級(jí)分層。即提供通用的調(diào)試服務(wù),靜態(tài)文件服務(wù)的utbd-devtools,以及基于utbd-devtools的各個(gè)不同CLI/IDE插件(通過DaemonInterface同utbd-devtools進(jìn)行交互)。

2 底層能力
這里主要抽象了一些同模板開發(fā)沒有直接關(guān)系的一些公共服務(wù),包括調(diào)試協(xié)議(通道)、數(shù)據(jù)的存儲(chǔ)與持久化、單例對象的管理池、Git服務(wù)、數(shù)據(jù)埋點(diǎn)服務(wù)等。
3 基礎(chǔ)服務(wù)(模板開發(fā))
這里主要是模板開發(fā)所需要的一些基礎(chǔ)服務(wù)。
從編輯的角度而言,主要是自定義的DSL下的代碼智能感知,核心是要一方面去實(shí)時(shí)分析源代碼的語法樹結(jié)構(gòu),一方面要結(jié)合DSL本身的約束與規(guī)范來判斷各個(gè)樹節(jié)點(diǎn)(及屬性)是否合法等,再結(jié)合VSCode本身提供的語言服務(wù)器協(xié)議,實(shí)現(xiàn)最終的代碼智能感知。從DX的角度而言,我們需要考慮以下DSL的分析:
- xml: 即main.xml,其描述了視圖的結(jié)構(gòu)與樣式,對其分析有成熟方案;
- json: 包括event_chain.json和mock.json, 用于描述事件鏈和mock數(shù)據(jù),對其分析有成熟方案;
- 表達(dá)式: 基于模板設(shè)置的數(shù)據(jù)源(data),開發(fā)者可通過表達(dá)式的形式來描述屬性,如:
<ImageView
width="match_content"
height="14"
scaleType="fitXY"
imageUrl="@{data.picUrl}"
visibility="@{data.picUrl?'visible':'gone'}"
/>
此處的imageUrl和visibility屬性即通過表達(dá)式書寫,表達(dá)式不僅可用于XML,也可用于事件鏈文件。表達(dá)式語法是一個(gè)刪減版的TypeScript語法,通過書寫antlr4語法文件(Lexer.g4和Parser.g4),使用antlr4ts工具即可自動(dòng)生成對應(yīng)的Lexer.ts,Parser.ts,ParserListener.ts和ParserVisitor.ts文件,從而用于后續(xù)AST分析。

分析獲得DSL的AST后,通過元數(shù)據(jù)(平臺(tái)約束的控件、表達(dá)式、原子能力等)的約束,結(jié)合VSCode LSP下支持的代碼智能感知API,我們即可實(shí)現(xiàn)包括補(bǔ)全、懸浮文檔、診斷、跳轉(zhuǎn)定義、代碼格式化、折疊、高亮等在內(nèi)的代碼開發(fā)支持。

4 Feature開發(fā)與研發(fā)模式組裝
我們按照研發(fā)模式包括一條工作流,工作流又可以分為多個(gè)階段(準(zhǔn)備階段、創(chuàng)建階段、編輯階段、調(diào)試階段、測試階段、發(fā)布階段),每個(gè)階段又包括多個(gè)Feature(如創(chuàng)建階段包括創(chuàng)建工程與創(chuàng)建模板)這樣的層次關(guān)系,通過開發(fā)Feature最終組裝成DevelopPattern。
5 研發(fā)模式擴(kuò)展
實(shí)踐中,不僅存在各類研發(fā)模式等的訴求,因?yàn)楦鞣N原因,還存在不少基于研發(fā)模式的自定義擴(kuò)展,如消息業(yè)務(wù)域有基于DX模式的腳本擴(kuò)展,菜鳥和CBU有基于DX模式的容器搭建擴(kuò)展。為此,我們還設(shè)計(jì)了研發(fā)模式擴(kuò)展插件,容許插件對上述的研發(fā)模式進(jìn)行自定義擴(kuò)展以滿足各自訴求。
IDE功能與使用
本文只介紹DX研發(fā)模式相關(guān)功能。

功能區(qū)圖示
創(chuàng)建階段
創(chuàng)建階段包括DX工程與模板。
創(chuàng)建工程
- 設(shè)置GitlabToken(僅一次,以便自動(dòng)創(chuàng)建Gitlab項(xiàng)目)
- 點(diǎn)擊創(chuàng)建工程入口
- 選擇研發(fā)模式(此處應(yīng)為DX)
- 配置參數(shù),創(chuàng)建項(xiàng)目

創(chuàng)建模板
【新建模板】
- 點(diǎn)擊創(chuàng)建模板入口
- 配置參數(shù),創(chuàng)建模板
【克隆模板】
- 選擇需要克隆的模板對應(yīng)的cola.build并右鍵
- 點(diǎn)擊克隆模板

編輯階段
導(dǎo)入模板
其中包括通過關(guān)鍵字搜索模板,搜索結(jié)果可以直接打開(如本地存在),也可以選擇導(dǎo)入。
導(dǎo)入時(shí),我們可以選擇針對單模板的導(dǎo)入,也可以通過應(yīng)用名+業(yè)務(wù)名的方式檢索到相關(guān)的所有模板,一并導(dǎo)入。
模板導(dǎo)入過程中,會(huì)挨個(gè)查詢各個(gè)模板的所有版本號(hào),已經(jīng)對應(yīng)的內(nèi)容,將這些內(nèi)容作為Git記錄,加以提交。對于正式版本號(hào),會(huì)打上形如: release/templatename/templateversion這樣的tag。
模板依賴管理
目前IDE中并不支持編譯基礎(chǔ)組件,僅支持引用基礎(chǔ)組件。如需編輯基礎(chǔ)組件需在模板平臺(tái)上操作,然后本地更新元數(shù)據(jù)獲取最新版本號(hào)后更新依賴以生效。這是因?yàn)?,我們希望未來Import可以由Template標(biāo)簽來替代,Template相關(guān)的編輯,引用和編譯IDE中都是支持的。
因而,這里只包括基礎(chǔ)組件的依賴管理以及批量版本變更。
對于基礎(chǔ)組件的依賴管理,實(shí)際上是可視化地編輯cola.build中的dependencies字段。
批量版本變更則適用于一個(gè)基礎(chǔ)組件被一組模板引用時(shí),批量地更新這些引用模板對于被引用的基礎(chǔ)組件的版本依賴描述(源代碼),通過選擇預(yù)發(fā)布,我們也可以在更新源代碼的同時(shí),將引用模板批量預(yù)發(fā)布。
類似基礎(chǔ)組件依賴的批量修改,IDE也支持了Slot引用的批量修改。
代碼幫助
此處主要包括事件鏈格式化、表達(dá)式格式化、本地文件搜索、以及代碼樣例搜索。
其中本地文件搜索可通過簡單的規(guī)則精準(zhǔn)搜索到文件如并點(diǎn)擊打開,如s/s/m可匹配到: sub_main/src/mock.json。
代碼樣例搜索可通過關(guān)鍵字搜索到當(dāng)前Aone代碼庫(Gitlab)上有哪些引用,如@getEngineStorage結(jié)合event_chain.json可以了解到時(shí)間鏈中g(shù)etEngineStorage的具體用法。
表達(dá)式支持
此處的主要作用是實(shí)現(xiàn)表達(dá)式的一鍵格式化。
事件鏈可視化
此處主要是通過可視化的方式將事件鏈描述的原子能力的調(diào)用與轉(zhuǎn)移表現(xiàn)出來,目前支持了多種轉(zhuǎn)移關(guān)系,包括顯式的轉(zhuǎn)移以及隱式(表達(dá)式)的轉(zhuǎn)移關(guān)系。

點(diǎn)擊節(jié)點(diǎn)或者邊也可以自動(dòng)選中對應(yīng)的代碼區(qū)域。
代碼智能感知
- 代碼補(bǔ)全: 支持main.xml中的控件名,屬性,屬性值;event_chain.json中的原子能力名,原子能力參數(shù),事件鏈節(jié)點(diǎn);表達(dá)式(名稱/data字段/事件鏈名稱)等;
- 懸浮文檔: 支持main.xml中的控件名、屬性名;event_chain.json中的原子能力名,原子能力參數(shù);表達(dá)式名;
- 代碼診斷: 包括main.xml中的控件名,屬性名,屬性值;event_chain.json中的原子能力名(原子能力參數(shù)暫不支持,主要原因是平臺(tái)上的約束不夠完備);表達(dá)式名;
- 跳轉(zhuǎn)至定義: 主要是跳轉(zhuǎn)到mock.json(即data表達(dá)式,從main.xml或event_chain.json)和event_chain.json(從main.xml);
- 代碼格式化: 包括main.xml的格式化,event_chain.json的格式化,表達(dá)式格式化;
- 代碼折疊: 包括main.xml, event_chain.json, mock.json以及表達(dá)式的折疊;
- 代碼高亮: 主要指的是表達(dá)式名的高亮。
調(diào)試階段
預(yù)覽
這里主要包括調(diào)試服務(wù)掃碼、預(yù)覽頁單模板預(yù)覽和業(yè)務(wù)容器多模板預(yù)覽。開發(fā)者通過掃碼連接調(diào)試服務(wù),當(dāng)有設(shè)備連接時(shí),當(dāng)前選中的模板的變更將會(huì)編譯并將產(chǎn)物實(shí)時(shí)推送到手機(jī)并生效,當(dāng)前沒有設(shè)備連接時(shí),模板變更會(huì)實(shí)時(shí)編譯,并將編譯產(chǎn)物以二維碼方式透出,可直接掃碼預(yù)覽。
其中預(yù)覽頁單模板預(yù)覽同之前模板平臺(tái)。
業(yè)務(wù)容器多模板的預(yù)覽核心是解決預(yù)覽頁預(yù)覽的一些問題,包括缺少對于自定義組建的良好支持,只能預(yù)覽單模板,數(shù)據(jù)Mock不真實(shí)等,使用這一特性,開發(fā)者可以在任意包含DX模板的頁面中預(yù)覽IDE中的模板文件,代碼變更并同步到設(shè)備成功后,刷新頁面重新渲染模板即可生效。
這里也包括通過Command+Shift+P喚起命令面板,執(zhí)行切換預(yù)覽模板從而快速切換到指定模板的功能(僅預(yù)覽頁預(yù)覽下有效)。
視圖審查
視圖審查主要用于排查布局顯示上的問題,比如節(jié)點(diǎn)丟失,屬性值不對等。
假設(shè)已經(jīng)掃碼連接了調(diào)試服務(wù),下同,不贅述。
- IDE上打開啟用視圖審查開關(guān)
- 設(shè)備側(cè)渲染DX模板
- IDE上選中某條視圖審查記錄(也支持模糊搜索)
- 打開對應(yīng)模板的main.xml文件
- 點(diǎn)擊main.xml中的某個(gè)標(biāo)簽,可以自動(dòng)展開三棵樹中的對應(yīng)節(jié)點(diǎn),并且將設(shè)備側(cè)的對應(yīng)視圖高亮。
- 點(diǎn)擊展開樹節(jié)點(diǎn),或者展開樹節(jié)點(diǎn)屬性節(jié)點(diǎn),即可自動(dòng)選中對應(yīng)的源代碼。

表達(dá)式回放
表達(dá)式回放主要用于排查復(fù)雜表達(dá)式執(zhí)行的問題。
- IDE上打開啟用表達(dá)式回放開關(guān)
- 設(shè)備側(cè)渲染DX模板
- IDE上選中某條表達(dá)式回放記錄(也支持模糊搜索)
- 點(diǎn)擊回放按鈕,即可看到整個(gè)表達(dá)式執(zhí)行的時(shí)序
- 選中某個(gè)被執(zhí)行過的節(jié)點(diǎn),可以看到其執(zhí)行的上下文。

事件鏈回放
事件鏈回放主要用于排查事件鏈執(zhí)行的問題。
- IDE上打開啟用事件鏈回放開關(guān)
- 設(shè)備側(cè)渲染DX模板
- IDE上選中某條事件鏈回放記錄(也支持模糊搜索)
- 點(diǎn)擊回放按鈕,即可看到整個(gè)事件鏈執(zhí)行的時(shí)序
- 選中某個(gè)被執(zhí)行過的節(jié)點(diǎn),可以看到其執(zhí)行的上下文。

設(shè)備管理
主要用于同iOS模擬器(Mac上)的深度融合,這樣開發(fā)者即使沒有一個(gè)iOS設(shè)備,或者設(shè)備商沒有可用于測試的包,也可以方便地安裝并使用IDE的各個(gè)功能。
發(fā)布階段
模板發(fā)布
- 選擇需要發(fā)布的模板(支持搜索)
- 選擇需要發(fā)布的分支
- 填寫發(fā)布描述
- 選擇部分配置項(xiàng)(其中校驗(yàn)版本沖突主要用于防止模板平臺(tái)上存在一些更新的版本號(hào);預(yù)先提交變更可使開發(fā)者訊速地修改校驗(yàn)變更(尤其是簡單模板的變更);跳過Git檢查可以不用檢查是否有待提交的內(nèi)容,尤其是當(dāng)開發(fā)者需要發(fā)布另一個(gè)分支,且當(dāng)前分支的變更不需要提交時(shí);預(yù)發(fā)布則用于配置是否正式發(fā)布)
- 發(fā)布即可

發(fā)布的結(jié)果彈窗也會(huì)提示開發(fā)者這次發(fā)布產(chǎn)生了哪些版本號(hào),產(chǎn)物cdn地址等。
模板歷史版本查詢

這里包括: 模板url拷貝、模板zip下載、模板預(yù)覽、發(fā)布信息、源代碼查看、代碼Diff、內(nèi)容回滾、Diff鏈接分享(CR使用)等。
批量內(nèi)置

這里將會(huì)完成雙端產(chǎn)物的內(nèi)置,以及Android側(cè)所需要的presetTemplateInfos.json構(gòu)建。
設(shè)置
這里主要是Gitlab Token的配置,以及基于GitDiff的模板發(fā)布所以來的Diff基線配置。
IDE演進(jìn)思考
針對過去模板平臺(tái)的不足,我們實(shí)現(xiàn)了從編輯器到IDE的轉(zhuǎn)變,顯著提升了開發(fā)者的研發(fā)體驗(yàn)。面向未來,我們有以下方面的演進(jìn)思考:
擴(kuò)大應(yīng)用場景/團(tuán)隊(duì)
1 IDE直接收益
- 工程化支持,開發(fā)者可在一個(gè)工作區(qū)內(nèi)開發(fā)相關(guān)業(yè)務(wù)的一組模板;
- 代碼托管到Gitlab,多人協(xié)同,提交歷史,回滾,搜索,CR,數(shù)據(jù)統(tǒng)計(jì),直接打通集團(tuán)代碼服務(wù);
- 更簡單的批量模板管理,如批量修改基礎(chǔ)組件依賴,批量發(fā)布,批量內(nèi)置等;
- 對標(biāo)高級(jí)語言編輯的代碼智能感知體驗(yàn)(補(bǔ)全,文檔,診斷,跳轉(zhuǎn),格式化,折疊,高亮等),涵蓋main.xml, 表達(dá)式,事件鏈等。不僅如此,針對事件鏈,IDE還提供排序,一鍵折疊所有和可視化預(yù)覽;
- 更好的預(yù)覽體驗(yàn),開發(fā)者可結(jié)合IDE的業(yè)務(wù)容器預(yù)覽直接在當(dāng)前業(yè)務(wù)容器動(dòng)態(tài)替換模板(IDE中模板即時(shí)修改編譯生效);
- 豐富的問題排查工具箱,針對視圖異常排查,IDE提供了視圖審查和源代碼關(guān)聯(lián),可以建立動(dòng)態(tài)的源碼同實(shí)際視圖結(jié)構(gòu)(屬性)的雙向關(guān)聯(lián);針對表達(dá)式執(zhí)行復(fù)雜的問題,IDE提供了表達(dá)式回放以跟蹤表達(dá)式AST的結(jié)構(gòu)和,執(zhí)行順序,輸入輸出和上下文;針對事件鏈執(zhí)行復(fù)雜的問題,IDE提供了事件鏈回放以跟蹤事件鏈中原子能力之間的執(zhí)行順序,輸入輸出和上下文;
- 更好的模擬器融合,Mac上IDE深度融合了iOS模擬器,開發(fā)者可快速安裝/激活應(yīng)用,連接調(diào)試服務(wù)并預(yù)覽頁面。
2 IDE潛在收益
- DX IDE提供了研發(fā)模式層面的擴(kuò)展,基于DX衍生出來的技術(shù)方案可便捷地融合到IDE;
- 目前我們正在移動(dòng)小組層面同研發(fā)體驗(yàn)CoE團(tuán)隊(duì)討論客戶端研發(fā)效能的度量模型和指標(biāo),基于IDE對于研發(fā)過程的多維度細(xì)粒度感知,我們將有機(jī)會(huì)幫助團(tuán)隊(duì)度量研發(fā)效能,進(jìn)一步改善研發(fā)體驗(yàn)。
3 IDE使用成本
- 開發(fā)者需安裝O2和DX IDE插件,之后會(huì)有自動(dòng)化的腳本,工具和命令以保證環(huán)境符合要求;
- 既有模板遷移成本的問題,目前IDE支持了基于搜索關(guān)鍵字(或ID)的單模板導(dǎo)入,以及基于app&biz的一組業(yè)務(wù)模板導(dǎo)入,一鍵遷移所需模板到DX工程;
技術(shù)迭代
目前,IDE已實(shí)現(xiàn)DX工程化和全研發(fā)生命周期支持,包含優(yōu)秀的代碼編輯體驗(yàn),諸多問題排查手段,豐富的工具箱以解決研發(fā)痛點(diǎn),后續(xù)我們將圍繞以下方面開展技術(shù)迭代。
1 既有設(shè)計(jì)的完善
- 補(bǔ)齊Android SDK中視圖審查功能。
- 性能方面,提供包括編輯期Linter,運(yùn)行期的實(shí)時(shí)性能采集,發(fā)布期的Benchmark,運(yùn)維期的性能大盤等數(shù)據(jù)以改善模板性能。
- 兼容性方面,打通手機(jī)中臺(tái)等設(shè)備服務(wù),開發(fā)者可以快速預(yù)覽在不同設(shè)備上的渲染效果和性能。
2 技術(shù)演進(jìn)與探索
- 目前的技術(shù)架構(gòu)下,開發(fā)者依需安裝IDE和插件,存在接入成本高的問題。通過將IDE遠(yuǎn)程部署,開發(fā)者使用Web連接遠(yuǎn)端服務(wù),不僅可避免安裝成本,也便于共享工作區(qū)等;
- 過去客戶端業(yè)務(wù)研發(fā)往往是客戶端與服務(wù)端分離,面對不斷增加的業(yè)務(wù)挑戰(zhàn),更快的迭代速度要求,以業(yè)務(wù)為中心的端云一體化開發(fā)有了更多價(jià)值,F(xiàn)aas本身的日益成熟也使得客戶端開發(fā)后端邏輯更為便捷可行。IDE作為一個(gè)統(tǒng)一的編程平面,能更好地支持一體化工程下的前后端邏輯(頁面)開發(fā),加速業(yè)務(wù)價(jià)值交付;
- 目前業(yè)界主流生態(tài)越來越多地使用聲明式UI,不論是技術(shù)先進(jìn)性還是技術(shù)同學(xué)成長,我們都應(yīng)更多地?fù)肀н@一趨勢。探索DX DSL同聲明式UI(JetpackCompose, SwiftUI,Flutter,ArkUI)的結(jié)合,通過升級(jí)DSL,結(jié)合Jetpack Compose/SwiftUI/Flutter,配合以相關(guān)的分析解析編譯執(zhí)行等工具鏈配套,開發(fā)者可更貼近原生(友好)地開發(fā)跨平臺(tái)業(yè)務(wù)。


































