前端架構——從入門到微前端 讀書筆記
最近,前端圈中出現(xiàn)一個一個熱詞”微前端“,作為一個前端菜鳥,也來趕趕集。
所以,我讀了黃蜂達老師寫的《前端架構——從入門到微前端》一書。

概要
這本書主要講的是, 對于一個前端項目,在項目不斷迭代的過程中,對整個項目的工作流、構建流,已經(jīng)對一個項目的技術選型,已經(jīng)后期的基礎設施的建設進行了一個講解。并且,在后面第九到第十章中,講解了微前端。
最近今年里,前端成為軟件行業(yè)中一個獨立的職業(yè),從小的創(chuàng)業(yè)公司到大的上市公司,都有自己的前端技術人員甚至是一個團隊。在業(yè)務不斷變化中,代碼量越來越大,工程化成為必然的問題。這本書,對于目前前端的現(xiàn)狀,以及前端的工程化進行的詳細的講述。但作為前端萌新 的,只能領略一二,在以后的項目中需要慢慢理解。下面是我讀書后一些記錄。
前端項目的構建,工作流,以及架構實施
因為要關注行情,了解市場的需求,我偶爾回去逛逛boss直聘等招聘網(wǎng)站。發(fā)現(xiàn),現(xiàn)在的前端已經(jīng)像過去一樣,只會寫樣式、html或者切圖。幾乎每個招聘上都會有以下這樣的要求:
掌握一門后端語言
有navtive開發(fā)經(jīng)驗更佳
了解前端工程化 會使用 webpack gulp這樣的工具
……
如今的前端已經(jīng)變成軟件行業(yè)中重要的一部分。
所以,逃不開的就是,工程化,質量管理,架構等一系列問題。
1. 軟件架構的一些基本常識
首先,一個架構我們要去考慮什么
系統(tǒng)間的關系,需要明確當前的系統(tǒng)與其他系統(tǒng)間的關系是調用關系還是依賴關系等
系統(tǒng)內的關系,系統(tǒng)內各個子系統(tǒng)的之間,接口是什么,他們是如何通信的
規(guī)范和原則,用于開發(fā)人員的溝通的基礎,這是一個架構中必須包含的一項,可以是文檔或者口頭約束。
其次,在架構中要明確需求,及其利益相關人員或者部門,可能不同人員或者部門關注的點不用。例如:
產(chǎn)品或者業(yè)務負責人員關心的是能否按時上線已經(jīng),未來如何進程產(chǎn)品的迭代
項目經(jīng)理確定項目計劃和人選
開發(fā)人員,關心架構的演進和維護
測試人員,是否可以自動測試,或者將測試自動地集成到項目中
對于前端人員,我們還要明確,瀏覽器支持的范圍以及,移動端可以支持的版本等。
常見的架構風格
- 分層風格
一個系統(tǒng)由多層構成,每個層有不同的模塊
- MVC架構風格
這個風格強調職責分離,將軟件系統(tǒng)分為三個基本部分: 模型(Model), 視圖(View),控制器(Controller)。視圖和模型通過控制器進行交互,保證用戶界面與書模型是一致的。
- 發(fā)布-訂閱風格
這種風格可以成為稱作基于事件的架構風格。其最大的好處是代碼上的解耦。在前端的開發(fā)過程中,為了解耦不同UI組件的依賴,會經(jīng)常采用這種模式。
- 管道和過濾器
這是一種適合于處理數(shù)據(jù)流的架構模式,它將每個步驟都封裝在一個過濾器組件中,數(shù)據(jù)通過相鄰過濾器之間的管道傳輸。最典型的管道過濾器架構師UNIX shell的設計。 在類Unix系統(tǒng)中,使用’|‘作為管道符號,當我明年需要編寫復雜的shell腳本來處理內容時,便會使用這個符號。例如’ ls-l|grep.jpg’,便會先執(zhí)行l(wèi)s-l命令,再將結果交由grep程序,查找以.jpg結尾的文件名。
前端架構的層次設計
下面是一個圖(原圖參考書籍:p:22)

2. 前端架構的實施過程
光有概念還不行,需要把它們轉化為一套可以落地的理論。首先看下我們一個企業(yè)項目的進行周期
下圖是一個項目的啟動和實施周期(p:28)

