基於qiankun落地部署微前端爬」坑「記

(給前端食堂加星標,吃好每一頓)

前沿:前半年微前端火得一踏糊塗,恰好業務需求上有這樣的應用場景,針對目前的微前端解決方案作了技術選型,qiankun做爲螞蟻金服內部孵化出來的微前端解決方案,通過線上應用充分檢驗及打磨最後開源,最終選擇qiankun做爲咱們雲產品架構入口。不過官方文檔上關於上線部署文檔較少,不少童鞋也可能只是在本地玩玩,沒有到真正走通整個閉環,因而結合自身,在將qiankun落地過程當中遇到的「那些坑」作個梳理。但願對你有所幫助css

1.🍵 茶前點心

本文不大篇幅介紹關於qiankun的「前世此生」,更多的設計理念介紹請看文檔若是有想了解其餘微前端解決方案的童鞋,也能夠回顧下以前樹醬分享的微前端那些事html

舉個例子:咱們有個這樣的場景,我有個門戶Portal的登錄界面(主應用基座),登錄成果後能夠切換不一樣的子應用,以下有兩個子應用A和B,且都在以前是獨立部署的,單獨能夠訪問,可是咱們如今想借助qiankun把他們「嵌」到基座來加載,往下看實操前端

你可能會問直接用iframe不香嗎?真不香,主要幾個侷限問題vue

  • 父子應用之間通訊問題
  • cookie共享問題(可作單點登錄SSO)
  • 交互視圖效果不佳

上面是一個經過域名訪問子應用的示意圖,接下來咱們看看一個view視圖,header頭部和sideMenu左側菜單是屬於portal門戶的,而右側區域則是顯示切換子應用的視圖,預期效果:當咱們訪問dev.portal.com/a該域名時(即切換到子應用A),左側菜單也會根據不一樣應用切換不一樣數據nginx

1.1 註冊子應用時應該注意哪些問題?

👦 啊明同窗:qiankun是如何註冊子應用的呢?web

qiankun是經過registerMicroApps(apps, lifeCycles)API來註冊子應用的,詳細文檔請看點我👉  用來實現當瀏覽器 url 發生變化時,自動加載相應的子應用的功能,結合上面的例子咱們試着在基座main.js註冊子應用vue-cli

主要包括:api

  • entry: 子應用的 entry 地址,好比咱們如今有兩個子應用A和B,那麼這裏配置的就是他們的資源訪問域名或ip
  • render:本質上是container的轉換,container用來定義子應用的容器節點的選擇器或者 Element 實例,這裏使用的是實際例子
  • activeRule:子應用的激活規則,即什麼路由訪問纔會去fetch entry配置的域名或ip,咱們用了 getActiveRule來完成匹配,咱們看看 getActiveRule的實現,該函數經過傳入當前 location 做爲參數,而後根據函數返回數值來看,若返回值爲 true 時則代表當前子應用會被激活,則去調用entry入口配置

匹配以下跨域

✅ https://dev.portal.com/a

✅ https://dev.portal.com/a/anything/everything

🚫 https://dev.portal.com/c

匹配成功後,qiankun 經過 fetch 去獲取所匹配子應用的靜態資源瀏覽器

1.2 資源訪問跨域如何解決?

👦  啊呆同窗:你這樣不會跨域嗎?基座 https://dev.portal.com/ 獲子應用a的資源 https://dev.monitor.com/a的資源 ,根據瀏覽器同源策略(瀏覽器採用同源策略,禁止頁面加載或執行與自身來源不一樣的域的任何腳本)應該獲取不到吧,明顯跨域

答案:是,因爲 qiankun 是經過 fetch 去獲取子應用註冊時配置的靜態資源url,全部靜態資源必須是支持跨域的,那就得設置容許源了,簡單的設置能夠看下面

  • Access-Control-Allow-Origin:跨域在服務端是不容許的。只能經過給Nginx配置Access-Control-Allow-Origin *後,才能使服務器能接受全部的請求源(Origin)

  • Access-Control-Allow-Headers: 設置支持的Content-Type

