京東運營活動頁的基石 —— 通天塔
1 前言
通天塔是京東商城內部提供給運營用以快速搭建活動頁面的平臺,自2015年第一版上線以來,已歷經多個618和雙十一的考驗。通天塔的誕生是歷史的必然,當業務發展到某一程度,有限的開發人力和冗長的開發流程已無法滿足蓬勃發展的業務需求,而這對電商企業來說尤為明顯,根據部分資料統計,2017年11月JD APP內的日均活動線上量達4000多,雙十一期間日均活動量達到5000~6000,要是完全依靠傳統的開發模式,那開發小哥哥們可以不用下班了。
近年來,頁面搭建平臺在諸多公司如雨後春筍,據瞭解阿里內部類似的系統就多達10多個,不能說是重複造輪子,每個系統面向的使用者群體,涉及的業務複雜程度是不盡相同的。接下來,我們一起來看看,JD商城體系對於活動搭建平臺的訴求是什麼。
2 起點和方向
這一節我們從產品和互動角度概括得來看下平臺的設計。從產品角度,它的目標使用者是各個事業部的運營,其中也包括事業部中具有開發能力的前端。搭建頁面的操作應該是“傻瓜式”的,即不用懂任何技術相關的知識就能完成一個頁面的搭建,同時我們又不能把系統做的過於封閉,系統仍需開放出一定的入口去支援擴充套件的功能實現。

操作介面
從互動角度上看,提供一個視覺化的頁面編輯平臺是目前比較理想的方案。因為目標使用者大部分是沒有程式設計基礎的運營,所以整個介面的核心操作就是拖拉和填表,系統底層封裝和實現了模板的拼裝和渲染,資料分發和功能邏輯等,對使用者來說,整個系統是一個黑盒,使用者和系統之間的橋樑就是視覺化的操作介面。這種模式的優勢就是保證了系統是穩定且可控的,缺點就是一旦出現不符合預期的行為,運營就會跑來問你。
上一節提到系統不能是封閉的,因為運營時不時會提出一些個性化的需求,小到某些樣式的更改,大到新功能的實現。一方面部門的開發人力有限,另一方面不是所有的需求都要做進系統內部。為了滿足這類的需求,系統內要開放出一定的入口,從視覺化介面的角度,目前主要是通過自定義模板的方式來實現。因為某些因素,我們向程式設計人員提供了富裕的自由度,我們沒有限制技術棧的使用,系統只負責載入使用者編寫的模組。當然這種自由度,會帶來一定的風險,據以往來看,頁面出問題絕大部分的原因是因為自定義程式碼導致的。

自定義程式碼
雖然通天塔是一個頁面搭建平臺,但同樣也是一個釋出平臺,使用者可以便捷地點擊發布按鈕更新頁面,那麼如何保證頁面上線後的質量和可靠性是需要考慮的問題。質量包括頁面的內容是否完整,樣式是否正常,資料是否有效等,而可靠性包括頁面不能有白屏,連結是否有效,點選位是否符合預期等。這裡面涉及的細節非常多,解決方案概括性的可以歸納以下幾點:
1. 儲存,釋出前檢驗配置資訊是否完整,有效(連結地址是否可達,優惠券id是否可用等)。
2. 提供真實的預覽頁面供使用者檢查。
3. 資料不完整導致樣式受影響時,會過濾相應的樓層。
4. 靜態降級H5頁用作兜底頁面。
5. 頁面測速平臺,異常監控平臺提供質量服務。

平臺藍圖
縱觀整個平臺的藍圖,實現開放化是平臺的最終目標。需要開放些什麼,怎麼開放是我們一直以來思考的問題。目前,我們正在做的是將模板依賴的資料可配置化,第三方資料服務的註冊與接入,制定DSL統一模板定義,封裝基礎元件和基礎服務可供呼叫,以及JD React的深度整合。
3 技術實現
考慮到整個系統十分龐大,涉及的面也非常廣,不妨我們先從資料提供側(視覺化搭建頁)的實現開始分析,以後的篇幅會繼續講解系統的其他部分實現。
3.1 技術選型

