文章描述
隨著工作時間的增加,發現公司的項目逐漸多了起來,有一個項目比較龐大,是需要集成多個子系統而形成的大項目。其中便是使用微前端的概念qiankun框架來集成其他多個子項目的。接下來,一起來看一下qiankun框架的具體使用方法吧。
更具體的使用方法請參考qiankun官網
主要內容
主應用
下載依賴
npm i qiankun -S
我們只需要再主應用中下載即可,需要注意的是,下載當前的依賴對node的版本也有限制,我第一次安裝就踩坑了
要求的node版本是"^12.22.0 || ^14.17.0 || >=16.0.0"之內,不能高不能低,挺無語的哈...
添加配置
在main.js文件夾同級下創建registerApp.js文件(重要)
import { registerMicroApps, start } from 'qiankun';// 配置加載中的鉤子函數
const onLoad = ()=>{console.log("加載中");
}
registerMicroApps([{name: 'appChild', // 子程序的name名,對應的是子程序中package中的name名字,唯一的entry: '//localhost:3002', // 子程序的路徑,就是訪問子程序的路徑container: '#container', // 希望將子應用放在哪個容器內activeRule: '/ortherSystem', // 子程序的路由匹配規則,如當主程序中訪問路由/ortherSystem時,框架會自動將子應用的內容加載到上面的容器內loader:onLoad, // 當前子應用加載時運行的函數props:{ // 希望給子應用傳遞的值,在子應用暴露出的mount等函數中可拿到text:"你好,我是主應用" }}
],{beforeLoad:()=>{console.log("加載前");},beforeMount:()=>{console.log("掛載前");},afterMount:()=>{console.log("掛載后");},beforeUnmount:()=>{console.log("銷毀前");},afterUnmount:()=>{console.log("銷毀后");},
});start({sandbox: {strictStyleIsolation: true, // 開啟shadow dom樣式隔離模式},
});
當然如果,如果我們需要手動添加子應用程序時,可以用下面這個函數,這個函數可以讓我們在某個js函數中加載子應用。
import { loadMicroApp } from 'qiankun';loadMicroApp({name: 'app',entry: '//localhost:7100',container: '#yourContainer',
});
對了,當前創建的文件記得要在main.js文件中引入哦
打包配置
在vue.config.js中也需要添加相關的打包配置
const { defineConfig } = require('@vue/cli-service')
const packageName = require('./package.json').name;
module.exports = defineConfig({devServer: {host:'localhost',port:3001,headers:{'Access-Control-Allow-Origin':'*',},publicPath:'./',configureWebpack:{output: {library: `${packageName}`,libraryTarget: 'umd',chunkLoadingGlobal: `webpackJsonp_${packageName}`,},}
})
請注意'Access-Control-Allow-Origin':'*'配置一定需要,要不會有跨域錯誤。
子應用
子應用中不需要下載相關的依賴,只需要安裝要求進行配置即可
配置main.js
根據官網要求,我們需要在子應用的main.js文件中添加并導出幾個函數,分別是bootstrap,mount,unmount等函數。main.js的文件具體寫法如下,被我改造了一下
import { createApp } from 'vue'
import App from './App.vue'// 引入路由
import router from './router/router'let app = null;
const render = (props)=>{app = createApp(App);app.use(router);app.use(ElementPlus);app.mount(props && props.container ? props.container.querySelector("#app") : '#app');
}
/*** bootstrap 只會在微應用初始化的時候調用一次,下次微應用重新進入時會直接調用 mount 鉤子,不會再重復觸發 bootstrap。* 通常我們可以在這里做一些全局變量的初始化,比如不會在 unmount 階段被銷毀的應用級別的緩存等。*/
export async function bootstrap(props) {console.log(props,'props app bootstraped');
}// 這個變量是qiankun框架暴露給全局的,判斷當前應用是否使用qiankun框架了
if(!window.__POWERED_BY_QIANKUN__){render()
}
/*** 應用每次進入都會調用 mount 方法,通常我們在這里觸發應用的渲染方法*/
export async function mount(props) {console.log(props,"props");render(props)
}
/*** 應用每次 切出/卸載 會調用的方法,通常在這里我們會卸載微應用的應用實例*/
export async function unmount(props) {app.unmount()app = null;
}/*** 可選生命周期鉤子,僅使用 loadMicroApp 方式加載微應用時生效*/
export async function update(props) {console.log('update props', props);
}
添加文件
創建public-path.js、.env.development、.env.production等文件
1、.env.development
VUE_APP_PORT = 3002
2、env.production
VUE_APP_PORT = 3002
3、public-path.js(該文件主要用于動態修改publicPath屬性)
(function() {if (window.__POWERED_BY_QIANKUN__) {if(process.env.NODE_ENV === 'development') {__webpack_public_path__ = `//localhost:${process.env.VUE_APP_PORT}${process.env.BASE_URL}`;return;}__webpack_public_path__ = window.INJECTED_PUBLIC_PATH_BY_QIANKUN__;}
})();
該文件記得在main.js中引入哦
打包配置
1、在package.json文件中,將name修改為主應用中注冊所使用的name名。
2、在路由配置中,將路由的baseUrl改成主應用中注冊的路由規則的值,如:
// 我得主應用的路由規則為 /ortherSystem
const routerHistory = createWebHistory('/ortherSystem')
3、在vue.config.js里面配置
const { defineConfig } = require('@vue/cli-service')
const packageName = require('./package.json').name;module.exports = defineConfig({devServer: {host: 'localhost',headers:{'Access-Control-Allow-Origin':'*',},port: process.env.VUE_APP_PORT,},configureWebpack:{output: {library: `${packageName}`,libraryTarget: 'umd',chunkLoadingGlobal: `webpackJsonp_${packageName}`,},}
})
運行結果
好了,進行了上面的幾步后我們應該就可以看到基本的效果了,
?
?報錯經歷
1、node版本不匹配,這是我們需要換適合的node版本了,推薦是"^12.22.0 || ^14.17.0 || >=16.0.0"之間。
?2、當我們的主應用和子應用都準備好了,但是效果還是不出來,查看控制臺發現是跨域了,這是因為端口后ip不同,我們需要再vue.config.js文件的devServer下添加相關配置
headers:{'Access-Control-Allow-Origin':'*',},
3、?子應用中路由不匹配,子應用中匹配好的路由,子應用單獨啟動能正常跳轉,但是使用qiankun框架使用就無法正常匹配了,報404未找到頁面
這大概率是因為你在主應用中將添加子應用的容器使用router-view這個標簽渲染了,我們不要用這個標簽,可以的話在組件中直接引入渲染即可
<template><!-- 不要要用這種方法 --><!-- <router-view></router-view> --><!-- 用這種方法渲染homePage組件,子應用的容器就在homePage組件中 --><homePage></homePage>
</template><script setup>
import homePage from '@/components/homePage.vue'
</script>
4、?樣式問題,在子應用中樣式是正常的,但是在主應用中,子應用的樣式丟失了,而且在我還設置了strictStyleIsolation: true模式,樣式還是很神奇的消失了,
網上查詢了好多方法,最后用審查元素查看發現子應用也正常被shadow-root包裹起來了,結果發現是子應用中,掛載元素時自己寫錯了,在子應用中的render函數應該這樣寫
let app = null;
const render = (props)=>{app = createApp(App);app.use(router);app.use(ElementPlus);// 錯誤// app.mount(props && props.container ? props.container : '#app');// 正常app.mount(props && props.container ? props.container.querySelector("#app") : '#app');
}
props是qiankun框架提供的參數,里面包含了我們注冊時提供的子應用名和主應用中要掛載的容器,但是我們不能直接將子應用掛載到props.container容器中,這樣會將里面內置的標簽屬性給覆蓋掉,導致樣式不生效
?
最終感想
這只是qiankun框架的基本使用方式,具體的方法和更多詳情可以去官網查看,官網寫的很清楚的,當前屬于我個人的筆記,也希望通過這篇文章可以幫到同行的朋友
如果以上寫的內容有什么錯誤的地方,歡迎各位大佬來指點,我發現后一定盡快修改