世界是平的嗎?——從不同角度看前端
在遠(yuǎn)古的時(shí)候,人們對(duì)世界的認(rèn)知有限,以為天圓地方,世界是平的。后來,隨著科技進(jìn)步,大家都知道了地球的形狀,它不但不平,還有山川河流,沙漠海洋。
這很大程度上說明了人所處的環(huán)境對(duì)認(rèn)知帶來的影響,我們看待一件事物,從不同的視角去看,所得到的結(jié)論未必是相同的。
前后端協(xié)作的研發(fā)模式
上個(gè)月有一天很奇妙,早上有個(gè)之前部門的同事跟我探討研發(fā)模式,下午有個(gè)之前同事跟我吐槽前后端溝通成本高,晚上部門群里又有人提到視圖跟服務(wù)的關(guān)系,這么多巧合,值得在這個(gè)事情上寫點(diǎn)東西。
回頭看看這幾年,前端領(lǐng)域在搞的一些東西,除去具體的框架和組件庫,大致有這么些:
- 工程體系:構(gòu)建、發(fā)布、持續(xù)集成、容器管理
- NodeJS實(shí)現(xiàn)的框架、中間件、服務(wù)
- 圍繞前后端協(xié)作展開的一系列探索:BaaS、BFF、函數(shù)計(jì)算、GraphQL等
- 跨端實(shí)踐
這里面,有很大一部分話題是跟廣義的“前后端分離”有關(guān)的。站在今天這個(gè)時(shí)間回頭看,看得到每個(gè)方向的進(jìn)展,人們逐步習(xí)慣了前端有類型、有構(gòu)建、有包管理、有測(cè)試、有持續(xù)集成等等,前端開發(fā)逐步成為了相對(duì)嚴(yán)謹(jǐn)?shù)能浖a(chǎn)活動(dòng)。
另外一方面,當(dāng)我們把目光投向整個(gè)系統(tǒng)的時(shí)候,我們也可能發(fā)現(xiàn)研發(fā)流程的一些狀況。現(xiàn)在,一個(gè)典型的系統(tǒng),它的開發(fā)過程可能是這樣的:
- 前端獨(dú)立系統(tǒng)
- 后端獨(dú)立系統(tǒng)
- 中間有類似 swagger 的接口約定機(jī)制
前端有一套東西,完整的組件化、構(gòu)建、發(fā)布、依賴管理,后端也有一套,但是,兩者的結(jié)合往往是很松散的,整個(gè)鏈路很長,在流程上會(huì)有很不協(xié)調(diào)的感覺。
形成這個(gè)問題的原因是整個(gè)研發(fā)過程兩極分化,斷裂得很厲害,前后端的唯一橋梁是接口,并且,一般來說,當(dāng)一端產(chǎn)生了變更之后,很難有一種自動(dòng)同步機(jī)制去影響另一端,通常只能去掃描發(fā)現(xiàn)這些不一致的地方,并且手工做調(diào)整。

整個(gè)系統(tǒng)的研發(fā)流程好比細(xì)胞的增殖過程,拉伸成了兩塊,中間的維系很脆弱。
從架構(gòu)治理角度看,“兩頭大”的情況是需要去控制的,只有主從結(jié)構(gòu)的形態(tài),在流程上才是簡(jiǎn)單的。對(duì)這么一個(gè)問題,業(yè)界存在不同的探索途徑:
- 前端主導(dǎo)的流程
- 前后端合一的研發(fā)模式
- 后端主導(dǎo)的流程
前端主導(dǎo)的流程
前端主導(dǎo)的流程是怎樣的呢?
這個(gè)流程的要點(diǎn)是讓后端退化為配置,借助 BaaS,F(xiàn)aaS 這樣的基礎(chǔ)架構(gòu),舍棄后端的構(gòu)建與發(fā)布環(huán)節(jié),工程上就會(huì)成為這樣的形態(tài):

這樣,后端成為了一種流程無感的環(huán)節(jié),前端是整個(gè)項(xiàng)目的集成方,后端成為了一種配置化的東西,成為了前端體系下的附屬。這種模式是否能行得通,最大的先決條件就是后端接口是否穩(wěn)定。在互聯(lián)網(wǎng)企業(yè)中,尤其是領(lǐng)域模型關(guān)聯(lián)關(guān)系較少的情況下,有不少系統(tǒng)在往這個(gè)方向走。
- 輕量業(yè)務(wù):完全 BaaS
- 較重的業(yè)務(wù):通過 Faas 調(diào)用微服務(wù)
前后端融合的模式
另外,業(yè)界也存在一些探索,希望把前后端的開發(fā)過程融合。我們所要解決的問題一直都是變更的同步,那么,如果一個(gè)項(xiàng)目的前后端都位于一個(gè)工程中,天然對(duì)同步也是有利的。