技術選型
視覺化的技術選型算中規中矩,用了React相關的全家桶。選用React,一方面是看好社群的發展,一方面也為了能與JD React進行深度整合。

層次劃分
從層次上講,整個系統劃分為Store,UI層,資料處理層,控制層,Service層。UI層是比較輕量的,理想的UI層只需負責介面的顯示,而大部分的業務邏輯我們剝離到了Service層,其中控制層主要負責邏輯的流程控制。雖然編寫程式碼的時候會比較繞,但整個專案的結構會變得非常清晰,對功能進行擴充套件的時候也非常方便。
3.2 元件結構

元件結構
整體的結構還是比較簡單的,對於配置面板,我們劃分成通用面板和自定義面板。稍後我們可以看到,對於簡單的配置資訊是可以轉化成配置表的形式,配置表的好處是可以通過介面下發,與系統是解耦的。通用面板負責解析這份配置表,而自定義面板處理複雜業務,實際使用的時候,我們在自定義面板中也會複用通用面板的能力。
3.3 模板定義
視覺化平臺的基本單位是模板,模板又涉及三個維度:佈局,樣式和資料。在視覺化層,我們把這三個維度定義成了三份描述檔案:

描述檔案
這三份檔案最終會被編譯成一個描述模板的json物件,並隨介面下發:

編譯流程
這裡需要說明的是視覺化所用的模板和樣式與生成端M頁所用的模板和樣式,不是同一套,目前還是由兩個團隊分別去開發和維護的。在規劃的時候,設想過複用同一套模板元件,因為視覺化和M頁面向的使用者,場景都不一樣,模板元件內部需要維護2個狀態(預覽態和真實態)。一來對模板元件的開發人員要求比較高,二來對現有元件的改造成本大,評估下來,目前我們只能選擇其他優先順序更高的需求。
現在我們來看下模板的三個維度在視覺化中是如何處理的:
3.3.1 佈局
佈局需要考慮的是與資料的繫結,預覽區對於使用者的輸入需要有反饋,比如更改了一個標題顏色,預覽區是要能夠體現出顏色的變化,這種互動對使用者來說是友好的。我們設定預覽區的模板是獨立且無互動的,從實現方案來說選擇有很多,考慮開發簡單,且與React融合度好,我們選擇用JSX來寫佈局。

JSX模板解析
效能上,我們在包裝元件(viewInstance)中,判斷了資料是否變化,減少了不必要的更新操作。
3.3.2 樣式
樣式的處理比較簡單,這裡就直接貼程式碼了。

樣式解析
3.3.3 資料
資料是視覺化平臺的核心,資料層面要考慮的問題主要有以下幾點:
1. 配置面板與模板資料之間的關係是什麼?
2. 資料更新如果實現?
3. 資料驗證如何實現?
以往的配置面板都是依靠人力去開發的,即使有健全的元件庫支援,也需要花精力去組裝和除錯。我們可以站在更高的層次,把共性的東西抽象出來,比如表單元件與資料的繫結關係,資料更新的邏輯,驗證的邏輯等等,最終的產物就是一份配置描述檔案(下右圖)。

配置表對映
有了配置檔案,我們還需要一個解析器去實現表單項的生成,這個解析器就是上文中提到的通用面板。

元件結構
整個資料的更新和驗證也是自動完成的:

資料流圖示
4 未來要做的工作
要真正做好這個系統不易,從系統上線以來,已歷經一次大的技術改版,這篇文章介紹的已經是改版之後的內容。通過改版,我們解決了一部分的問題,為未來的發展鋪平了道路,但距離期望還有段距離,這裡我列舉出未來的規劃方向以供參考:
1. 複用模板元件,在元件內部實現預覽態與真實態的切換。
2. 模板與視覺化系統的解耦
3. 建立模板市場
4. 依賴jdReact實現一份程式碼多端複用