漫談前端體系建設

發表於2017-08-10

前端體系建設從前端開始專職發展就慢慢開始演進了。過去,我們習慣描繪一些技術細節作為前端體系所需要的,而沒有看到其背後的連線,所謂建設之道,即是建立向前向後的連線。前端在專案研發中的上流是互動視覺,下流是後端研發。這兩個角色之間的連線對我們來說至關重要。

這就有兩個方面,一是團隊與團隊之間的體系,尤其是上下流團隊之間的連線。二是前端團隊之內的體系,可以理解為角色之中的連線。

與設計師的連線

對於前端的前端是互動視覺,互動視覺在我們固有的理解一定帶著『不可控』的因素,即便我們定了互動視覺標準。

沉澱元件體系標準

我們分解系統的基本互動邏輯,一定由基本元件構成。我們完全可以固化下來沉澱成基礎元件庫。對於基本元件而言,我們確定一個『可變』範圍,包括底色,邊框色,圓角,字型等,梳理出一套『樣式變數』。那麼就在可視範圍內,我們可以調整出多套基本互動視覺模板。

不同形態的產品使用者體驗心流是不同的,所形成的互動視覺會有所不同。因此,對於前端來說與之連線一定是在同一個互動視覺規範下。這個範圍的界定可以通過使用者體驗心流一致來判斷,比如操作控制類,資料展示類等。今天,設計師們一般會將產品設計理念沉澱成一套設計語言,如 antd 會針對後臺應用類。

這時,我們必須要考慮背後的問題,我們怎麼針對不同的互動視覺抽象元件。antd 背後的 rc-component 就高度抽象了元件行為,讓上層 antd 去選擇用怎樣的互動。形成很好的元件體系,也很方便的讓其它前端基於此新建一套設計語言。

因此,抽象互動的元件體系結合不同的視覺互動標準規範就可以形成一系列元件庫,從而構成前端元件體系,而其中的樣式部分經過我們的抽象可以成為主題配置的要素,最終形態就是主題配置平臺。當我們的業務選擇生成一套元件的時候可以同時生成互動所需要的元件模板,非常方便地讓視覺完成頁面和應用級別的工作。

v2-546b3663865753317636df6c5e89a175_bmaterial design 就是很好的 demo。google 設計師開發的基於 material 風格的 sketch plugin 意在生成複雜的 Material Design 風格的互動控制元件。更進一步,可以將 sketch 在生成模板程式碼。這是連鎖反應。

更好的相互理解

在與互動視覺的連線中,前端的工作很像是『翻譯』。但工程師本身對於設計,甚至美感是相對不擅長的領域,但我們在工作中常常遇到設計師的天馬行空,對於前端開發成本較高的情況。另外,還有很多設計師會以『技術先行』的方式嘗試自己的互動 demo。

在專業領域,比如資料視覺化,帶著資料研發流程在內,這時侯不只是單純的從視覺互動上考慮,而是從資料本身的角度結合視覺互動去幫助理解業務,從而設計一種合適的視覺化形態。

因此,對於角色本身來說,並不完全都是正向連線的關係。前端也有義務幫助設計師更好的理解頁面的構建方式,視覺化圖表的正常使用方式等。

與後端研發的連線

前端與後連線的是後端研發,現在應用為了高效的互動體驗已經極少使用同步請求,因此,我們與後端的連線主要在於非同步介面定義上,還有一部分是頁面初始化的頁面模板渲染兩個部分。

介面定義對於前後端之間是一份契約,將兩個角色團隊的人連線起來,高效協作。對於傳統前後端互動,為了並行開發的便利,會在專案前相互對介面進行約定,然後各自開發,最後在預發環境下聯調正式介面。這個過程有幾個問題。

資料模型

由於前端對於資料的理解不是基於底層資料,而是基於介面元素。儘管前後端對於介面的約定在專案一開始就會約定,但後端對於最終資料的來源存在不確定性。欄位及格式在總是會有不少調整,對於專案來說帶來的很多風險。

對於通用業務,前後端傾向於均抽象一套實體模型。那麼前後端只要維護這一套資料模型就可以實現無調整即可上線。這時配合 GraphQL 感覺會有『徹底』的前後端分離,更好的是非常適合來做資料適配。

單獨考慮資料適配層,對於前後端都可以來做這一層,需要做一些取捨。考慮到了釋出成本,資料、後端,前端釋出的成本中前端一定是最小的。一旦資料或後端出問題,前端可以快速適配作應急處理。因此,在現實當中,常常由前端來做一層的適配。