1.3 子應用加載失敗是什麼問題?

👦  啊明同窗:跨域解決了,可仍是fetch不到子應用a的靜態資源?是什麼問題咋搞?

出現這個報錯:Application died in status LOADING_SOURCE_CODE: You need to export the functional lifecycles in xxx entry

答案:你的打包姿式不對

vue-cli 3x項目中須要經過在vue.config.js配置output來配置輸出的方式,以下👇所示

  • pubilcPath: 主要解決的是子應用動態載入的 腳本、樣式、圖片 等地址不正確的問題
  • output.library:須要與主應用註冊子應用時的name一致且惟一
  • output.libraryTarget:umd : 導出umd格式,能夠支持inport、require和script引入

而後建立一個publichPath文件,並在main.js 引入

1.4 子應用的publichPath到底應該怎麼配置?

👦  啊明同窗:打包output配置改好了,可是爲何publichPath路徑配置爲/a?

拓展: 沿用上文提到的a應用的訪問域名 dev.monitor.com/a

如今瀏覽器要正確獲取a應用的靜態資源中的css文件,則會去訪問 dev.monitor.com/a/css/common.css

主要分兩種狀況:

  • publichPath若是默認配置或者配置爲/,則生成的index.html 訪問的資源是則不正確,由於將訪問的是dev.monitor.com/css/common.css並非a應用的資源
  • 配置爲/a,則生成的index.html 訪問的資源是 就能夠

👦 啊呆同窗:那publichPath路徑配置爲./相對路徑能夠嗎?

答案:也是能夠的,跟配置爲/a訪問同樣

1.5 如何保障原來的應用運行正常,但能集成到基座portal中

👦 啊明同窗:我以前a應用是單獨運行部署的,我經過qiankun集成到基座portal中會有影響嗎?

答案:使用這個全局變量來區分當前是否運行在 qiankun 的主應用中

那就是:window.__POWERED_BY_QIANKUN_那能夠用來幹嗎?請看下面👇

  • 獨立運行: window.__POWERED_BY_QIANKUN__爲false,執行mount建立vue對象
  • 運行在qiankun: window.__POWERED_BY_QIANKUN__爲true,則不執行mount

1.6 父應用如何共享util和data給子應用

👦   隔壁老王同窗:若是我想把門戶登錄應用登錄成功獲取到的我的數據共享給子應用還有一些公用的方法,我該怎麼作?

答案:能夠在註冊子應用的時候,把定義好要共享的msg,經過props共享出去

  • msg.data 把store狀態管理數據共享給子應用
  • msg.prototype 定義一些原型數據,好比是否爲qiankun上下文中

父應用定義完,那子應用是如何獲取呢?是經過在子應用掛載前,將props數據導到子應用經過遍歷賦值給到子應用vue原型中

1.7 history路由模式,須要如何配置ngnix,才能正常訪問?

👦  啊宇同窗:我看你訪問的路由模式不是hash,而是history模式,那你是怎麼解決當頁面刷新404問題?

答案:經過nginx配置加入try_files,history 模式一樣會有一個問題,就是當頁面刷新時,若是沒有合適的配置,會出現404錯誤,針對這種請看,須要額外在nginx配置,對於找不到url的,將首頁html返回

  • try_files:用來解決nginx找不到client客戶端所須要的資源時訪問404的問題

  • proxy_pass:主要是用來配置接口網關反向代理,可使得父子應用下訪問的api是一致的,防止接口跨域問題

公衆號:前端食堂


掘金:童歐巴


知乎:童歐巴


這是一個終身學習的男人,他在堅持本身熱愛的事情,歡迎加入前端食堂,和這個男人一塊兒開心的變胖~



推薦閱讀:

互聯網人,都是「快男快女」

據說你 ping 用的很 6 ?給我圖解一下 ping 的工做原理!


  在看和轉發是莫大鼓勵❤️


本文分享自微信公衆號 - 前端食堂(webcanteen)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。