微前端思考與總結(jié)

點擊上方藍(lán)字關(guān)注我們
微前端是最近一年以來前端領(lǐng)域非?;鸬囊粋€概念,同時阿里集團(tuán)內(nèi)也衍生了很多相關(guān)的技術(shù)產(chǎn)品。這篇文章是考拉運營中臺組最近調(diào)研微前端的一些嘗試和思考
微前端介紹
微前端是一種多個團(tuán)隊通過獨立發(fā)布功能的方式來共同構(gòu)建現(xiàn)代化 web 應(yīng)用的技術(shù)手段及方法策略 https://micro-frontends.org
微前端工程價值
獨立開發(fā)、獨立部署;
框架無關(guān);
跨業(yè)務(wù)域復(fù)用;
方便功能擴(kuò)展、升級;
便于多人協(xié)作開發(fā);
如果微前端只存在工程上的價值是不值得大張旗鼓去做的
微前端業(yè)務(wù)價值
業(yè)務(wù)原子化輸出;
業(yè)務(wù)編排整合;
應(yīng)用場景
巨石應(yīng)用的拆分-pop partner系統(tǒng)
業(yè)務(wù)編排整合-搭建&大促系統(tǒng)
微前端的優(yōu)勢可以有效的彌補(bǔ)當(dāng)前運營中臺遇到的一些痛點:
技術(shù):考拉加入阿里之后有很多網(wǎng)易技術(shù)背景下的工程,特別是中臺組這邊 angular 和 vue 框架實現(xiàn)的代碼,甚至還有前后端不分離的 java+angular 的老工程,這些工程開發(fā)效率慢,開發(fā)體驗差,沒有成就感
運營:運營同事針對各種內(nèi)部系統(tǒng)沒有統(tǒng)一的調(diào)配入口,一次操作有可能需要在多個不同系統(tǒng)完成,操作效率底下
single-spa & qiankun
single-spa 是現(xiàn)在市場上比較成熟的技術(shù)方案,以及螞蟻基于 single-spa 研發(fā)的 qiankun 框架
import * as singleSpa from 'single-spa';singleSpa.registerApplication('app-1', () =>import ('../app1/app1.js'), pathPrefix('/app1'));singleSpa.registerApplication('app-2', () =>import ('../app2/app2.js'), pathPrefix('/app2'));singleSpa.start();function pathPrefix(prefix) {return function(location) {return location.pathname.startsWith(`${prefix}`);}}
我們需要注冊對應(yīng)的 application,并且指定對應(yīng) application 的激活函數(shù)。同時 application 需要在入口文件導(dǎo)出相應(yīng)的生命周期函數(shù)?
export async function bootstrap(props) {...}export async function mount(props) {...}export async function unmount(props) {...}

如果簡單來看的話,single-spa 就是在合適的時候執(zhí)行我們傳入的 loadFunctin, bootstarp, mount, unmount, unload 方法,并拋出了一些事件
qiankun 的啟動調(diào)用方式和 single-spa 非常相似,但是在 single-spa 的基礎(chǔ)上增加了一些功能
import-html-entry
js沙箱
更豐富的生命周期
prefetch
https://qiankun.umijs.org/zh/guide/getting-started.html#%E4%B8%BB%E5%BA%94%E7%94%A8
技術(shù)難點
1.應(yīng)用隔離
js 沙箱實現(xiàn)
通過proxy代理window對象,監(jiān)聽對應(yīng)的get set方法
在應(yīng)用的 bootstrap 及 mount 兩個生命周期開始之前分別給全局狀態(tài)打下快照,然后當(dāng)應(yīng)用切出/卸載時,將狀態(tài)回滾至 bootstrap 開始之前的階段,確保應(yīng)用對全局狀態(tài)的污染全部清零。而當(dāng)應(yīng)用二次進(jìn)入時則再恢復(fù)至 mount 前的狀態(tài)的,從而確保應(yīng)用在 remount 時擁有跟第一次 mount 時一致的全局上下文

對象,函數(shù)劫持
setInterval、setTimeout,addEventListener,removeEventListener,appendChild
單實例 多實例的場景
2.樣式隔離
Shadow DOM
CSS Module? BEM
Dynamic Stylesheet
3.html-entry
獲取html頁面內(nèi)容
解析成dom,script,style,entry入口文件
獲取style的內(nèi)容填充到html中
通過sandbox執(zhí)行script代碼
4.應(yīng)用通信
initGloabalState,props
參考:https://zhuanlan.zhihu.com/p/78362028
? https://zhuanlan.zhihu.com/p/107240132
大促系統(tǒng)改造方案:
主應(yīng)用改造:
在大促系統(tǒng)的工程下新建了一個服務(wù),單獨用來做微服務(wù)的主應(yīng)用工程
提供統(tǒng)一的吊頂服務(wù)
因為各個系統(tǒng)都維護(hù)了各自獨立的登錄體系,主應(yīng)用暴露出login入口
自定義了fetch方法
css中相對路徑替換
子應(yīng)用改造:
靜態(tài)文件,接口請求支持跨域 egg-cors
入口文件導(dǎo)出生命周期
dll output配置 library librarytarget
kapp/cas 去掉 loginSuccessUrl
mounted 增加login組件
接口請求 publicpath 配置
靜態(tài)文件 __webpack_publicpath_ 配置
href 跳轉(zhuǎn)替換,子應(yīng)用互跳
獨立的路由規(guī)則
隱藏側(cè)邊欄和頂欄
文件上傳組件publicpath設(shè)置
regular nej改造
https://www.yuque.com/docs/share/95b0302c-dba6-44d0-9292-9b81d7415de7?#
https://www.yuque.com/docs/share/35788488-2bfc-406d-8627-aacd6a7e79e3?#
技術(shù)上的痛點:巨石應(yīng)用,可維護(hù)性
代碼量達(dá)到一定量的時候,單次構(gòu)建時間很長,開發(fā)&發(fā)布效率極低
代碼庫中依賴升級會影響整個應(yīng)用,而代碼量又非常大,導(dǎo)致回歸成本極高
變成一個非常臃腫的巨石應(yīng)用,完全失去靈活性,無論是多人協(xié)作還是業(yè)務(wù)接入成本都會大大增加
業(yè)務(wù)上的場景:應(yīng)用的拆分和編排
用戶端必須是「一個系統(tǒng)」的心智,從域名到體驗
能夠根據(jù)功能拆分成多個子應(yīng)用,每個子應(yīng)用獨立開發(fā)獨立部署
子應(yīng)用盡量保證跟傳統(tǒng)單頁面應(yīng)用一樣的開發(fā)體驗,不要讓開發(fā)者有太多學(xué)習(xí)成本
所有子應(yīng)用可被統(tǒng)一管理起來,不能無限制的泛濫
微前端生態(tài)體系?
什么樣的模式是最佳實踐?


后續(xù)規(guī)劃
考拉集團(tuán)內(nèi)部技術(shù)棧統(tǒng)一
統(tǒng)一的配置發(fā)布平臺產(chǎn)品,提供快速的業(yè)務(wù)整合串聯(lián)能力,幫助業(yè)務(wù)提效
賬號登錄統(tǒng)一收斂
微前端子應(yīng)用接入方案
包含應(yīng)用 組件庫 方法主應(yīng)用接入方式
本地的開發(fā)工具
其他:
????????webpack5 module federation
????????webcomponent
????????調(diào)試
????????登錄模式不友好
????????報錯:ResizeObserver loop limit exceeded

推薦閱讀