對於個性化業務,只能 case by case 來約定介面。這時,我們需要一個 Mock 介面的服務來作模擬介面,實現對線上介面的代理。通過平臺與本地工具無縫切換,同步這個過程。這麼做為了最小化聯調的時間。Easy Mock 平臺就是一個不錯的開源選擇。

跨端適配

由於不同的終端產品與研發的視角均不同,研發對於資料的理解也會不同。例如在無線端資料要求更精簡,而 Web 上一般沒有這樣的要求。

那麼我們想到對於底層資料都是相似的,但上層應用介面卻有差異。那麼,我們就讓原來面向應用的介面下沉形成的微服務,提高抽象性與穩定性。而在它的前端引入一層 BfF(服務於前端的後端)層。這種模式不會為所有的客戶端建立通用的介面,我們可以擁有多個 BfF,對應於 Web、移動客戶端等。

這一層的好處在於後端主要的關注點下沉到微服務架構,如果其中一個服務要遷移,那麼其中一個 BfF 就可以呼叫新服務,其它的保持不變。進一步提高了系統的解耦。

當然,這種模式的問題在於誰來維護 BfF 層。如果由後端來維護這一層那麼選用一種輕量級的語言會加快研發的效率,比如 PHP。如果由前端來維護這一層,那麼 Node 就非常適合。對於介面服務來說主要是高 IO 場景,正與 Node 優勢相匹配。這一選擇取決於團隊人員的配比。

模板管理

在過去介面服務還不多的情況,前後端主要的連線就在於模板。

對於後端來說會把系統變數直接寫在模板中,這對於前端維護來說就帶來了很多困難。對於前端來說,我們的指令碼與樣式的配置都在模板當中,常常因為發新版需要改地址。

對於耦合這麼嚴重的這部分。對於今天前端來說,已經慢慢找到自己的方法。就是通過 Node 來管理這個模板,將模板做成通用服務,後端會把系統變數傳送給服務,服務來完成後續的模板生成的工作。

這帶來的另一個好處是我們在做 SSR 時只需要將邏輯在這一層當中完成即可。

那麼,在理想情況下,我們會抽象一層『使用者體驗適配層』來做兩個工作,模板渲染與資料適配。這也是今天前端工作外沿的一個表現之一。對於後端來說,這一層相當輕,對於前端來說,這一層對於我們的連線顯得更加順暢。

v2-4ad78928743cd09d391c1e8cf4740d57_b穩定性保障

產品的資料化運營,我們都耳熟能詳,一般體現在運營效率的突破,商業模式的創新,客戶價值的提升等。

那麼再來看商業價值的背後是產品的穩定性,從產品角度穩定性鏈路是貫穿在互動行為的鏈路中。其中,一系列的互動行為引發了一系列的前後端的請求,後端與資料庫的請求。我們稱之為端到端的穩定性保障。

端到端的監控,除了我們必須要制定好詳細的規範以外,重點看的是每條鏈路上的效能,並能夠在最短的時間內知道哪裡的鏈路出問題了。做法比較簡單,前端傳送的每一個請求都會帶上一個 traceId,這樣就可以馬上跟蹤到是後端的哪一個類,並關聯到是哪些 SQL 的呼叫,哪些關聯表位於哪些機房中。

正因為有這樣的全鏈路保障,我們不同角色之間相互獨立,又相互連線在一起。成為產品保障的基石。

更好的相互理解

誠如上述與設計師一樣,與後端研發合作同樣涉及到如何幫助後端更好的理解前端。

前端與後端的理解差異往往來自於資料介面上。後端是伺服器環境,前端是瀏覽器環境,往往兩者處於的立場不同,不能感同深受。前端考慮的是使用者體驗增強,因此,為了在資料傳輸大小與次數上都有自己的考慮,這時候與後端的工作就有關聯。

因此,現代前端也更傾向於將抹平這一層差異的工作放到『中間層』來做。為了做更極致的前後端解耦與效能優化。

前端自我連線

回到最後前端自身的連線。從蒸汽時代的工業革命到今天資訊時代,經歷了工具的演變。從工作效率、穩定性上提升了幾個層級。今天的前端界的工程革命,對於知識的半衰期來說,大概只有2-3年時代。同樣經歷了標準的創新,工具的創新等。

在這個時代下我們怎麼做自我連線呢。

架構選型

前端從過去的頁面級發展到今天的應用級,我們看待系統的複雜度也在與日俱增。技術架構與團隊息息相關,對於技術架構定義兩個關鍵詞 面向未來面向場景

如果今天業務面向場景幾乎是靜態頁面,那麼我架構的選擇重點會在重模板語言設計上,可以方便作自動化構建。

