天天看點

如何設計同時支援低碼和源碼的應用架構

作者:閃念基因
如何設計同時支援低碼和源碼的應用架構

開發者經常會诟病低代碼帶來的開發靈活度不足的問題,但業界對于低代碼的投資和探索卻一直沒有中斷過。對于開發者而言,低代碼始終有一種“教開發者如何開發應用”的感覺,并且業務需求往往複雜多變,是以很難不被喜好自由度的開發者抱怨。我相信,沒有能夠解決一切問題的銀彈,有的隻不過是需求場景和解決方案的錯配。

在雲音樂,我們一直在探索低代碼開發與源碼開發的平衡,既為業務傳遞提供高效的傳遞能力,同時為開發者提供低門檻且靈活的用來響應業務需求變化的開發能力。 雲音樂是一個擁有 11 年曆史的業務,很多的系統建構在複雜的既有體系中,很難采用單一方案一蹴而就地解決曆史積弊。是以,在為業務提供标準能力的同時,技術架構上的可持續性就顯得特别的重要。

基于源碼提供低代碼開發能力

Tango 是我們針對雲音樂現有業務的特點和開發者的實際訴求建構的一套基于源碼的低代碼解決方案。支援在現有的代碼庫和業界主流的開源架構基礎上提供低代碼可視化開發能力。我始終相信,代碼庫是技術團隊的核心資産之一,同時也相信,源代碼可以為開發者提供最保險的逃生艙。通過建構基于源碼的低代碼開發能力,無論是對業務的可持續疊代,還是對于開發者習慣的漸進式培養,都會更為可靠且可持續。

Tango 引擎的核心是建立在對源碼的 AST 操縱的基礎上。AST 的全稱是 Abstract Syntax Tree,是程式設計語言文法的抽象表示,可以将任意的代碼片段轉為 AST 結構樹。Tango 通過将使用者的操作轉為對 AST 樹節點的讀取和修改,實作對使用者低代碼開發的支援。

通過 AST 來修改源碼在很多的架構和庫中都有實作,例如前端典型的 uglify, eslint plugin 等庫都是基于 AST 操縱實作的。但隻是通過操縱 AST 來實作代碼生成和修改,問題顯然會非常的複雜,因為很難預測和應對應對開發者程式設計過程中的随機性。

如何設計同時支援低碼和源碼的應用架構

圖:Tango 基于 AST 驅動的原理示意圖

通過應用架構統一前端程式設計範式

針對程式設計過程的随機性,我們可以對前端應用的開發行為進行标準化限制,TangoBoot 是我們面向雲音樂的 web 應用開發場景建構的一套标準化的前端應用開發架構,它建構在主流的開源架構基礎上。TangoBoot 提供了一套标準的前端應用開發範式,包括應用的建構、啟動、視圖渲染、狀态管理、異步資料請求、微前端等。

如何設計同時支援低碼和源碼的應用架構

圖:TangoBoot 通過建構标準應用範式統一應用的開發過程

TangoBoot 同時支援在低碼開發環境和源碼開發環境中使用。 對于源碼開發者而言,可以輕松的掌握 TangoBoot,并用于實際的應用開發,并且支援快速低成本的與現有代碼庫內建在一起。對于低代碼開發者,Tango 引擎提供了基于 TangoBoot 的标準可視化搭建能力,引擎按照既定的規範生成和修改應用代碼,實作低代碼搭建過程。

如何設計同時支援低碼和源碼的應用架構

圖:在 Tango 低代碼設計器中開發應用

更少的視圖和邏輯代碼

通過 TangoBoot,可以讓開發者少寫約 50% 的視圖和邏輯代碼。 TangoBoot 的核心是采用響應式狀态管理(Reactive States)+響應式視圖(Reactive View)的方式來降低開發者對于視圖層渲染邏輯的了解門檻:當綁定到視圖的資料變化的時候,視圖就會自動更新。對于開發者而言,無需掌握複雜的程式設計文法,即可快速的面向業務場景建構應用程式。下面我們以一個代辦清單應用為例,使用者可以輸入代辦事項,點選确認按鈕,将計數器添加到頁面中。

如何設計同時支援低碼和源碼的應用架構

圖:使用 TangoBoot 和 Dva 分别實作 Todo App 的代碼對比

前端響應式狀态管理的實作

TangoBoot 提供的狀态管理基于一個基本的事實,當綁定到視圖的資料變化的時候,視圖就會自動更新。這個被後端同學認為理所應當的事,使用 redux 等前端架構來實作卻并不容易。不妨用一個更簡單的例子來示範,下面的代碼簡單的表明了在視圖中消費變量 counter.count 計數器,并通過點選按鈕實作 counter.count 變量自增,而視圖會自動觸發重新渲染,無需開發者關注底層實作細節。

const counter = store({ count: 1 });
const Page = view(() => {
  return (
    <div>
      <span>{counter.count}</span>
      <button
        onClick={() => {
          counter.count++;
        }}>
        add
      </button>
    </div>
  );
});
           