這種模式下,實(shí)際上是通過兩者合一的方式,縮短了前后端研發(fā)過程之間的距離和溝通成本,在此基礎(chǔ)上,還可以有另外一些手段作優(yōu)化,比如:
- 根據(jù)后端的服務(wù)生成前端的調(diào)用接口,并且附帶 TypeScript 類型描述
- 根據(jù)后端的單元測(cè)試生成前端的 mock 數(shù)據(jù)
前后端合一的工程中,最大優(yōu)勢(shì)就是后端接口的變更一定會(huì)自動(dòng)傳導(dǎo)到前端,服務(wù)接口字段變更會(huì)導(dǎo)致:
- 前端類型校驗(yàn)出錯(cuò)
- 前端的單元測(cè)試出錯(cuò)
并且,由于二者合并在一個(gè)項(xiàng)目中,改了一邊忘記改另一邊的情況也更不容易發(fā)生,兩者的發(fā)布也是在同一個(gè)流程中。
這種模式普適性相對(duì)好,但是對(duì)人員全棧技能的需求是要稍高的。
后端主導(dǎo)的流程
后端主導(dǎo)的流程又是怎樣的呢?
這個(gè)流程是反過來,盡可能地把視圖弱化,讓它成為后端模型的附屬物。在很長的時(shí)間里,這種形態(tài)一直是主流,只是可能具體形式上歷經(jīng)了一些演變。
后端主導(dǎo)的流程推行到極致,工程上就會(huì)成為這樣的形態(tài):

在這種路徑下,視圖成為了領(lǐng)域模型的附屬物,當(dāng)領(lǐng)域模型產(chǎn)生變動(dòng)的時(shí)候,視圖自然跟著變動(dòng),即使是視圖之間的聯(lián)動(dòng)關(guān)系,也是經(jīng)由領(lǐng)域模型之間的關(guān)系控制的。
這樣,前端成為了一種流程無感的環(huán)節(jié),后端是整個(gè)項(xiàng)目的集成方,前端成為了一種配置化的東西。這條路徑的先決條件是前端的模式相對(duì)固定,可窮舉,不會(huì)存在太多的個(gè)性化交互。通常,會(huì)有一些企業(yè)軟件的研發(fā)過程采用這種模式。這種模式對(duì)人的需求是領(lǐng)域建模能力較強(qiáng)。
組件化
研發(fā)流程也會(huì)導(dǎo)致實(shí)施過程中的一些細(xì)節(jié)差異,比較典型的就是組件化。
組件化是一個(gè)很久遠(yuǎn)的名詞了,自從工業(yè)革命開始,標(biāo)準(zhǔn)化的可替換部件逐步成為了生產(chǎn)效率的基石。在前端領(lǐng)域,這個(gè)詞最近也在越來越多地被提到。然而,對(duì)這個(gè)詞如何理解,不同的人有不同看法。
組件化的實(shí)施路徑是需要隨著技術(shù)方案的不同而調(diào)整的。剛才我們提到了三種研發(fā)模式,組件化實(shí)施方案也會(huì)有不同的模式。
- 前端不分層的組件化體系
- 前端分層的組件化體系
- 端到端組件化體系
前端不分層的組件化體系
這個(gè)體系是當(dāng)前前端最熟悉的路徑了,在實(shí)現(xiàn)者眼里,后端退化為接口,不關(guān)心數(shù)據(jù)之間的關(guān)系。

前端分層的組件化體系
另外存在一種實(shí)踐,在前端又引入分層,把真正的視圖和邏輯、數(shù)據(jù)等等隔離,這個(gè)時(shí)候,視圖部分實(shí)際上就可以變得非常薄,整個(gè)視圖部分的組件化,實(shí)際上類似于模板化。

端到端的組件化體系
如果考慮到實(shí)施的原則盡量簡(jiǎn)單,端到端組件是最容易理解,集成難度最低的一種形態(tài)。
在此模式下,單個(gè)組件應(yīng)當(dāng)包含視圖到服務(wù)端模型的整個(gè)鏈路。組件只跟某個(gè)具體的領(lǐng)域模型交互,并不關(guān)心其他組件的存在。單個(gè)或者多個(gè)組件,都能夠直接運(yùn)行。頁面成為一種通用的容器,把它們集成起來。

