低代碼平臺邊界探索:多技術(shù)棧支持及高低代碼混合開發(fā)(低代碼平臺技術(shù)框架)
本文整理自華為云主任工程師莫春輝在 GMTC 全球大前端技術(shù)大會(深圳站)2021 的演講《多技術(shù)棧及高低代碼混合開發(fā)——華為云低代碼平臺架構(gòu)探討》。
當(dāng)前,華為云部門內(nèi)部的前端技術(shù)棧并不統(tǒng)一,比如華為云官網(wǎng)的 Console 控制臺使用 Angular 技術(shù)棧開發(fā),其他內(nèi)部 IT 系統(tǒng)使 Vue 技術(shù)棧開發(fā)。因此,華為云要建設(shè)一套低代碼搭建平臺,對內(nèi)提效能要同時兼顧 Angular 和 Vue 兩種技術(shù)棧,對外建生態(tài)則要同時支持 Vue 和 React 技術(shù)棧。
另外,目前業(yè)界的低代碼搭建平臺大多局限于簡單的應(yīng)用開發(fā),而華為云自身的業(yè)務(wù)邏輯中,既有需要用高代碼開發(fā)的復(fù)雜頁面,又存在一些簡單頁面。這些復(fù)雜頁面,你很難完全通過可視化拖拽搭建出來,但對于簡單的頁面,又希望能夠使用可視化拖拽快速生成。因此,支持高低代碼混合開發(fā)的需求就擺在了我們的眼前。
1. 華為云低代碼平臺建設(shè)背景與訴求
華為云低代碼平臺的建設(shè)背景
在 Gartner 的定義中,低代碼平臺被稱為企業(yè)級低代碼應(yīng)用平臺,是支持快速應(yīng)用開發(fā),使用陳述性、高級的編程抽象(如基于模型驅(qū)動和元數(shù)據(jù)編程語言)實(shí)現(xiàn)一站式應(yīng)用部署、執(zhí)行和管理的應(yīng)用平臺。不同于傳統(tǒng)的應(yīng)用平臺,它支持用戶界面、業(yè)務(wù)邏輯和數(shù)據(jù)服務(wù)的開發(fā),并以犧牲跨平臺的可移植性、應(yīng)用開放性為代價來提高生產(chǎn)效率。
正因?yàn)闋奚丝缙脚_的可移植性和應(yīng)用的開放性,各廠商開發(fā)的低代碼平臺,都不約而同地朝著“低”的方向走,越低越好,甚至是無代碼、智能生成代碼,于是就容易忽略“高”的需求,忽略與“高”的結(jié)合。而且,各廠商都希望用戶從頭到尾都在自己的平臺上進(jìn)行開發(fā)、全程托管,于是就容易忽略“被托”的需求,或者說“被集成”的需求,忽略與存量應(yīng)用的結(jié)合。
這種忽略其實(shí)也是不得已而為之。如果不犧牲跨平臺可移植性,就有可能支撐不同平臺不同技術(shù)棧、生成可移植的代碼,與現(xiàn)有的高代碼(純手寫代碼)相結(jié)合;如果不犧牲應(yīng)用開放性,就有可能更好地支撐被集成的需求,靈活地與存量應(yīng)用相結(jié)合。事實(shí)上,企業(yè)內(nèi)部有非常多的存量應(yīng)用,這些存量應(yīng)用也想通過低代碼平臺去提升開發(fā)效率。
目前華為內(nèi)部已經(jīng)有幾套低代碼平臺,華為云的低代碼平臺是否存在重復(fù)造輪子的嫌疑?2021 年 7 月北京的 GMTC 大會上,阿里巴巴研究員玉伯在談前端現(xiàn)狀的時候說到:阿里內(nèi)部的低代碼平臺也很多,但深入到業(yè)務(wù)層面去看,你就會發(fā)現(xiàn),那些“輪子”都是合理的,它確實(shí)是在解決特定領(lǐng)域的特定問題。華為云低代碼平臺的建設(shè)初衷,就是用來解決華為云領(lǐng)域內(nèi)部的存量應(yīng)用想通過低代碼平臺提升開發(fā)效率的問題。
如何在盡量不犧牲跨平臺可移植性、盡量不犧牲應(yīng)用開放性的情況下建設(shè)華為云低代碼平臺?這就是本文要探討的問題。以下內(nèi)容,我們將華為云領(lǐng)域存量應(yīng)用的業(yè)務(wù)需求為線索,分析這些業(yè)務(wù)需求背后的實(shí)質(zhì)問題,討論用什么樣的技術(shù)方案去應(yīng)對這些問題,以及用什么樣的平臺架構(gòu)去承載技術(shù)方案,最后講講建設(shè)過程中我們所踩過的坑。
華為云 CRM 系統(tǒng)的低代碼需求分析
華為云內(nèi)部有一個 CRM 客戶關(guān)系管理系統(tǒng),這個系統(tǒng)已經(jīng)開發(fā)完成并且上線運(yùn)行,屬于存量應(yīng)用。由于后面不斷有新的需求,需要開發(fā)新的頁面,而那些新的頁面又跟原來的頁面非常相似,所以重復(fù)性的開發(fā)工作比較多,于是 CRM 的開發(fā)人員就想利用低代碼平臺來搭建新頁面。
由于新的頁面跟原來的頁面非常相似,CRM 的需求其實(shí)是想將原來的頁面封裝成可配置的頁面模板。這樣在面對新需求時,只需在低代碼平臺里配置一下頁面模板就能產(chǎn)生新的頁面,不用再重復(fù)開發(fā)。可配置的頁面模板也是由 CRM 開發(fā)人員在低代碼平臺搭建而成,而產(chǎn)生的新頁面則必須提供源代碼,以便與 CRM 原系統(tǒng)一起編譯構(gòu)建,組成一個完整的應(yīng)用,如下圖所示:
左圖是開發(fā)人員日常使用的 IDE(Visual Studio Code),低代碼平臺作為 IDE 的插件嵌入到 IDE 里。開發(fā)人員在平臺里通過可視化方式搭建頁面,保存頁面的時候平臺會生成頁面的源代碼(中圖),與原來純手寫的代碼一起編譯生成應(yīng)用(右圖)。這里的可視化搭建相當(dāng)于部分代替了原本需要手寫代碼的工作。
CRM 低代碼需求背后的實(shí)質(zhì)問題,其實(shí)是 ProCode 與 LowCode 的混合開發(fā)。ProCode 就是我們傳統(tǒng)意義上的高代碼開發(fā),即所有代碼都是純手寫的,而 LowCode 就是借助可視化工具搭建頁面,只需編寫少量代碼。所謂的高低代碼混合開發(fā)就是:在本地 IDE 里,有些場景直接手寫代碼,有些場景則用可視化工具搭建,生成代碼到本地工程?;旌祥_發(fā)的目的,仍然是想充分利用低代碼平臺的能力,提高開發(fā)階段的生產(chǎn)效率。
華為云 DevOps 系統(tǒng)的低代碼需求分析
再來看一下華為云另一個領(lǐng)域的低代碼需求,這個需求來自 DevOps 系統(tǒng)。在 DevOps 流水線上,我們允許用戶添加自定義的插件,這個插件能讓用戶干預(yù)構(gòu)建和部署過程。
在使用插件前,需要通過一些頁面來配置插件的參數(shù),而這些頁面當(dāng)前是由 DevOps 團(tuán)隊(duì)開發(fā)。為了減輕團(tuán)隊(duì)的負(fù)擔(dān),他們希望借助低代碼平臺的能力,讓用戶在 DevOps 網(wǎng)站上直接搭建頁面,頁面保存后同樣生成源代碼,集成到 DevOps 系統(tǒng)里。這個需求與 CRM 不同之處有三點(diǎn):
- 目標(biāo)用戶不同
- CRM 是 CRM 系統(tǒng)的開發(fā)人員使用低代碼平臺搭建系統(tǒng)頁面,DevOps 則是 DevOps 系統(tǒng)的用戶使用低代碼平臺搭建插件配置頁面。
- 嵌入方式不同
- CRM 是在 IDE 里嵌入低代碼平臺,屬于線下開發(fā)。DevOps 則是在 DevOps 網(wǎng)站上嵌入低代碼平臺,屬于線上開發(fā)。
- 技術(shù)棧不同
- CRM 采用 Angular 技術(shù)棧,DevOps 采用 Vue 技術(shù)棧。所以在 CRM 低代碼平臺搭建頁面所用的組件,必須是 CRM 系統(tǒng)當(dāng)前使用的 Angular 組件,而 DevOps 則是 Vue 組件。CRM 低代碼平臺生成的源代碼,必須是 Angular 技術(shù)棧,而 DevOps 則是 Vue 技術(shù)棧。如下圖所示:
如果僅僅是生成不同技術(shù)棧的源碼,相信很多低代碼平臺都能做到,但是我們面對的是不同技術(shù)棧的組件。比如一個按鈕,CRM 是用 Angular 開發(fā)的,DevOps 是用 Vue 開發(fā)的。兩個技術(shù)棧開發(fā)的按鈕,它們的屬性、方法、事件,甚至功能都不一定相同。打個比方,我們要給這個按鈕設(shè)置顏色,Angular 的屬性名稱叫 type,屬性的值是 success,而 Vue 的屬性名稱叫 color,屬性的值是 green,兩者并不匹配,如下圖所示:
所以,用 Angular 組件搭建的頁面,生成的 Vue 源碼是跑不通的。有些人可能會說,通過 DSL 做屬性映射,但是,如果功能不同,用 DSL 也無濟(jì)于事。那么,我們是不是我們要為不同技術(shù)棧,不同領(lǐng)域打造不同的低代碼平臺呢?
如果這樣做了,我們的成本會非常高,這個成本不僅包括軟硬件資源的投入,還包括研發(fā)和運(yùn)維的投入。而且各技術(shù)棧的低代碼物料的不通用,還會造成物料生態(tài)的割裂。因此我們的低代碼平臺方案要能夠支持不同的技術(shù)棧。
與傳統(tǒng) Visual Studio 可視化 IDE 的區(qū)別
把低代碼平臺嵌入到 IDE 里,通過可視化搭建生成源代碼,這與 20 年前流行的 Delphi/ C Builder/ J Builder/ Visual Studio 非常類似,當(dāng)然這些工具今天也還有人在用。
如下圖所示的 Visual Studio,左邊是可以拖拽的組件,中間上方是畫布,左邊的組件可以拖到畫布里,中間下方是代碼編輯區(qū)域,右邊是文件系統(tǒng)以及組件的屬性配置面板??梢?,雖然技術(shù)在向前演進(jìn),但是解決問題的思路又回到了原點(diǎn)。
兩者的相同點(diǎn)不難看出,都是可視化搭建,都會生成源代碼。要厘清兩者的區(qū)別,我們從以下三個維度去探討:
- 適用人群
- 低代碼平臺面向的人群,通常是不太懂編程的業(yè)務(wù)人員,或者能在幫助文檔下寫一點(diǎn)簡單的業(yè)務(wù)邏輯代碼,可視化搭建是他們的主要工作,寫少量的代碼只是輔助工作。在高低代碼混合開發(fā)的方案里,適用人群可分為兩類,一類是不太懂編程的業(yè)務(wù)人員,主要負(fù)責(zé)業(yè)務(wù)頁面的搭建,另一類是傳統(tǒng)的專業(yè)編程人員,主要負(fù)責(zé)業(yè)務(wù)邏輯的編寫,兩者協(xié)同開發(fā)一個應(yīng)用。Visual Studio 面向的是單一人群,即專業(yè)編程的開發(fā)人員,可視化拖拽組件只起到輔助作用,大部分時間他們都在編寫和調(diào)試代碼,獨(dú)立完成一個應(yīng)用的開發(fā)。
- 開發(fā)語言
- 低代碼平臺本身與開發(fā)語言無關(guān),即便在平臺上寫的少量代碼,也是前端通用的 JavaScript 語言。在高低代碼混合開發(fā)的方案里,不太懂編程的業(yè)務(wù)人員可能需要掌握 JavaScript 語言,用來編寫小部分的業(yè)務(wù)邏輯。另外,由于本文的低代碼方案可以生成不同技術(shù)棧的源代碼,所以專業(yè)編程人員需要掌握 Angular 或 Vue 等前端開發(fā)框架,才能調(diào)用低代碼平臺生成的源碼。Visual Studio 的可視化工具與 IDE 本身是天然集成的,一個子產(chǎn)品只支持一種開發(fā)語言,比如 Visual Basic 等。由于主流的前端框架并無統(tǒng)一的組件庫,Visual Studio 系列也就沒有諸如 Visual Angular 或 Visual Vue 的子產(chǎn)品,市面上也沒有類似成熟的面向前端框架開發(fā)的可視化 IDE,所以低代碼平臺的可視化搭建工具正好彌補(bǔ)這一空缺。
- 協(xié)同開發(fā)
- 這是高低代碼混合開發(fā)的方案特有的,Visual Studio 并不存在這種情況。因?yàn)榈痛a平臺雖然嵌入到 IDE 里,但仍然是獨(dú)立于 IDE 的模塊,其生成的源代碼需要跟本地純手寫的代碼協(xié)同工作,才能達(dá)成混合開發(fā)的目標(biāo)。協(xié)同的方式按模塊顆粒度分為兩種:一種是頁面級別,另一種是組件級別。頁面級別是指平臺生成的源代碼本身是一個頁面,本地工程通過路由直接跳轉(zhuǎn)到該頁面即可。這種級別與高代碼部分耦合度最小,也最容易集成。組件級別是指平臺生成的源代碼只是頁面的一個組成部分,需要跟頁面的其他純手寫的部分相互通訊、協(xié)調(diào)運(yùn)行。這種級別與高代碼部分耦合度非常大,但卻是混合開發(fā)的普遍場景,為此我們引入橋接源來解決協(xié)同開發(fā)的問題。
讓業(yè)務(wù)人員參與低代碼平臺開發(fā)
厘清兩者的區(qū)別之后,有人可能會指出:為什么讓業(yè)務(wù)人員參與混合開發(fā),全部由專業(yè)編程人員不行嗎?為什么要高低代碼混合開發(fā)?把開發(fā)流程復(fù)雜化,增加學(xué)習(xí)成本。有些人甚至還指出:LowCode 是行業(yè)毒瘤,它沒有任何未來,不值得我們?nèi)魏蔚耐顿Y和想法。讓不懂軟件開發(fā)的人可以寫代碼,這個想法就是錯的,而且錯的非常離譜。我們從以下兩個方面來回應(yīng)這些問題和說法:
- 數(shù)字化轉(zhuǎn)型需要業(yè)務(wù)人員參與
- 在企業(yè)數(shù)字化轉(zhuǎn)型的大背景下,應(yīng)用軟件呈爆炸式增長,開發(fā)應(yīng)用所需的專業(yè)人員或者供不應(yīng)求或者成本太高。于是降低開發(fā)門檻,讓懂業(yè)務(wù)的人員直接參與應(yīng)用構(gòu)建,就成了低代碼平臺的發(fā)展機(jī)遇。對于企業(yè)的存量應(yīng)用,仍然需要面對快速變化的業(yè)務(wù)需求,但這些應(yīng)用很難直接拋棄另起爐灶,改用低代碼平臺重新構(gòu)建。在專業(yè)編程人力不足的情況下,或者站在提高研發(fā)效率、降低維護(hù)成本的角度上考慮,都希望讓了解業(yè)務(wù)需求的業(yè)務(wù)人員能直接參與進(jìn)來,與專業(yè)編程人員一起更新這些存量的應(yīng)用。
- 低代碼平臺本質(zhì)上仍然是軟件開發(fā)工具
- 低代碼是一種軟件開發(fā)技術(shù),屬于軟件開發(fā)的高級語言。低代碼開發(fā)平臺通常整合了軟件開發(fā)所需的 IDE,有些還覆蓋軟件開發(fā)的全生命周期,提供數(shù)據(jù)建模與流程編排的能力,提供編程接口與系統(tǒng)集成的能力等。因此,低代碼與其他軟件開發(fā)技術(shù)一樣,值得我們投資和發(fā)展。低代碼開發(fā)平臺有自己專屬的開發(fā)語言,本身也能夠獨(dú)立完成應(yīng)用開發(fā),當(dāng)要與傳統(tǒng)的純代碼開發(fā)方式融合時,必然存在兩種開發(fā)語言的磨合。這種磨合是有成本的,但成本是可控的,特別是低代碼平臺直接生成源代碼,能極大方便本地調(diào)試與快速排查問題。
本文我們所討論的華為云低代碼平臺,不同于市面上常見的低代碼平臺,它不僅僅可以實(shí)現(xiàn)簡單的增刪改查頁面,還能支持復(fù)雜的 CRM 系統(tǒng)頁面開發(fā),還能生成 CRM 和 DevOps 不同技術(shù)棧的源代碼,并與原 CRM 和 DevOps 系統(tǒng)編譯集成。此外,它讓不懂編程的業(yè)務(wù)人員,與專業(yè)的開發(fā)人員一起協(xié)同工作,每個人負(fù)責(zé)各自擅長的部分,使得低代碼平臺能夠適應(yīng)更多的業(yè)務(wù)場景,覆蓋更多的行業(yè)領(lǐng)域,進(jìn)一步拓展了低代碼開發(fā)平臺的邊界。
2. 支持多技術(shù)棧與高低代碼混合開發(fā)
前面描述的 CRM 和 DevOps 系統(tǒng)的低代碼需求,除了高低代碼混合與支持多技術(shù)棧外,還有搭建復(fù)雜頁面的場景。企業(yè)級的 CRM 客戶關(guān)系管理系統(tǒng),如果不能像 Salesforce 一樣,把客戶關(guān)系管理系統(tǒng)都做透,通過配置化實(shí)現(xiàn)客戶側(cè)的定制,那么低代碼平臺很難通過可視化搭建,構(gòu)建復(fù)雜的 CRM 系統(tǒng)頁面。這也是大多數(shù)低代碼平臺為什么只專注于簡單的增刪改查頁面、或者流程審批電子流的原因。
然而這些問題如果沒有解決,那代碼混合開發(fā)就無從談起。企業(yè)內(nèi)部的存量應(yīng)用,不會因?yàn)槟阕霾坏骄秃喕撁?,畢竟業(yè)務(wù)邏輯的復(fù)雜度本身就無法忽視。
如何可視化搭建復(fù)雜的 CRM 系統(tǒng)頁面
這個問題我們給出的解決方案是:為用戶提供自助搭建可復(fù)用區(qū)塊的能力。
什么是區(qū)塊?我們來看下面這張圖,一個頁面通常由多個區(qū)塊拼接而成,每個區(qū)塊由一到多個業(yè)務(wù)組件構(gòu)成,每個業(yè)務(wù)組件都由基礎(chǔ)組件實(shí)現(xiàn)。在低代碼平臺里,基礎(chǔ)組件和業(yè)務(wù)組件都屬于原子組件,即不可拆分的、平臺內(nèi)置的、可以拖到畫布用于搭建區(qū)塊的組件。一個復(fù)雜的頁面通常可以拆分成若干個區(qū)塊,而區(qū)塊里面也可以嵌套區(qū)塊。只要讓用戶能夠復(fù)用已搭建好的區(qū)塊,復(fù)雜的頁面就像搭積木一樣,一層層摞起來即可。
我們用低代碼平臺搭建的頁面,會有一個描述頁面信息的文件,這個文件我們稱為頁面 Schema。如下圖左邊所示,可以看到這個頁面只包含兩個組件,一個是 Button,另一個是 Input。如果我們認(rèn)為這個頁面可以復(fù)用,我們就把它轉(zhuǎn)為區(qū)塊,這時候該區(qū)塊可以理解為:可配置的頁面。所以只需在頁面的 Schema 里面,增加區(qū)塊可配置的屬性,它就變成了描述區(qū)塊的 Schema。如下圖右邊所示,該區(qū)塊暴露了兩個配置項(xiàng):buttonSize 和 inputSize,分別對應(yīng)頁面包含的 Button 組件和 Input 組件的屬性。
以下這張圖展示了低代碼區(qū)塊的創(chuàng)建和消費(fèi)過程。首先,從新建空白畫布開始,用戶在畫布上拖拽組件、搭建區(qū)塊,接著添加區(qū)塊的業(yè)務(wù)邏輯。這里需要說明的是,我們提供了一些橋接方法,讓用戶可以調(diào)用高代碼的部分功能,即前面提到的高低代碼混合開發(fā)時,需要跟頁面的其他純手寫的部分相互通訊、協(xié)調(diào)運(yùn)行。第四步就是保存區(qū)塊,讓用戶選擇暴露的配置項(xiàng),即將區(qū)塊里所有組件的所有屬性都羅列出來,讓用戶選擇哪些屬性可以對外暴露,以便復(fù)用的時候進(jìn)行配置。第五步是發(fā)布區(qū)塊到物料中心,這樣下次新建頁面的時候,用戶就可以將這個區(qū)塊拖到畫布上,重復(fù)使用。
另外,由于我們的頁面和區(qū)塊都會生成源代碼。如果兩個頁面都用到同一個區(qū)塊,只是區(qū)塊的配置有所不同,那么在生成這兩個頁面源碼的同時,我們只會生成一份區(qū)塊源碼,然后讓這兩個頁面都引用這個相同的區(qū)塊。
如何在畫布里展現(xiàn)不同技術(shù)棧的 UI 組件
目前大多數(shù)的低代碼平臺為了方便實(shí)現(xiàn),都會限定畫布只支持一種技術(shù)棧,甚至一套組件庫。因?yàn)闆]有為用戶提供頁面源代碼的需求,搭建出來的頁面也不需要被其他系統(tǒng)集成,所以沒必要考慮多技術(shù)棧,用一套組件庫實(shí)現(xiàn)的成本是最低的。但是在華為云領(lǐng)域,面對 CRM 和 DevOps 的需求,我們要解決一個問題:如何在畫布里展現(xiàn)不同技術(shù)棧的 UI 組件?這個問題我們給出的解決方案是——使用 Web Component 技術(shù)。
上圖是 InfoQ 2020 年一季度,Web 開發(fā)相關(guān)的語言、標(biāo)準(zhǔn)、模式趨勢圖。可以看到 Web Component 處于中間位置,說明它已經(jīng)到了主流成熟階段,我們可以使用 Web Component 來解決跨技術(shù)棧問題。
目前三大主流前端框架:Angular、React、Vue 都已經(jīng)提供官方的 Web Component 轉(zhuǎn)換工具,我們利用這些轉(zhuǎn)換工具,就可以輕松的將各技術(shù)棧的 UI 組件,全部包裹成 Web Component,然后當(dāng)做 HTML 原生組件顯示到畫布上。需要指出的是,在生成的代碼里,我們引用的仍然是原始的 UI 組件,而不是 Web Component,這是因?yàn)楫嫴际窃O(shè)計態(tài),源碼是運(yùn)行態(tài),兩者是不同的。
當(dāng)前 Angular、React、Vue 是三大主流前端框架,未來又會出現(xiàn)什么樣的框架代替它們呢?我們不得而知。但是,不管未來的前端框架如何變化,我們都先用 Web Component 技術(shù)收斂,再通過 DSL(Domain Specific Language)機(jī)制發(fā)散,生成不同框架不同技術(shù)棧的源碼,這就是我們低代碼平臺的演進(jìn)策略:
我們來舉個 Vue 的例子說明 Web Component 方案。首先按照 Vue 官方的示例,定義一個 Vue 的組件,并注冊成為 Web Component。然后在畫布的 HTML 代碼里,我們聲明該 Web Component。假設(shè)這個 Vue 組件暴露的 options 屬性,是數(shù)組類型。我們知道,在 HTML 標(biāo)簽上,attribute 屬性只能設(shè)置為字符串或數(shù)值類型,因此,我們需要通過 JavaScript 腳本動態(tài)設(shè)置 options 的屬性值。如下圖所示:
接下來,我們將畫布的 HTML 內(nèi)容,用 AST 抽象語法樹,解析成一個 JSON 對象,即描述頁面的 Schema。從下面左側(cè)的圖可以看到,Web Component 組件的 options 屬性,它仍然是數(shù)組類型。然后我們通過 DSL 將頁面描述 Schema 轉(zhuǎn)換成 Vue 的源碼。從下面右側(cè)的圖可以看到,Vue 組件的 options 屬性,也仍舊是數(shù)組類型。于是我們發(fā)現(xiàn),從 Web Component 封裝組件開始,到生成 Vue 的源碼,整個過程中,給組件屬性設(shè)置的值是可以透傳的。
講到這里,大家可能會有疑問,為什么不能在 Vue 應(yīng)用中,直接使用 Web Component?以下列出 5 個理由,都摘自 Vue 的官網(wǎng)。簡而言之,就是 Web Component 技術(shù)還不夠強(qiáng)大,還不能完全替代現(xiàn)有的主流前端框架。
- 我們需要一個聲明式的、高效的模板系統(tǒng)
- 我們需要一個有助于跨組件邏輯提取和重用的響應(yīng)式狀態(tài)管理系統(tǒng)
- 我們需要一個能在服務(wù)器端渲染組件并在客戶端集成的高效方法
- 原生插槽沒有 Vue 的作用域插槽提供的組件整合機(jī)制
- 隱式 DOM scoped CSS 的自定義元素需要將 CSS 嵌入到 JS 中
生成源代碼 VS 運(yùn)行時渲染
要將畫布的描述生成不同技術(shù)棧的源碼,需要借助 DSL 機(jī)制。我們知道,用可視化方式搭建頁面,這個屬于設(shè)計態(tài)。將頁面描述文件通過 DSL 轉(zhuǎn)換成源代碼,然后編譯成可以運(yùn)行的應(yīng)用,這個屬于運(yùn)行態(tài)??梢赃@么說,DSL 的作用就是將低代碼從設(shè)計態(tài)轉(zhuǎn)換成運(yùn)行態(tài)。
但是,并不是所有低代碼平臺都會采用生成源碼的方案。事實(shí)上,有很多低代碼平臺采用的是運(yùn)行時渲染的方案,即將頁面描述文件直接傳給運(yùn)行時解析引擎,然后動態(tài)地渲染頁面。兩種方案各有所長,這里列出四個對比項(xiàng),如下圖所示:
第一項(xiàng),從性能上來看,運(yùn)行時渲染要用到解析引擎,這個肯定不如生成源碼編譯跑的快;
第二項(xiàng),由于運(yùn)行時渲染一般要求所有應(yīng)用都用統(tǒng)一的解析引擎,因此升級和修復(fù)平臺問題時,只需針對統(tǒng)一的解析引擎,其效率自然要高于每個應(yīng)用的源碼都需要重新編譯的方式;
第三項(xiàng),DSL 生成源碼天然具有很高的靈活性,只要用戶通過自定義 DSL,就能生成任意想要的源碼,因此擴(kuò)展性和開放性要比運(yùn)行時渲染高;
第四項(xiàng),開發(fā)和運(yùn)維的成本,兩者應(yīng)該相差不大。
3.低代碼平臺架構(gòu)開發(fā)及生態(tài)建設(shè)思路
低代碼平臺架構(gòu)設(shè)計
下圖是我們低代碼平臺架構(gòu)設(shè)計圖。先看底部的平臺服務(wù),我們會利用華為云原生的能力搭建后端服務(wù),會跟華為云的業(yè)務(wù)集成互通,比如跟我們的 Console 控制臺業(yè)務(wù)集成等。中間這塊是我們搭建平臺的核心,底層能力提供搭建頁面所需的基礎(chǔ)組件、移動組件和業(yè)務(wù)組件,提供頁面運(yùn)行用到的邏輯編排、流程編排。
往上一層是我們用來粘合各個模塊的平臺協(xié)議,這個頁面搭建協(xié)議是用來描述頁面信息的,而組件描述協(xié)議是用來給組件設(shè)置屬性的,物料資產(chǎn)協(xié)議是用來描述平臺用到的組件、區(qū)塊以及技術(shù)棧等信息,DSL 轉(zhuǎn)換協(xié)議則是用來將頁面或區(qū)塊 Schema 轉(zhuǎn)換成各技術(shù)棧的源代碼。
低代碼設(shè)計器是我們核心中的核心。首先從導(dǎo)入物料開始,中間是設(shè)計器的各個模塊,這些模塊會接入我們的平臺擴(kuò)展生態(tài),包括設(shè)計器的插件生態(tài),以及組件和區(qū)塊生態(tài)。最后,設(shè)計器還要負(fù)責(zé)生成源代碼,適配多終端多技術(shù)棧。再看上圖右下角,我們?yōu)榱藢?shí)現(xiàn)設(shè)計開發(fā)一體化,會提供在線設(shè)計平臺、提供支持高低代碼混合開發(fā)的 VSCode 插件。
平臺管理中心包含很多個中心,我們會先在物料中心挑選物料,然后打成物料資產(chǎn)包,再到平臺中心選擇剛打好的物料資產(chǎn)包,用來構(gòu)建各領(lǐng)域的平臺,接著在應(yīng)用中心管理各領(lǐng)域平臺生成的應(yīng)用。PaaS 平臺服務(wù)就是支撐我們?nèi)?gòu)建定制的平臺,提供平臺的運(yùn)行時服務(wù),另外還要支撐應(yīng)用的設(shè)計、開發(fā)、構(gòu)建、部署等。
有了 PaaS 平臺之后,我們就可以提供 SaaS 能力,既可以開發(fā)傳統(tǒng)的中后臺應(yīng)用,也開發(fā)華為云的 Console 控制臺應(yīng)用,甚至包括我們的 WeLink 移動端應(yīng)用、鴻蒙的多端應(yīng)用,然后再將這些應(yīng)用發(fā)布到我們的應(yīng)用生態(tài)市場。
低代碼平臺工作流程
下圖是我們的低代碼平臺工作流程。先從底部的低代碼后端說起,可以看到包含了前面說的物料中心、平臺中心以及應(yīng)用中心,這三個中心的后端都會連接一個數(shù)據(jù)中心,再由數(shù)據(jù)中心連接數(shù)據(jù)庫。平臺中心構(gòu)建出來的產(chǎn)物是低代碼平臺實(shí)例,VSCode 模塊根據(jù)模板工程把這個低代碼平臺實(shí)例打包編譯,構(gòu)建出一個 VSCode 插件。
物料中心會構(gòu)建出兩個產(chǎn)物,分別是物料資產(chǎn)包,以及搭建頁面所需的組件庫,它們會被低代碼平臺實(shí)例動態(tài)加載。每個平臺實(shí)例都是由設(shè)計器各個模塊組裝而成,這些設(shè)計器的模塊都來源于 npm 倉庫。每個平臺的實(shí)例都會請求對應(yīng)的平臺服務(wù),平臺服務(wù)提供各技術(shù)棧的頁面預(yù)覽功能,并且將生成的代碼提交到 Git 庫,再通過流水線發(fā)布應(yīng)用。
低代碼組件及區(qū)塊構(gòu)建流程
接下來我們看一下,物料中心的兩個產(chǎn)物,物料資產(chǎn)包和組件庫,它們是如何構(gòu)建的。如下圖所示,首先在物料中心的前端頁面,我們點(diǎn)擊構(gòu)建組件和區(qū)塊的按鈕,后端服務(wù)就會分別執(zhí)行構(gòu)建動作。先看左邊的組件構(gòu)建流程,我們會根據(jù)用戶選擇的技術(shù)棧,安裝相應(yīng)的 Web Component 組件庫,接著生成構(gòu)建代碼,代碼里引入用戶選擇的組件,并且按照物料資產(chǎn)協(xié)議,輸出該組件的描述信息,最后用 Rollup 打包構(gòu)建,生成組件庫。
再來看右邊的區(qū)塊構(gòu)建流程,我們先從數(shù)據(jù)中心里獲取區(qū)塊的 Schema,然后將 Schema 轉(zhuǎn)成區(qū)塊的描述信息,所有區(qū)塊的描述信息都會插入到 material.config 文件里,這個文件是按照物料資產(chǎn)協(xié)議進(jìn)行整理,包含平臺用到的組件、區(qū)塊以及技術(shù)棧等信息,這個文件最后被打到物料資產(chǎn)包里,并且保存到數(shù)據(jù)中心。
低代碼平臺項(xiàng)目開發(fā)流程
下圖我們低代碼平臺的項(xiàng)目開發(fā)流程。流程分三個角色,首先由項(xiàng)目經(jīng)理在平臺中心新建一個項(xiàng)目,然后設(shè)置可視化設(shè)計器的默認(rèn)配置,比如設(shè)計器用什么樣的主題,是深色還是淺色主題、設(shè)計器的面板有哪些插件、工具欄上有哪些按鈕等。接著設(shè)置平臺的默認(rèn)配置,比如使用自定義的 DSL 配置、設(shè)置代碼倉庫的地址、監(jiān)控應(yīng)用所需的埋點(diǎn)信息等,下一步是設(shè)置項(xiàng)目所用的物料,比如用什么技術(shù)棧的組件、用什么領(lǐng)域的區(qū)塊及模板。最后,項(xiàng)目經(jīng)理點(diǎn)擊構(gòu)建平臺的按鈕,等平臺生成后,就會通知開發(fā)人員登錄平臺網(wǎng)址,或者安裝 VSCode 插件。
開發(fā)人員可以在平臺上創(chuàng)建低碼或無碼應(yīng)用。如果是低碼應(yīng)用,則可以創(chuàng)建分支,支持多人協(xié)作;如果是無碼應(yīng)用,只需選擇模板,做一些簡單的配置。經(jīng)過一系列的迭代開發(fā),用可視化工具搭建完頁面,平臺就可以通過 DSL 生成代碼,最后用流水線部署應(yīng)用。在開發(fā)過程中,如果發(fā)現(xiàn)組件缺失,還可以通過專業(yè)前端開發(fā)相應(yīng)的組件,然后作為源碼物料導(dǎo)入到物料中心。另外,由于用戶也可以自行搭建可復(fù)用的區(qū)塊,將區(qū)塊作為低代碼物料發(fā)布到物料中心,形成物料的雙向流通。
4. 低代碼平臺建設(shè)過程中踩過的坑
第一個坑是關(guān)于 Vue 的 Web Component 轉(zhuǎn)換工具,我們使用 Vue3.2 版本推出的轉(zhuǎn)換工具。當(dāng)時發(fā)現(xiàn)一個問題,就是 Vue 組件轉(zhuǎn)換成 Web Component 之后,使用 JavaScript 腳本設(shè)置它的 property 屬性,只有第一次設(shè)置是生效的,后面再設(shè)置是無效的,請注意:這不是 HTML 標(biāo)簽上的 attribute 屬性。什么原因呢?
我分析了一下 Vue 的源代碼,原來轉(zhuǎn)換后的 Web Component 只在初始化時讀取 property 屬性,后面并沒有監(jiān)聽 property 屬性的變化。但是低代碼平臺就是要對畫布上的組件進(jìn)行屬性設(shè)置。
于是我就對轉(zhuǎn)換工具做了點(diǎn)改進(jìn),給轉(zhuǎn)換后的 Web Component 添加了一個方法,把要設(shè)置的屬性傳進(jìn)去,然后調(diào)用它內(nèi)部的 render 方法重新渲染組件,這樣設(shè)置就生效了。值得一提的是,我發(fā)現(xiàn) Angular 的 Web Component 轉(zhuǎn)換工具并沒有這個問題。
第二個坑是關(guān)于 VSCode 插件,我們是通過 VSCode 插件來實(shí)現(xiàn)高低代碼混合開發(fā)的需求,如下圖所示。
首先把低代碼平臺解耦,然后通過 VSCode 的 WebView 嵌入這個低代碼平臺。接著我們就發(fā)現(xiàn),平臺通過 WebView 發(fā)送網(wǎng)絡(luò)請求的時候,是不能攜帶 Cookie 的,這樣就導(dǎo)致我們的低代碼平臺無法進(jìn)行鑒權(quán)。
我從 VSCode 的 Github 上搜到這個問題的官方回復(fù),他們是這么說的,WebView 沒有 host 主機(jī)的概念,它只是在渲染一個 HTML 文檔,并不是你想要訪問的網(wǎng)頁,所以不會有 Cookie 和 LocalStorage 的概念。那我們該怎么辦?
由于 VSCode 它本身自帶 Node.js 客戶端,于是我們就想到,把這個 Node.js 客戶端當(dāng)做代理服務(wù)器,轉(zhuǎn)發(fā) WebView 的請求。當(dāng)后端服務(wù)返回生成的源代碼后,再借助 Node.js 客戶端將源代碼寫入到本地工程。這樣,就實(shí)現(xiàn)了高低代碼混合開發(fā)的基本功能。最后我們還需要在 VSCode 里,實(shí)現(xiàn)內(nèi)置的賬號登錄功能,這樣才能讓請求帶上 Cookie,完成整個平臺的鑒權(quán)。
5. 低代碼平臺的相關(guān)問答
以下問答系演講結(jié)束后根據(jù)聽眾的反饋整理的,選取一些有代表性的問答分享給大家:
- 對于接口請求渲染數(shù)據(jù)的,這種是如何實(shí)現(xiàn)的?
- 在頁面描述 Schema 里除了描述頁面信息,還有一個 Datasource 對象。Datasource 對象里新建一個數(shù)據(jù)源對象,描述接口請求數(shù)據(jù)的參數(shù)。頁面描述 Schema 通過 DSL 生成代碼時,單獨(dú)生成一個數(shù)據(jù)源的 JS 文件。JS 文件里 export 導(dǎo)出一個對象,對象的每個屬性都是一個單獨(dú)的數(shù)據(jù)源對象。每個數(shù)據(jù)源對象有 fetch 獲取數(shù)據(jù)等方法,以及其他數(shù)據(jù)源相關(guān)配置項(xiàng)。每個 fetch 方法內(nèi)部是將該數(shù)據(jù)源的參數(shù)傳給統(tǒng)一的獲取后臺數(shù)據(jù)的方法。給每個需渲染數(shù)據(jù)的組件配置數(shù)據(jù)源對象,生成的代碼包含雙向綁定數(shù)據(jù)。在頁面加載的時候,就調(diào)用數(shù)據(jù)源對象的 fetch 方法,給雙向綁定的數(shù)據(jù)賦值。
- 頁面代碼編輯出來后,持續(xù)維護(hù)這塊如何考慮的?方案是什么?
- 通過 DSL 將頁面描述 Schema 生成源代碼,這個過程是單向的。單向意味著生成的源代碼是只讀的,不可以編輯,只能被調(diào)用。如果對生成的源代碼改動,后續(xù)保存頁面生成代碼會覆蓋改動。持續(xù)維護(hù)還是要走持續(xù)改進(jìn)和提升頁面搭建能力的方式。高低代碼混合的特點(diǎn),就是低代碼可以通過橋接方法調(diào)用高代碼。用戶在頁面搭建時通過橋接方法,直接調(diào)用本地相對路徑的 JS 文件。將包含復(fù)雜邏輯等需要經(jīng)常維護(hù)的業(yè)務(wù)代碼包含在這些 JS 文件里。低代碼搭建平臺始終主要做頁面、區(qū)塊等 UI 界面的搭建工作。
- 高低代碼混合開發(fā)中的橋接源可以理解為回調(diào)嗎?
- 低代碼平臺生成的源代碼存放在用戶指定的本地工程專有目錄下,與高代碼部分是隔離的。高代碼可以直接用相對路徑的方式導(dǎo)入或者引用低代碼生成的模塊,而低代碼要導(dǎo)入或者引用高代碼的模塊,則需借助橋接源。比方說,在低代碼平臺里定義一個橋接源,里面聲明高代碼模塊的相對路徑,或者 npm 依賴包的名稱。這樣在低代碼平臺的自定義方法里就可以導(dǎo)入高代碼的模塊或者引用 npm 依賴包。而傳統(tǒng)的低代碼平臺,如果當(dāng)前提供的 API 接口不能滿足業(yè)務(wù),需引入第三方模塊,一般要先提需求,等開發(fā)完成后重新部署,再告知調(diào)用方式,整個鏈路會比較長。
6. 總結(jié)和展望
華為云的低代碼平臺要想持續(xù)發(fā)展,就需要建設(shè)物料生態(tài)、平臺生態(tài)以及應(yīng)用生態(tài)。只有物料的雙向流通才能促進(jìn)物料生態(tài)的發(fā)展,除了組件、區(qū)塊之外,我們還要為用戶提供自助搭建可復(fù)用模板的能力,進(jìn)一步豐富物料的生態(tài)。我們要做低代碼的 PaaS 平臺,利用 Web Component 技術(shù)以及 DSL 機(jī)制,為不同領(lǐng)域,比如辦公、零售、制造等,去創(chuàng)建定制的平臺。不僅要能夠生成桌面端應(yīng)用、移動端應(yīng)用,還要能夠生成鴻蒙的多端應(yīng)用,擴(kuò)展我們的應(yīng)用生態(tài)。
低代碼的物料生態(tài)、平臺生態(tài)、應(yīng)用生態(tài),這三者不是互相孤立的,而是相輔相成的。我們要把這三個生態(tài)圈打通,形成合力,這樣下面這張圖,就不是三個圈,而是三個環(huán)環(huán)相扣的 8。
據(jù) Gartner 預(yù)計,到 2024 年,低代碼應(yīng)用開發(fā)將占應(yīng)用開發(fā)總數(shù)的 65% 以上,將有 3/4 的大型企業(yè)會使用至少 4 個低代碼平臺進(jìn)行 IT 應(yīng)用開發(fā)。
另外,據(jù)不完全統(tǒng)計,目前國內(nèi)外大大小小的低代碼廠商至少有 60 個以上,而且大廠商內(nèi)部的低代碼平臺可能還不止一個。作為企業(yè)數(shù)字化轉(zhuǎn)型的工具引擎之一,低代碼平臺必然會被越來越多的企業(yè)所了解并加以使用,使用的場景也會越來越豐富。我們在開發(fā)或使用低代碼平臺時,要清楚低代碼不能一蹴而就,而要持續(xù)迭代、持續(xù)演進(jìn),要不斷探索和拓展低代碼開發(fā)平臺的邊界。
作者簡介
莫春輝,華為云主任工程師,華為云 Web 能力中心低代碼平臺負(fù)責(zé)人,AUI 前端框架負(fù)責(zé)人。2014 年加入華為,帶領(lǐng)團(tuán)隊(duì)開發(fā) HAE(Huawei Application Engine)前端框架,其底層核心是自研的面向?qū)ο蟮?JS 類架構(gòu),支持與 AngularJS 相似的數(shù)據(jù)雙向綁定,可靈活配置的系統(tǒng)、頁面、組件生命周期,以及支撐華為內(nèi)部 IT 應(yīng)用的高性能 UI 組件庫。2017 年 HAE 演進(jìn)成為基于 Vue 的 AUI 框架,并以落實(shí)體驗(yàn)一致性規(guī)范的要求,在公司各 BET 領(lǐng)域大規(guī)模推行,2019 年底發(fā)布了全新架構(gòu)支持跨端跨框架的 AUI 3.0 版本,2020 年推出同時支持 Vue 2 和 Vue 3 的 AUI 4.0 版本,2021 年開始負(fù)責(zé)華為云低代碼平臺研發(fā)工作。
除前端框架開發(fā)、低代碼平臺研發(fā)外,還參與制定公司的前端開發(fā)規(guī)范,擔(dān)任信息技術(shù)任職的評委、JavaScript 認(rèn)證考試專家組成員,系公司開源能力中心 Vue SIG 組織 Maintainer 成員。
活動推薦
2022 年 6 月 10-11 日,GMTC 全球大前端技術(shù)大會(北京站)2022 將再度與您相約!前端業(yè)務(wù)架構(gòu)、前端 DevOps、前端性能優(yōu)化、IoT 動態(tài)應(yīng)用開發(fā)、TypeScript、移動端性能與效率優(yōu)化、前端成長實(shí)戰(zhàn)、團(tuán)隊(duì)可持續(xù)建設(shè)、跨端技術(shù)選型等 15 個專題,最熱點(diǎn)的方向,解決你最關(guān)心的問題。更多精彩議題持續(xù)打磨上線中,點(diǎn)擊此處了解更多內(nèi)容。