響應式狀态管理意味着,當綁定視圖的變量的值變化時,視圖自動重新渲染,以反映其變化。當對象的屬性被修改時,它會查找屬于該(對象,屬性)對的所有元件并重新渲染它們 —— 是的,非常符合開發者想象中的那樣。這種狀态管理方案無論是對前端開發者,還是後端開發者都更易于掌握,也是 Tango 建構簡單易用低代碼開發能力的基礎。

讓我們看看如何來實作這一過程。為了建構(對象、屬性、元件)關系,我們必須知道 counter 和 Page 在渲染期間使用哪些對象和屬性。開發者可以通過看一眼代碼就很快識别到這些資訊,但架構卻不能。我們需要讓架構知道對象的屬性何時發生變化,以便從儲存的關系中收集相關元件并渲染它們。這兩個問題都可以通過 ES6 代理來解決。

import { saveRelation, renderCompsThatUse } from './reactiveWiring';

export function store(obj) {
  return new Proxy(obj, traps);
}

const traps = {
  get(obj, key) {
    saveRelation(obj, key, currentlyRenderingComp);
    return Reflect.get(obj, key);
  },
  set(obj, key, value) {
    renderCompsThatUse(obj, key);
    return Reflect(obj, key, value);
  },
};
           

簡單解讀下上面的代碼,store 代理攔截所有屬性擷取和設定操作,并分别建構和查詢關系表。還有一個問題是,traps 裡的 get 中的 currentRenderingComp 是什麼?我們如何知道目前正在渲染哪個元件?這就是 view 發揮作用的地方。

view 包裝了一個元件并使用簡單的邏輯來檢測其渲染方法。它在渲染時為元件設定 currentRenderingComp 标志。這樣我們就擁有了在 get 中建立關系所需的所有資訊。對象和屬性來自 get 函數的參數,元件是由 view 包裹的 currentRenderingComp。

通過上面的代碼,我們可以簡單的了解到如何實作一個基本的響應式狀态管理庫,但真實的場景往往比這複雜非常多,有衆多的邊緣情況和設計決策需要權衡。篇幅原因,這裡不再詳細介紹相關的細節,具體的内容可以參考 The Ideas Behind React Easy State 一文進行詳細的了解。當然,TangoBoot 的狀态管理實作也并沒有重複造一個新的輪子,而是選擇了更加成熟的社群方案,感興趣的同學可以參考 Observer-Utility 和 React-Easy-State。

使用服務函數調用後端接口

對于後端資料請求,Tango 為低碼和源碼開發場景提供了統一的開發範式 -- 服務函數調用。開發者無需關注請求實作的細節,而是通過配置優先的方式進行接口的資料請求,使用者的配置資訊會自動生成對應的服務函數調用邏輯。可以通過下面這段簡單的代碼示例 TangoBoot 的資料請求的配置。值得說明的是,TangoBoot 本身并沒有實作請求庫,而是直接在 axios 和 fetch 的基礎上進行了封裝,使得開發者完全可以使用自己習慣的方式進行代碼編寫。

如何設計同時支援低碼和源碼的應用架構

圖:使用 TangoBoot 發起資料請求和使用 axios 發起資料請求的的對比

當使用者執行某個服務函數的時候,Tango 将會使用服務函數的配置資訊通過 TangoGateway 将請求代理給對應的後端服務,并由後端服務進行相應的處理。這意味着,開發者可以非常輕松的在低碼環境中執行資料請求,而無需考慮源碼開發過程中複雜的鑒權、跨域、Mock 等相關的問題。

如何設計同時支援低碼和源碼的應用架構

圖:在 Tango 低碼環境中發起資料請求的執行鍊路

前端架構的挑戰

與業界大部分低代碼方案不一樣的是,Tango 并沒有發明一個全新的文法或程式設計語言,而是選擇了在社群标準的基礎上建構了低代碼引擎,并基于低代碼引擎建構了低代碼可視化設計器。考慮到雲音樂的業務現狀,為了融合現有的源碼開發過程和低碼開發能力,通過建構标準化的應用架構 TangoBoot 來統一低代碼開發和源碼開發過程,使得開發者無論是在低碼環境還是源碼環境都可以使用一緻的概念和範式開發應用。

面向未來,完全私有化的方案不可避免地存在着各種難以預測的可維護問題。對于 Tango 而言,就像現階段的大語言模型 Copilot,我更願意将其看作為一個開發者的輔助開發工具,可以降低開發者去開發和傳遞應用的門檻,讓跨技能棧的開發者也可以去傳遞典型的前端應用,而不是完全取代開發過程。

關于 Tango

開源進展

目前 Tango 低代碼引擎已經開源,仍然持續更新中,可以通過如下的資訊了解到我們的最新進展:

  • 開源代碼庫:https://github.com/NetEase/tango
  • 文檔位址:https://netease.github.io/tango-site/

作者:景莊

來源-微信公衆号:網易雲音樂技術團隊

出處:https://mp.weixin.qq.com/s/cpMjMXg7RLUh7XQpxVtFrg

繼續閱讀