從去年開始,前端領域就出現了一個‘微應用’的名詞,說的是前端架構的一種設計思路,業內都把它和后端的微服務進行類比,當時忙於公司的項目。沒有靜下心來好好了解,現在項目結束,再加上最近看的幾篇關於前端微服務的文章,(特別討厭有些文章說的天花亂墜,引用各種高大上的名字,一篇通讀下來什么也沒有獲得)回頭一想,我們做的這個架構設計不就是 ‘微服務’嗎?
首先說一下前端微服務。
我覺得這是一種架構設計,不是什么新技術,而是多種技術結合的產物,既然是架構設計那么它就得有使用場景,否則那是空談,而它的使用場景則是面對平台級的產品解決方案,可以支撐許多web應用,各個應用之間相互獨立解耦,又可以不斷擴展,不僅易於老代碼,老業務的維護,而且開發項目也是游刃有余的。對於開發人員來說,這樣的架構設計也是獨立的,完完全全可以負責單獨的web應用,而不需要和別的團隊交叉式協作,所以我覺得如果產品是平台級的,做的是解決方案的東西,長期支撐公司發展的,那它的一種設計思路不妨一試,但如果就是幾個獨立的web應用,比如說公司官網,后台系統,支付系統,這幾個一點關聯都沒有的項目,沒有必要來這樣做,反而會增加項目本身的難度。
它的出現我覺得很大程度上是由於spa單頁面應用的出現,組件化的出現,讓一個完整的頁面從幾個標簽的組合,到模塊功能的組合,再到應用的組合,一步步過渡,最初一個頁面由幾個標簽加點文字或者圖片組成,主要用來向消費者輸出信息,到后來ajax出現,局部刷新人機交互,頁面成了按照功能模塊來划分,再到現在單頁面應用,直接按照應用來划分,每一個應用有自己的一套數據,交互,邏輯,業務等等,頁面成了一個容器,或者說是一張幕布,它所做的就是有一個加載機制,更夠很多好地處理各個應用的關系和數據通信,所以一步步走過來,有各大瀏覽器廠商對引擎的升級換代,有硬件的迭代,還有大量交互數據的出現,體驗的升級等等因素,這些訴求讓前端領域不再是展示內容那么簡單,需要不斷突破自我,架構設計應運而生。
微服務里面容器或者稱為平台該怎么搭建,怎么加載不同的web應用,應用之間如何數據通信,應用怎么擴展定義,那些平台級核心方法如何處理等等,帶着這些問題,結合我司的項目談談我的看法及設計思路。
首先有一個最基本的容器
由於項目的復雜特點和背景,我們使用的是jq,別覺得low,用小米加步槍能打敗敵人更是說明策略用得好,容器呢則是iframe,應用之間數據通信呢,則是掛載了window這個大對象。
加載機制
那么如何去加載不同的應用呢,有的做法是將所有的應用js文件在首次全加入進來,每一個應用都是一個獨立的大對象,根據地址欄的url組成,獲得其中的hash名,這個名字可以是應用的名字,去實例化特定的應用。
或者學習一下vue-router,利用hash改名字,頁面不刷新的特點,去按需加載特定的應用js文件。
在或者直接以整個web組件的形式,通過document.append的方式直接插入進來。
我司采用的是第二種,這樣的方式可控,加載機制可以自定義處理。畢加索的名言,‘優秀的藝術家抄襲創意,傑出的藝術家剽竊靈感’。
然后各個應用該如何處理呢,怎么才能做到應用獨立擴展,而又沒有重復代碼呢?
按照如今一切js文件皆模塊的原則,每個應用的數據,交互邏輯,都是獨立的類,或者獨立的模塊,這個每次擴展就是一個獨立的類,包含着新業務的特定數據和邏輯,相互之間使用import進行引用,不會出現代碼越來越多,慘不忍睹的情況,而每一個應用它都有一個index.js文件,在每次啟動應用的時候去加載這個index文件。
而那些平台級基礎層的組件如何操作呢
繼承,由於是平台級的基礎層,每個應用都會使用,所以在每個應用的邏輯處理時,都需要通過繼承來使用平台級的方法,當然每個應用都不一樣,平台級的工具要做到‘拿來即用’,應用可以結合自己的數據自由組合這些工具,搭建自己的應用,軟件行業里面有句名言,‘架構設計中,沒有一個問題是不能通過一層抽象層來解決,如果有,那就是兩層’。
注意后期維護
如果不明白這個架構思路,當有新人接收項目,或者出現新的業務的時候,很容易將這個架構打破,可能還是會按照程序員他自己原來的思路去往上堆,如果是個高手他可能會看明白,但是個初中級的段位呢?對吧,最明顯的例子就是你可能僅僅加一個小功能,想當然地直接插入進去,雖然成功了,結果很容易忽視它是一個平台級的還是應用級的方法,甚至可能會因為命名而導致你其他應用的部分功能不好使,所以架構規則很重要,同時也會發現,當你只是要添加一個小功能的時候,基於這是一個平台級的應用,合理地增加新功能是一件不容易的事,你可能會質疑它,但隨着你的不斷深入,抽絲剝繭,你最終會發現,這一切都是有原因可言的。
關於后台通信
由於將項目所有的重心放在了前端,所以弱化了后端的功能,只需要提供最基本的數據增刪改查即可。
關於構建部署
如何前端構建部署都是基於webpack工具來操作,平台級的部署也能夠體現微服務的特點,獨立部署,獨立構建,所以在需要結合項目去自定義腳手架,在我司項目中,自定義npm命令,以web應用名來定義,而在webpack文件夾下,目錄結構大概是這樣:
和其他腳手架類似,有一個最基本的base文件,來做平台級的構建優化,比如壓縮靜態資源,babel轉編譯,打包編譯,開發環境和構建環境的差異化部署等等,來覆蓋整個應用,然后各個應用有自己獨立的webpack文件,對webpack有一定了解的人都知道,在應用中繼承或者使用baseJS文件,直接require進來即可,由於webpack的幾大要素都是通過對象屬性來構成的,所以想二次加工這baseJS文件,可以直接修改這些屬性即可,如此,便建立了應用自己的構建部署,
在package.json文件中根據命令定義好了特定web應用的webpack文件
而在cmd命令中,只需輸入命令npm run XXX,則會在package.json命令中自動加載特定webpack文件
快速理解
項目特別復雜,你又想特別快入手,明白它的架構設計,我覺得抓住兩點很重要,第一是數據流,你得注意它的數據結構和流向,從上到下(父子組件,應用之間),從左到右(兄弟組件,應用之間),數據又是如何展示到各個應用的,有一個整體概念,第二,事件機制,其實就是數據處理的交互,每一部分的數據都如何產生的,邏輯處理是怎樣的,再深入到具體的應用中,去分析它的業務即可,這也是為什么大學里面計算機專業的課程很大一部分是在教授數據結構和算法,而不教你一大堆主流框架,各種java,R,go,javascript編程語言的原因,說到底,我認為,一個應用就是由數據結構,算法,以及本身的業務數據構成的,而那些vue或者react只不過是一種工具,讓你更好地實現你的idea。
寫着寫着,其實發現這個vue的設計思想特別像,我覺得vue的組件化設計其實就是面向對象思路,react更多的是函數式編程,一切js皆文件,以一種web組件的形式來集成應用,無論是哪一種主流框架結構,更多的理解框架本身的設計思路,並融會到自己的項目中,也算是一種借鑒和突破,我認為不一定非得用主流框架,使用一大堆API就是新技術,借鑒思想,修煉js內功,結合業務突破瓶頸,才是最根本的。
其他方面的有時間再完善。