而今天,我們的產品是重展示的模組化介面,我的技術架構基礎是 React,React 代表了今天趨向於應用級的發展的前端需要完整的聚合元件概念。但上層會有兩套模板,一套是以 flux 為基礎理念,保證在複雜狀態下的資料流的控制,一套以 observable 為基礎理念,保證了其使用簡單,方便後端工程師上手。在不同場景和規模下使用。

當然,架構的變化對於前端來說只有幾年時間,我們應對的是高速發展的網際網路和其人機互動的形式。如果說我們可以在一套系統中針對不同的技術架構作共存,以及迭代方案。技術本身就有了流動性,技術發展不會在團隊中停滯。

因此,在框架能力差不多的情況,我不會混用,只會用其一,但也不會排斥未來轉型。我考慮的是如何來控制它們的迭代。

流程標準化

經歷過那個工具匱乏年代的前端工程師,前端工程專案通常沒有構建、除錯、測試工具,只會涉及到簡單的腳手架和壓縮打包功能。可以提供給前端最常見的是在工程下新建 makefile 設定一些命令,指令碼語言通常會選擇 shell 或 python。

直到 Node 興起了之後,前端工程化算是真正開啟了大門。我們看到了從 grunt 開始基於 node 環境的流程化工具的興起,直到發展到今天大行其道的 webpack。我們一直會緊跟時代變化對流程工具做改變,但流程本身的邏輯 **腳手架、構建、除錯、測試到打包釋出** 這些從來沒有變過,或一直在我們的預想之中。

對於今天的本地流程化工具,我所需要的功能可能一直是這些,但背後一定需要它具有可擴充套件性,本地線上打通的能力,以及資料監控。

v2-6951e34cf705e709a2579a37f8d65d40_b

1. 可擴充套件性

命令列工具天性就非常容易封裝,我們常用的 git 就有流程擴充套件 gitflow。那麼流程化工具的擴充套件能力在於它每一個環節具備重寫能力。比如 Web 流程和無線流程本身的工具體系有所不同,但流程是一樣的,我們可以通過不同的外掛化能力去擴充套件。

漫談前端體系建設2. 去中心化

去中心化意味著可以本地工作,專注在個人工作上。而線上意味是多人協作的終端,可以看到不同人的結果。

如本地 git 就有一個 repo 來做管理,在沒有 push 到 remote 伺服器時我們一直可以做到本地管理。到線上,我們有類似於 github 這樣的平臺,可以做 issue,project 管理,這是一個 team 級別一起來做的事。

對於本地流程化工具來說,打包釋出就需要和線上作一個關聯,因為釋出行為本身是一個團隊協作的一部分,我們有必要統一管理,那麼作為本地工具,我們知道它具有的便利性,那麼線上平臺則保證的是團隊的協同。

3. 資料監控

對於 git 來說,它本身就是一個資料庫。而本地流程化開發工具只是一個命令列工具,資料上報的意義在於在服務端統一每一個環節的效率,我們可以怎麼優化這些環節。

自我理解

v2-5a9fcf37e63c369ae82d5d6742feef89_b我們有介面邏輯,屬於非邏輯沉澱。我們有資料邏輯,屬於邏輯沉澱。我們在處理它們的理解與產品理解之間的誤差。最終的人機互動介面展現的是前端的工作,我們的工作有極大的不確定性。把這種不確定性儘可能安定下來,是我們的工作。

總結

全文述說最基本原則是 不同角色之間的連線減少約定,加強標準建設;前端自身則是首要提高流程化管理的能力,同時不斷從場景中抽象應用架構的能力。研發流程體現的是效率與穩定的平衡。總體架構的取捨體現在 團隊規模與業務的發展速度:

1. 每一個環節都在儘可能小的粒度上,遵從 Unix 原則

2. 每一個環節具備定製能力,有進一步生態化的能力

3. 每一個環節規定輸入輸出作規範化沉澱

4. 鏈路連線的工作讓系統來完成

5. 全鏈路都都有資料支援,不斷調整其中的取捨

在每一個角色階段,都會有自己的服務,如 Demo 管理平臺,PRD 管理,自動化測試系統等。但它們之間都是分散的,並沒有針對專案的角度是整體審視。因此,在整體研發的體系建設上,全鏈路研發管理集中在流程管理系統之中,會把其中核心的流程抽取出來形成一套系統。

在大規模企業中職能團隊就非常之多,這樣就面臨著職能團隊與職能團隊,職能團隊與上下流團隊之間的平衡。我們既要考慮人在環境中的創造性,又要考慮重要建設的成本,所有的架構一定是時時刻刻講求當前效益最大化。

相關文章