【微前端】微前端最終章-qiankun指南以及微前端整體探索

itread01 2021-02-23 00:26:02
前端 指南 qiankun


 這才2月中旬,廣州就已經漸漸地進入了夏季,——夏天總是讓人焦慮的。過年閒暇時間寫下了微前端這系列的終章,歡迎拍磚。如果你習慣直接上手程式碼,不妨跳到實踐一節,直接上程式碼教程玩一玩。

如果你還沒有看過前面幾章 這裡是連結:

微前端大賞

微前端大賞二-singlespa實踐

qiankun原理和API介紹

qiankun是基於singlespa框架的一個上層應用,它提供了完整的生命週期,和一些鉤子函式,通過路由匹配來動態載入註冊微應用,同時提供了一系列api對微應用做管理和預載入等,它相對singlespa來說進步是比較大的。

所以---qiankun實質上是singlespa的一個封裝,基於我們在上一節看到的,singlespa是通過輸出一個manifest.json 通過標識入口資訊動態構造script渲染實現的微前端應用,類似下面的圖:

回顧一下singlespa在渲染過程中的核心邏輯
1、 首先我們有 main(主app) child(子app),主app只有一個,子app可以有多個
2、 其次,主app上一般我們可以在index.html裡面,寫多幾個空間,也就是多幾個div
例如:

 

<div id=”react-app”></div><div id=”vue-app”></div>

3、然後,在我們的child上,我們要用webpack外掛,生成一個帶有所有需要載入的依賴檔案的manifest.json

4、主應用去載入這個manifest.json,獲取到具體的js,使用script標籤把它放到主應用上,進行渲染

在qiankun中對這套邏輯做了基本的封裝, 讓我們只需要經過簡單的幾個api就可以控制singlespa中比較複雜的配置和概念。

 

註冊

