無論你們有意或者無心間,或多或少都已經接觸到了微前端這個新的概念,這種新的前端架構真的有存在的必要嗎?畢竟沒有銀彈,在新的架構體系下,它除了帶了好處之外,同時也帶來了風險和技術挑戰。本文將帶你揭祕微前端給現有的工程化體系帶來了的意義,和它的架構設計,以及簡單講解一下微前端的核心模塊loader、sandbox。
微前端是一種相似於微服務的架構,它經過將一個單體的web應用拆分紅多個子應用,在運行時經過主應用來加載對應子應用來達到解耦子應用單獨運行、開發、部署的目的。
css
咱們先來了解一下微前端出現的緣由,因爲大部分開發同窗開發的都是單體應用。先舉幾個實際工做中開發單體應用常見的問題吧:
html
微前端的核心價值前端
經過微前端的核心價值咱們能夠很好的解決上述問題:歷史遺留代碼、跨多個團隊協做、發佈效率問題。跨空間和時間的產品極可能會致使應用變成一個巨石應用、技術棧老舊,致使項目的維護成本變高,微前端就是爲了解決這些問題。
在簡單瞭解了現有工程體系的問題,還有微前端能解決的問題以後,咱們來簡單瞭解一下微前端的技術架構。
react
why not iframewebpack
其實從瀏覽器原生的方案來講,iframe不從體驗角度上來看幾乎是最可靠的微前端方案了,主應用經過iframe來加載子應用,iframe自帶的樣式、環境隔離機制使得它具有自然的沙盒機制,但也是因爲它的隔離性對用於體驗帶來了一些反作用:
web
SPA微前端架構前端工程化
從iframe的用戶體驗咱們很難將其做爲微前端的標準方案,那咱們本身要作一套微前端框架具體要作哪些事情呢,從iframe功能咱們大體可以瞭解到,微服務框架須要具有如下幾個功能:
瀏覽器
主工程基座緩存
微前端架構必須有一個主工程基座,基座主要是作爲承載子應用的容器,子應用經過導出對應的格式,主應用在進入到對應路由時加載對應的子應用。
前端框架
loader是微前端核心模塊的加載器,能夠經過loader來進行子應用的加載,目前的微前端方案設計裏面通常有兩種模式。
第一種是非侵入式,經過加載對應子應用的 index.html
文件,再經過對首頁html文件進行解析,獲取到子應用的js文件和css文件,進行加載。
另外一種是子應用打包成一個js文件,按照規範的導出格式,主應用只加載 index.js
文件。獲取到對應的render和destroy方法。
let vm;
module.exports = { render () { vm = new Vue({ render: (h) => h(Home), }).$mount(dom); }, destroy() { vm.$destroy(); } } 複製代碼
做爲模塊加載器它一般須要提供如下幾種能力:
在微前端中有一個須要解決的問題就是,子應用間的公共依賴,咱們如何抽離項目間的公共依賴呢,因爲咱們將一個應用拆分紅了多個子應用,那子應用之間的依賴如何複用。若是瞭解commonJS的同窗應該知道,commonJS具有加載模塊緩存能力,加載過的模塊會將其緩存起來,那麼是否是咱們能夠將子模塊以commonJS的規範進行打包。在加載子模塊時,提供全局的exports和require方法,將子應用導出的exports進行收集,在require時加載咱們配置的external資源。
commonJS加載實現
Module._catcheModule = {}
function req(moduleId){ if(Module._catcheModule[p]){ //模塊已存在 return Module._catcheModule[p].exports } //沒有緩存就生成一個 let module = new Module(p); Module._catcheModule[p] = module; //加載模塊 module.exports = module.load(p); return module.exports; } function Module(p){ this.id = p this.exports = {} this.load = function(filepath){ return Module._extensions(this) } } Module._wrapper = ['(function(exports,require,module,__dirname,__filename){','\n})'] Module._extensions = function(module){ let fn = Module._wrapper[0] + fs.readFileSync(module.id,'utf8') + Module._wrapper[1] vm.runInThisContext(fn).call(module.exports,module.exports,req,module) return module.exports } 複製代碼
經過上面commonJS的源碼模式實現,咱們只須要將exports中增長公共依賴,而且子應用經過webpack構建工具,提供external配置一樣的公共依賴便可。
在微前端框架中另外一個核心的模塊就是沙盒,因爲多個子應用會反覆的展現在同一個容器內,子應用中不免會形成對當前環境的反作用,例如:全局樣式、全局變量、監聽事件、定時器等。沙盒在這裏主要是爲運行中的程序提供隔離環境,避免應用之間相互影響。
在web端設計沙盒咱們須要考慮哪些因素
爲解決全局環境污染和style污染,一般採用,快照模式和代理劫持模式。
快照模式
代理模式
招聘
另外也但願可以吸引更多優秀的同窗加入咱們,加入字節跳動。
團隊相關介紹:ByteDance Web Infra Team is hiring