舉例來說,一個(gè)人員列表與詳情的頁面,如果實(shí)現(xiàn)為兩個(gè)組件,其功能分別如下:
- 列表組件
- 綁定了某個(gè)條件的人員列表查詢服務(wù)
- 詳情組件
- 綁定了某個(gè)具體的人員
這兩個(gè)組件應(yīng)當(dāng)是互相獨(dú)立的,在這種情況下頁面對(duì)它們的集成,包括兩者之間的聯(lián)動(dòng)關(guān)系,都是在領(lǐng)域模型(后端)上定義的,然后借助特定的機(jī)制,自動(dòng)就形成了聯(lián)動(dòng)關(guān)系。
從實(shí)現(xiàn)角度,這種組件內(nèi)部也可能接近于其他形態(tài)的組件實(shí)現(xiàn)方式,比如,組件內(nèi)部可以有分層,當(dāng)某組件被注冊(cè)的時(shí)候,它所屬的各層是分別注冊(cè)的。
需要注意的是,以上三種實(shí)踐并非直接對(duì)應(yīng)于第一部分我們提到的三種模式,它們是存在并存關(guān)系的,可以根據(jù)業(yè)務(wù)場(chǎng)景去適當(dāng)進(jìn)行混合。
小結(jié)
不考慮實(shí)際情況的技術(shù)選型是非常可怕的,并不存在通吃一切的技術(shù)方案,每種方案都有它的邊界。在實(shí)踐過程中,可以問問自己,我們正在做的這個(gè)系統(tǒng):
- 前端跟后端,哪塊更模式化?
- 與其他系統(tǒng)的集成方式是怎樣的?
- 視圖變更與復(fù)用程度如何?
- 人員的技能狀況如何?
- 視圖是“寫”出來的,還是“配置”出來的?
對(duì)這些問題的不同回答,都會(huì)影響到具體實(shí)施路徑的選擇。
幾年前,左耳朵耗子說了一句話,被很多人圍攻:“CSS不就是配置文件么?”從前端角度看,這句話簡(jiǎn)直大逆不道。但是,在某些場(chǎng)景下,當(dāng)我們把視野放在全局,到整個(gè)系統(tǒng)層面,CSS確實(shí)就可以被認(rèn)為是一種配置文件。不但如此,在有些場(chǎng)景下,連視圖的大部分都能算是配置文件了。
有的時(shí)候,我們也會(huì)看到一些探索,比如說,嘗試用可視化的方式去配置視圖層,在這種情況下,視圖確實(shí)就是由:
- “寫”出來的基礎(chǔ)組件
- “拼”出來的大塊模板
這兩類部分所組成的,這也是我個(gè)人在很多情況下很傾向于“模板型”視圖層框架的原因。
我們繞了很大一圈,離題萬里,那么,世界是平的嗎?
可以試試閉著眼睛去摸一下立體的地球儀,感覺是怎樣的?但實(shí)際上這是一種錯(cuò)覺,因?yàn)榈厍騼x對(duì)比例進(jìn)行了夸張,以青藏高原的海拔,相對(duì)地球半徑而言,其高度差簡(jiǎn)直可以忽略不計(jì)。所以,宏觀角度看,世界確實(shí)就是平的。
橫看成嶺側(cè)成峰,遠(yuǎn)近高低各不同。不識(shí)廬山真面目,只緣身在此山中。
——蘇軾
后記:本文是2019年1月19日在網(wǎng)易前端技術(shù)大會(huì)上的分享。整篇文章想要解決的問題是給出一些建議:前端技術(shù)選型應(yīng)當(dāng)結(jié)合業(yè)務(wù)場(chǎng)景,社區(qū)方案只是自己的工具,技術(shù)人員不應(yīng)當(dāng)變成工具的奴隸。在不合適的場(chǎng)景下,即使是很著名、流行的工具,也應(yīng)當(dāng)果斷舍棄。
分享過程中,我提到自己給自己打的標(biāo)簽是缺乏情懷的工業(yè)黨,所謂工業(yè)黨,在我看來,有另外一個(gè)名詞可以對(duì)等,那就是生產(chǎn)力至上。一個(gè)生產(chǎn)力至上者的態(tài)度是這樣的:竭盡全力尋找出限制生產(chǎn)力發(fā)展的因素,找到最適合的生產(chǎn)方式:
- 如果生產(chǎn)工具(技術(shù)框架)是瓶頸,那就改造生產(chǎn)工具;
- 如果研發(fā)流程是瓶頸,那就重塑研發(fā)流程;
- 如果人是瓶頸,那就改變?nèi)恕?/li>




