import { registerMicroApps, start } from 'qiankun';registerMicroApps([ { name: 'react app', // 應用名稱 entry: '//localhost:7100', // 應用入口,應用需要增加cors選項 container: '#yourContainer', // 應用單獨的appid的div activeRule: '/yourActiveRule', // 匹配路由 }, { name: 'vue app', entry: { scripts: ['//localhost:7100/main.js'] }, container: '#yourContainer2', activeRule: '/yourActiveRule2', },]);start();

 

main

main是一個qiankun的主體部分,它也是不限制框架種類的,可以用react也可以用vue和angular,只需要在entry.js裡面註冊它就可以了。

一般情況下main的作用是存放公共程式碼,例如:
1、訊息觸發器
2、公共路由
3、許可權觸發器
4、存放例如全域性管理、面板、使用者管理等公共頁面

你也可以把站點的首頁寫在這裡,可以加快主體載入速度

 

生命週期

 

bootstrap

boostrap相當於init,子應用在第一次載入的時候會呼叫這個方法, 一般可以在裡面做一些專案的初始化操作,例如

 

mount

每次在載入到子應用的時候都會呼叫它,就像是componentDidMount,一般情況下我們要把ReactDOM.render這樣的初始化函式寫在裡面,每次mount時呼叫render

 

unmount

這個跟mount正好相反,每一次登出/切換子應用的時候會呼叫它,一般我們在這裡 ReactDOM.unmountComponentAtNode 登出這個應用,然後把整個專案的容器讓出來

 

update

這是個可選的生命週期,子應用發生變化的時候會呼叫。

 

路由匹配

路由規則有兩種,需要手動呼叫對應的子應用渲染就行了,通過一個叫loadMicroApp的方法掛載一個子應用元件,這樣就可以在main中像配置一個正常的應用那樣配置子應用的view了。

 

import { loadMicroApp } from 'qiankun';import React from 'react';class App extends React.Component { containerRef = React.createRef(); microApp = null; componentDidMount() { this.microApp = loadMicroApp( { name: 'app1', entry: '//localhost:1234', container: this.containerRef.current, props: { name: 'qiankun' } }, ); } componentWillUnmount() { this.microApp.unmount(); } componentDidUpdate() { this.microApp.update({ name: 'kuitos' }); } render() { return <div ref={this.containerRef}></div>; }}

 

處理樣式

 

沙箱

qiankun的沙箱模式是在start的api配置項裡面開啟的

sandbox 選項可選

 

start({ sandbox: true // true | false | { strictStyleIsolation?: boolean, experimentalStyleIsolation?: boolean }})

預設情況下沙箱可以確保單例項場景子應用之間的樣式隔離,但是無法確保主應用跟子應用、或者多例項場景的子應用樣式隔離。當配置為 { strictStyleIsolation: true } 時表示開啟嚴格的樣式隔離模式。這種模式下 qiankun 會為每個微應用的容器包裹上一個 shadow dom 節點,從而確保微應用的樣式不會對全域性造成影響。
shadow dom coco大神寫過一篇文章介紹這個,我就不班門弄斧了
https://www.cnblogs.com/coco1s/p/5711795.html

 

樣式衝突解決方案

qiankun 會自動隔離微應用之間的樣式(開啟沙箱的情況下),你可以通過手動的方式確保主應用與微應用之間的樣式隔離。比如給主應用的所有樣式新增一個字首,或者假如你使用了 ant-design 這樣的元件庫,你可以通過這篇文件中的配置方式給主應用樣式自動新增指定的字首。

以 antd 為例:

配置 webpack 修改 less 變數

 

{ loader: 'less-loader',+ options: {+ modifyVars: {+ '@ant-prefix': 'yourPrefix',+ },+ javascriptEnabled: true,+ },}

配置 antd ConfigProvider

 

import { ConfigProvider } from 'antd';export const MyApp = () => ( <ConfigProvider prefixCls="yourPrefix"> <App /> </ConfigProvider>);

 

webpack配置的問題

微應用的打包工具還需要增加如下配置:

 

 const packageName = require('./package.json').name; module.exports = { output: { library: `${packageName}-[name]`, libraryTarget: 'umd', jsonpFunction: `webpackJsonp_${packageName}`, }, };

 

qiankun實踐-react微前端應用

 

起始,準備2個react應用

直接用create-react-app建立兩個app應用

 

npx create-react-app main-appnpx create-react-app micro-app

可以得到一個資料夾裡有兩個專案


我們用main做主應用,micro做子應用,按照我們的api,子應用只需要配置一個register就可以引入子應用了
其中子應用需要調出webpack配置,create-react-app預設是不允許手動配置的,使用命令就可以了
進入micro-app的資料夾目錄執行(create-react-app也有overload的辦法更改配置,這裡為了方便直接用命令調出來):

npm run eject

這樣專案的準備工作就做好了。

 

子應用配置

配置子應用兩個步驟,一個是生命週期的配置。 我們把生命週期函式寫好放到main.js中:

然後我們把reactDom.render放到mount生命週期裡呼叫,讓qiankun在準備好載入mount的時候再去初始化應用:

unmount的登出操作也不能忘記:

我們更改一下子應用的根節點id,在父應用中再去引用它(不要忘了html裡也需要更改):

最後再把webpack中的配置修改一下:
1、修改devserver支援cors 修改埠
headers: { 'Access-Control-Allow-Origin': '*', }

 

 

 


2、修改增加bundle的匯出,在webpack.config.js增加配置:

 

 

 

 

父應用配置

然後我們就可以去在main應用中,註冊了首先要

npm install qiankun --save

然後在main檔案index.js中註冊子應用:

 

 

 


別忘了我們還需要在public/index.html中寫一個div容器,id是我們子應用的那個id,用來承載子應用的渲染:

 

 

 

然後我們就可以開始執行看一看了:

 

 

 

執行成功,隨便改一下micro的樣式看看效果:

 

 

 


接下來我們需要處理一下路由跳轉的問題。

 

路由的處理實踐

前文有提到,在react中使用qiankun可以使用apiloadMicroApp,這裡我們也用它來處理路由的跳轉。
我們主要是在main-app中操作:
首先新建micro-app的view檔案(每多一個子應用就新建一個):

 

 

 

然後使用react-router直接配置:
由於create-react-app預設沒有直接提供react-router,我們手動下一個

 

npm install react-router react-router-dom --save

改完index.js長這樣:

 

 


再試一下:

 

 

大功告成! 

 

結論和原始碼

相比較上一次我們看見的 singlespa的配置要簡單了很多,而且更加直白,新增子應用更加無縫。
需要demo原始碼的同學私信我哦

 

應用場景和坑

 

坑-靜態資源問題解決

微應用打包之後 css 中的字型檔案和圖片載入如果使用的載入路徑是相對路徑,會導致css 中的字型檔案和圖片載入 404。

而 css 檔案一旦打包完成,就無法通過動態修改 publicPath 來修正其中的字型檔案和背景圖片的路徑。

主要有三個解決方案:

  • 所有圖片等靜態資源上傳至 cdn,css 中直接引用 cdn 地址(推薦)
  • 藉助 webpack 的 url-loader 將字型檔案和圖片打包成 base64(適用於字型檔案和圖片體積小的專案)(推薦)
  • 使用絕對地址,nginx中設定靜態目錄

  

結束語

qiankun整體的思路是比較ok的,它大大簡化了singlespa的使用邏輯,讓微前端的門檻變得更低,但它仍然有一些缺點,例如部分api總是會有莫名其妙的問題,例如api文件不是特別的直觀等,這些都是待改進的地方。而對於微前端來說,做到能夠技術棧無關、漸進升級舊專案、分離不同業務等功能就已經能發揮它的最大價值

版权声明
本文为[itread01]所创,转载请带上原文链接,感谢
https://www.itread01.com/content/1614009665.html

  1. 【微前端】微前端最终章-qiankun指南以及微前端整体探索
  2. Vue-Cli 创建vue3项目
  3. Go in the front of the progress of u boot v7.0 U disk boot disk production tools
  4. 使用NTLM的windows身份验证的nginx反向代理
  5. Rust教程:针对JavaScript开发人员的Rust简介
  6. 使用 Serverless Framework 部署个人博客到腾讯云
  7. #研發解決方案#易車前端監控系統
  8. Vue changes localhost to IP address and cannot access
  9. JavaScript进阶学习
  10. HTML5 from entry to proficient, realize annual salary 10W +, zero basic students must see
  11. Vue:vuex状态数据持久化插件vuex-persistedstate
  12. Vue source code analysis - start
  13. Vue -- the child component calls the method of the parent component and passes parameters --- props
  14. React-Native 获取设备当前网络状态 NetInfo
  15. 高性能 Nginx HTTPS 调优 - 如何为 HTTPS 提速 30%
  16. How to learn HTML5? How can Xiaobai start HTML5 quickly?
  17. HTML + CSS detailed tutorial, this article is enough, but also quickly save
  18. JavaScript高级:JavaScript面向对象,JavaScript内置对象,JavaScript BOM,JavaScript封装
  19. Why Vue uses asynchronous rendering
  20. JavaScript高级:JavaScript面向对象,JavaScript内置对象,JavaScript BOM,JavaScript封装
  21. vue判断elementui中el-form是否更新变化,变化就提示是否保存,没变就直接离开
  22. 算法题:两数之和——JavaScript及Java实现
  23. 高性能 Nginx HTTPS 调优
  24. Why Vue uses asynchronous rendering
  25. day 31 jQuery进阶
  26. day 30 jQuery
  27. CSS whimsy -- using background to create all kinds of wonderful backgrounds
  28. Why are more and more people learning front end?
  29. What do you do with 4K front-end development?
  30. 8 years of front-end development knowledge precipitation (do not know how many words, keep writing it...)
  31. What is the annual salary of a good web front end?
  32. Front end novice tutorial! How to get started with web front end
  33. Will the front end have a future?
  34. Is the front end hard to learn?
  35. Seven new Vue combat skills to improve efficiency in 2021!
  36. Is front end learning difficult?
  37. How about the process of Web front-end development and self-study?
  38. Front end learning route from zero basis to proficient
  39. What is the basis of learning front end?
  40. What knowledge points need to be learned for self-study front end? How long can I become a front-end Engineer?
  41. An inexperienced front-end engineer, what are the common problems when writing CSS?
  42. HttpServletRequest get URL (parameter, path, port number, protocol, etc.) details
  43. Springboot starts http2
  44. Enabling http2.0 in spring boot
  45. JQuery:JQuery基本语法,JQuery选择器,JQuery DOM,综合案例 复选框,综合案例 随机图片
  46. Using JavaScript in Safari browser history.back () the page will not refresh after returning to the previous page
  47. vue.js Error in win10 NPM install
  48. In less than two months, musk made more than $1 billion, more than Tesla's annual profit
  49. Springboot starts http2
  50. Vue event bus
  51. JQuery easy UI tutorial: custom data grid Pagination
  52. Using okhttp and okhttpgo to obtain onenet cloud platform data
  53. Vue3 component (IX) Vue + element plus + JSON = dynamic rendering form control
  54. HTTP 1. X learning notes: an authoritative guide to Web Performance
  55. Vue3 component (IX) Vue + element plus + JSON = dynamic rendering form control
  56. HTTP 1. X learning notes: an authoritative guide to Web Performance
  57. JQuery:JQuery基本语法,JQuery选择器,JQuery DOM,综合案例 复选框,综合案例 随机图片
  58. Event bubble and capture in JavaScript
  59. The root element is missing solution
  60. Event bubble and capture in JavaScript