本文是架構師 2018-10 月刊的卷首語,歸納於自筆者的技術之路系列文章,也是對 現代 Web 開發基礎與工程實踐 中的內容提點總結。
資料浪潮之間的前端工程師
十年來,波瀾壯闊的移動網際網路浪潮促進了 Web 技術的迅猛發展,隨著瀏覽器效能、網路頻寬等基礎設施的提升,Web 也能夠承載起包含複雜互動、視覺化、計算邏輯需求的富客戶端應用。同時 RN, Weex, 小程式為代表的混合式開發日趨成為與 Android、iOS 原生開發並肩的開發模式之一;而 VR, AR, IoT 等新的互動方式或者媒介也正步入消費級市場,原本前端之間的隔閡逐漸消亡,我們慢慢進入了大前端的時代。筆者認為大前端不僅僅是橫向地指泛 GUI 的接入端,縱向來看基於 Node.js 的全棧開發、中臺化背景下的 BFF 模式,微前端架構等也是大前端的有機組成,也給予了前端工程師更廣闊地舞臺。
DT 時代
繁多的網際網路接入端也催生了海量資料的產生與富集,開啟了所謂的 DT 時代;我們利用雲端計算、人工智慧、深度學習等手段分析資料、利用資料,將資料作為燃料,賦能新的商業模式。演算法、資料與工程是優秀的智慧化產品不可或缺的組成部分,前端作為與資料的產生源頭–使用者最貼近的部分,也在未來全連線的架構裡迸發出更絢爛的火花。
前端首先能夠通過埋點、監控等方式,採集到使用者行為、偏好、應用執行狀態等豐富的資料,我們團隊(阿里南京 NUE)也自研了高效能 Web 實時錄屏與回放的產品,賦能客戶服務的體驗提升與前端開發者的線上除錯。基於資料與演算法,前端也可以設計更好地人機互動模式,譬如人臉識別的登入方式、智慧問答客服、智慧音響的語音控制;資料視覺化也是典型的前端與資料水乳交融的領域,ECharts, G2, D3, Three.js 等框架允許我們更便捷、友好地、深刻地展現統計資料、關係資料、地理空間資料、時間序列資料與文字資料等多源異構資料集。此外,TensorFire, TensorFlow.js 等深度學習框架利用客戶端的 GPU 計算能力, pix2code 或者 SketchCode 利用演算法來快速實現原型介面,Guess.js 能夠幫助優化構建好的包體與智慧新增預抓取策略。
值得一提的是,近幾年區塊鏈技術的爆炸性發展也促進了 Web 3.0 概念的思辨與實踐,IPFS, Ethereum dApp 等工具或者開發框架允許我們便捷地編寫去中心化的 Web 應用。Web 3.0 提倡以人為本,看重隱私,反壟斷網路,旨在更開放的網路上進行集體貢獻並實現共享利益,這也給予了前端開發者更多樣化的未來。在 DT 時代,我們或許不能站在浪潮之巔,但是隨波逐流順勢而下也可以找到自己的位置,或高或低地翱翔於天。
資料流驅動的介面
資料的核心操作是儲存與計算,傳統的 Web 應用因為單執行緒與離線不可用性往往是即用即走,而 PWA 這樣的應用設計模式,提倡使用 Service Worker 新增離線支援,充分利用 IndexDB, CacheAPI 等進行靈活地資料儲存與檢索,並且給予使用者貼近原生的體驗。另一方面,Web Worker, WebAssembly 等亦從不同的方面釋放或者增強前端的計算能力,不僅使得 Web 中執行高效能要求的應用或動畫,也可以借鑑邊緣計算的理念,未來將更多地資料聚合、計算的邏輯前移。感性地說,當資料逐漸活躍、富集,如百川匯海,自然需要流動起來。
廣義的資料流驅動的介面有很多的理解,其一是介面層的從以 DOM 操作為核心到邏輯分離,其二是資料互動層的前後端分離。在 jQuery 時代,我們往往將 DOM 操作與邏輯操作混雜在一起,再加上模組機制的缺乏使得程式碼的可讀性、可測試性與可維護性極低;隨著專案複雜度的增加、開發人員的增加與時間的推移,專案的維護成本會以幾何級數增長。隨著 ES6 Modules 的廣泛應用,我們在前端開發中更易於去實踐 SRP 單一職責原則,也更方便地去編寫單元測試、整合測試等來保證程式碼質量。而像 React、Vue 這樣現代的檢視層庫為我們提供了宣告式元件,託管了從資料變化到 DOM 操作之間的對映,使得開發者能夠專注於業務邏輯本身。並且 Redux, MobX 這樣獨立的狀態管理庫,又可以將產品中的檢視層與邏輯層剝離,保證了邏輯程式碼的易於測試性與跨端遷移性,促進了前端的工程化步伐。
近兩年來隨著無線技術的發展和各種智慧裝置的興起,網際網路應用演進到以 API 驅動的無線優先(Mobile First)和麵向全渠道體驗(Omni-channel Experience Oriented)的時代,BFF 這樣前端優先的 API 設計模式與 GraphQL 這樣的查詢語言也得到了大量的關注與應用。GraphQL 是由 Facebook 開源的查詢語言標準,包含了資料格式、資料關聯、查詢方式定義與實現等等一攬子東西的資料抽象層。GraphQL 並不能消融業務內在的複雜度,而是通過引入靈活的資料抽象層,儘量解耦前後端之間的直接關聯或者阻塞;在滿足日益增長不斷變化的 Web/Mobile 端複雜的資料需求的同時,儘可能避免服務端內部邏輯複雜度的無序增加。
工程化與微前端
程式設計生態往往會經歷三個階段:湧現大量工具的原始階段、複雜度提升後引入大量設計模式的框架階段、具有更好的團隊組織與協調機制的工程化階段。大部分時候我們談論到工程化這個概念的時候,往往指的是工具化;工具的存在是為了幫助我們應對複雜度,在技術選型的時候我們面臨的抽象問題就是應用的複雜度與所使用的工具複雜度的對比。而工程化,即是面向某個產品需求的技術架構與專案組織,致力於儘可能快的速度實現可信賴的產品;儘可能短的時間包括開發速度、部署速度與重構速度,而可信賴又在於產品的可測試性、可變性以及 Bug 的重現與定位。
在 DT 時代中,很多公司也開啟了大中臺,小前臺的戰略,即在中臺中完成一系列可開放能力的聚合,賦能前端業務,加速迭代開發。工程化是中臺化的基石,通過制定標準化的規範、基於後設資料的可配置業務流等,完成前後端的業務銜接;而統一的服務中臺又是在複雜業務場景下實現微前端/微服務的保障。微服務與微前端,都是希望將某個單一的單體應用,轉化為多個可以獨立執行、獨立開發、獨立部署、獨立維護的服務或者應用的聚合,從而滿足業務快速變化及分散式多團隊並行開發的需求。微前端的落地,需要考慮到產品研發與釋出的完整生命週期;我們會關注如何保證各個團隊的獨立開發與靈活的技術棧選配,如何保證程式碼風格、程式碼規範的一致性,如何合併多個獨立的前端應用,如何在執行時對多個應用進行有效治理,如何保障多應用的體驗一致性,如何保障個應用的可測試與可依賴性等方面。
最後,對於個人而言,隨著團隊技術棧的相對穩定,關注點也會逐步從元件庫的建設變化為基礎設施的建設,從考慮選擇怎樣的技術棧到如何在立足某個技術棧更好地服務於業務規劃。這個知識爆炸與終身學習/碎片化學習為主的時代,我們要進行更有效地學習,從知識廣度,程式設計能力與知識深度等方面提升自己。