了解了開發(fā)周期,就需要通過每個周期中不同的特點進行資源的調配。
例如:當我們進入業(yè)務回補期,我們當前要面對第一次deadline,這個時候雖然業(yè)務開發(fā)已經(jīng)進入正軌,但是于是工作優(yōu)先級,變成了業(yè)務第一,工作第二。
或者,當我們部署上線成功,并且正常進行業(yè)務迭代時,我們就需要考慮提升團隊能力來獲取更好的開發(fā) 效率等等。
3. 重要的工作——設計工作流和構建流
在我剛步入工作的時候,接觸的項目是多頁面應用,用jquery然后html5 ,就是手寫文件,在瀏覽器上打開文件,沒寫一行CSS就需要手動刷新一下。當項目完成是,就交個后端,后端會用腳本拷貝到nginx相應 的目錄下。
后來接觸到vue,知道了有cli這么個東西。
到目前為止,市場上出現(xiàn)”云效“等軟件。
在這個過程中,我?guī)缀醪恢缹τ谝粋€前端來說什么是運維,或者構建流。
這本書中用了兩大章的內容,來說工作流和構建流,下面我分開說一下。
工作流
工作流,就是在工作中可以使用一些腳本或者自己開發(fā)一些有用的工具,幫助我們減少重復的勞動,降低出錯率。
在工作中,我們可以注意一下幾個方面,
- 構建基礎規(guī)范,包括一些基本是書寫規(guī)范
前期,如果在團隊比較小情況下,可以通過后頭來約束。但是,當團隊發(fā)展到一定規(guī)模,就需要通過文檔,自動化(eslint等),以及代碼評審來規(guī)范。
再這樣的情況下,便于新人更快的融入到開發(fā)當中,以及可以約束同事產(chǎn)出更好的代碼并且使得項目維護更加方便。
- 可以使用一些預編譯器,來加快我們的開發(fā)效率,例如es6,es7等語法,或者typescript。對于css有sass,less等
- 統(tǒng)一的開發(fā)工具,統(tǒng)一的開發(fā)工具有利于,可以通過使用工具中的插件來提升開發(fā)效率,并且不需要學習。但我個人喜歡用不同的工具,目前用的最多的有vscode 以及webstrom 。并且兩個工具各有優(yōu)劣。例如,vscode更佳簡單輕便有很多插件可以隨時插拔,并且是free的 。但是,我再使用vscode的git相關插件中,總會出現(xiàn)一些問題。在這點webstrom會更好一些,我比較喜歡使用webstrom的git對比工具,每當有不該合并的代碼混入時,我可以通過比對,輕松將代碼分離開來。
- 值得注意的是項目中的文檔
項目中的文檔可以分為獨立的文檔,已經(jīng)代碼中的文檔,兩者相結合可以達到很好的效果。我認為,在開發(fā)新需求的同時,開發(fā)文檔也應該是工作中不可缺少的一部分。通過文檔可以讓隊友很好的理解你當初的設計思路,或者比如說,日后在重構的時候,可以很清楚代碼的邏輯以及為什么要這么寫。
除了單獨的文檔,還有注釋,代碼提交記錄以及相應的描述都可以成為很好的文檔。
- 測試
測試是很好保證代碼質量的一個手段,通過寫測試可以更好的理解代碼和邏輯,并可以在適當?shù)臅r候為重構或者修復bug時防止,其他功能被篡改。
測試從下往上主要有單元測試,組件測試,服務測試,e2e測試。
構建流
有了工作流之后,我們需要將我們,我們的源代碼通過構建,發(fā)布到服務器上。
對于一個小的,不需要任何依賴項目,我們只需要將我們編寫的js,css,html放在一個文件夾里,然后丟到服務器上。幾乎,沒有什么構建流可言。但,我們項目越來越復雜我們必須關注以下一些問題。
- 依賴管理工具
目前而言,我們主要使用npm,npm主要基于commenJS來實現(xiàn)。在構建的過程中,可能會通過其他形式來引入,因為,commenJs并是在nodejs中運行的包管理機制,它并不適合用于移動端。
這里有一個重要的問題,就是nodeJS跨平臺的問題,有些nodeJS依賴包,為了優(yōu)化性能,將一部分功能使用C++編寫,而C++代碼再node中運行的時候,需要編譯。編譯的過程會存在,操作系統(tǒng)或者,npm版本不兼容的問題。
- 構建的目標
根據(jù)場景不同,構建是一個復雜的話題,但基本項目離不開以下一些文件
? a. 用于管理運行時(如路由懶加載)的runtime.js文件
? b.樣式相關的style.css
? c. 解決JavaScript在不同瀏覽器兼容問題polyfills.js
? d. 程序相關的main.js
在文件打包時,除了進行代碼的編譯、打包、還要對css,js等靜態(tài)文件進行重命名等。
-
設計構建流
- 明確任務,就是需要做什么,例如npm build是打包,npm test是測試
- 步驟拆解,將任務拆解為一些步驟
- 展現(xiàn)形式,我們大多數(shù)是一個網(wǎng)站,但有些項目例如一個組件庫,需要的是文檔以及示例
- 插件,在構建的時候,一般會選用插件,使用插件能更高效,在選用插件的時候,確定構建的可行性
明確上述后,我們需要使用工具對其進行自動化
目前,常用的工具有glup grunt webpack等,不同的工具優(yōu)劣不同,使用場景也不同。
對于,使用框架的項目,一般情況框架都提供的相應的cli,只需要進行簡單的定制。
持續(xù)集成
對于構建好的目標文件,則需要進行部署。以下為三種部署方式:
- 持續(xù)部署,構建完成即部署,常見于測試環(huán)境
- 自動化部署,在持續(xù)部署的基礎上稍微進行弱化,即需要人為的介入才能自動化部署
- 手動部署,即需要全程人為介入的部署流程
對于自動化部署,我們需要選取適當?shù)墓ぞ撸鏹enkins等幫助我們完成。同時,部署的時候需要,進行環(huán)境配置。例如將http請求從本地的mock Server指向后端服務等。
還有一件事情,就是我們需要寫一些調試的代碼,為了捕獲難于察覺的bug,通常會有一些額外的開關來獲取我們需要的調試數(shù)據(jù)。如:
- 在url中添加一些參數(shù),在前端代碼運行時去讀取這些參數(shù)
- 對特定的賬號進行權限處理,以獲取調試功能。
多頁面應用與單頁面應用
我認為,假設你所擁有的工具只有一個錘子時, 把所有的事物都當做釘子來對待是很有吸引力的。
——錘子定律
1. 為什么不使用單頁面應用
對一個前端工程師來說,拿到一個項目要去實現(xiàn)它,無非用兩種方式
- 使用多頁面,包括服務端使用模板引擎進行渲染,或者使用類似jquery的js庫
- 使用單頁面框架,目前流行的vue,react,angular
書中作者通過三個方面來闡述多頁面應用的優(yōu)勢,分別是:構建成本,學習成本,后臺渲染成本,架構的復雜性。
構建成本
對于一個多頁面系統(tǒng)來說,幾乎不需要什么構建,因為,不論是html代碼或者后端通過jsp或者asp等動態(tài)產(chǎn)生的html代碼都是可以直接在瀏覽器中運行的。
但是,單頁面就沒有那么順利。目前的單頁面系統(tǒng)中幾乎都使用了虛擬dom技術,我們在開發(fā)中產(chǎn)出的是,vue的template模板語言,或者是jsx。但是它們在瀏覽器中運行的卻是,可以返回一個對象的render函數(shù),這個對象是一個虛擬dom的對象,經(jīng)過一系列復雜的操作將其渲染為真實的dom。
所以,當將一個.vue文件或者.jsx文件變成render函數(shù)時,就產(chǎn)生了構建成本。即使目前已經(jīng)有成熟的工具可以使用,例如vue-loader, 或者babel.js。但是,跟多頁面比起來,這些”黑盒工具“(vue-loader,babel.js等)在一定程度上會帶來一些成本,與維護的風險。
學習成本
就目前我們前端開發(fā)中常用的單頁面框架(vue, react, angluar), 每一種框架都有詳細的文檔,以及強大的社區(qū)。特別是最近比較火的vue,我們在編寫的時候,感覺就好像是編寫原生的html代碼,對于一個小團隊或者團隊的技術儲備不夠扎實的時候,直接是首選。
但是,使用久了就會發(fā)現(xiàn),要構建一個復雜的項目,需要對其原理有一個深入的理解才可以,這個過程無形中增加了許多學習成本。
后臺渲染成本
書中談到這個,主要是說目前的一單頁面框架在面對SEO(Search Engine Optimization)的情況,作為單頁面系統(tǒng),需要將dom渲染挪到服務端去,這樣就增加看服務端渲染的成本。如果是,用原生的html開發(fā)的網(wǎng)站就不存在這個問題。
除此之外,使用多頁面應用,還有個好處就是,在面對在對兼容性有要求的項目中體現(xiàn)出的優(yōu)勢,就是防止出現(xiàn)兼容問題時對”黑盒框架“的束手無策。
2. 多頁面應用
3. 單頁面應用
前端MV*原理
- M: model表示數(shù)據(jù)模型,返回一個數(shù)據(jù)對象,是展現(xiàn)給用戶的信息的一個抽象。
- V:view展示層,這里表示呈現(xiàn)給用戶的頁面。
- *: 這里通常有兩種,一種Controller,一種是VM(ViewModel)實際上是改進版的MVC。
在我們常用的三大框架(vue,react,angluar)中都是通過虛擬dom來優(yōu)化直接使用瀏覽器dom操作api操作dom帶來的性能低下的問題,所以有兩層mv*,
- data->virtual dom: 這里vue中的是data函數(shù)返回的數(shù)據(jù)對象,react中是this.state,他們都是
- Virtual dom -> real dom:在虛擬dom與真實dom之間,通過一些邏輯進行關聯(lián),當虛擬dom發(fā)生改變時會同步到真實dom上去