没有特别的幸运,那么就特别的努力!!!
前言
涉及到环境
npm:9.6.3
node:19.9.0
node官网地下载址:https://nodejs.org/dist
项目框架
主应用:vue2
微应用1:vue2,qiankun官网API是基于vue2+webpack。
微应用2:vue3+vite+ts,目前官网没有vue3示例,需要介入vite-plugin-qiankun插件进行处理
下面是用qiankun简易搭建的demo效果图:
主应用
第一步:安装qiankun
$ yarn add qiankun # 或者 npm i qiankun -S
第二步:主应用中注册微应用
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import { registerMicroApps, start } from 'qiankun' //新增部分,导入qiankun中的两个方法
const apps = [
{
name: 'vue2App', //子应用的名称
entry: 'http://192.168.1.12:8083/#/', //子应用的域名,改成自己对应的ip即可
container: '#vue', //承载子应用的容器,在上面App.vue中定义
activeRule: '/vue', // 被激活的子应用的路由
},
{
name: 'vue3App', //子应用的名称
entry: 'http://192.168.1.12:8089/#/', //子应用的域名
container: '#vue', //承载子应用的容器,在上面App.vue中定义
activeRule: '/main', // 被激活的子应用的路由
},
]
registerMicroApps(apps); //注册子应用
start(); //启动qiankun
new Vue({
router,
render: h => h(App)
}).$mount('#app');
微应用
微应用1:vue2+webpack
微应用分为有 webpack 构建,需要做的事情如下:
步骤 | 说明 |
---|---|
1 | 新增 public-path.js 文件,用于修改运行时的 publicPath。 |
2 | 微应用建议使用 history 模式的路由,需要设置路由 base,值和它的 activeRule 是一样的。 |
3 | 在入口文件最顶部引入 public-path.js,修改并导出三个生命周期函数。 |
4 | 修改 webpack 打包,允许开发环境跨域和 umd 打包。 |
1.在 src 目录新增 public-path.js:
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
2.微应用建议使用 history 模式的路由,需要设置路由 base,值和它的 activeRule 是一样的。
import Vue from 'vue'
import VueRouter from 'vue-router'
import home from '../view/home.vue'
import '../public-path'
Vue.use(VueRouter)
const routes = [{
path: '/home',
name: 'home',
component: home
},
{
path: '/Dome',
name: 'Dome',
component: () =>
import ( /* webpackChunkName: "about" */ '../view/About.vue')
}
]
const router = new VueRouter({
mode: 'history',
base: window.__POWERED_BY_QIANKUN__ ? '/vue' : '/',
routes
})
export default router
3.在入口文件最顶部引入 public-path.js,修改并导出三个生命周期函数。
import 'babel-polyfill'
import 'core-js/stable'
import 'regenerator-runtime/runtime';
require('es6-promise').polyfill()
import Vue from 'vue'
import App from './App.vue'
import router from './router'
// import store from './store'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
Vue.config.productionTip = false
let instance = null;
function render(props = {}) {
const { container } = props;
instance = new Vue({
router,
// store,
render: h => h(App),
}).$mount(container ? container.querySelector('#app') : '#app');
}
export async function mount(props) {
render(props);
}
//判断当前运行环境是独立运行的还是在父应用里面进行运行,配置全局的公共资源路径
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
//如果是独立运行window.__POWERED_BY_QIANKUN__=undefined
if (!window.__POWERED_BY_QIANKUN__) {
render()
}
//最后暴露的三个方法是固定的,加载渲染以及销毁
export async function bootstrap() {}
// export async function mount(props){
// render();
// }
export async function unmount() {
instance.$destroy();
}
export async function update(props) {
console.log('update props', props);
}
4.修改 webpack 打包,允许开发环境跨域和 umd 打包。
// vue.config.js
module.exports = {
lintOnSave: false,
devServer: {
port: 8083,
headers: {
"Access-Control-Allow-Origin": "*"
}
},
transpileDependencies: ['*'],
configureWebpack: config => {
config.entry.app = ['babel-polyfill', './src/main.js']
return {
output: {
library: 'vueApp',
libraryTarget: 'umd'
}
}
}
}
微应用2:vue3+vite5
1.qiankun目前不支持vite,需要借助插件vite-plugin-qiankun
npm install vite-plugin-qiankun
2.修改vite.config.js配置
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import qiankun from 'vite-plugin-qiankun'
// useDevMode 开启时与热更新插件冲突
const useDevMode = true // 如果是在主应用中加载子应用vite,必须打开这个,否则vite加载不成功, 单独运行没影响
// https://vite.dev/config/
export default defineConfig({
plugins: [
vue(),
qiankun('vue3App', { // 微应用名字,与主应用注册的微应用名字保持一致
useDevMode
})
],
base: '/main/',
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
server: {
host: "0.0.0.0",
port: 8889, //这里的端口是必须和父应用配置的子应用端口一致
headers: {
//因为qiankun内部请求都是fetch来请求资源,所以子应用必须允许跨域
'Access-Control-Allow-Origin': '*'
},
overlay: {
warning: false,
errors: false
}
},
configureWebpack: {
output: {
library: `vue3App`,
libraryTarget: 'umd', // 把微应用打包成 umd 库格式
// jsonpFunction: `webpackJsonp_${name}`, // webpack 5 需要把 jsonpFunction 替换成 chunkLoadingGlobal
},
},
})
3.路由配置
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import {
qiankunWindow,
} from 'vite-plugin-qiankun/dist/helper'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
base: qiankunWindow.__POWERED_BY_QIANKUN__ ? '/main' : '/',
routes: [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (About.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import('../views/AboutView.vue')
}
]
})
export default router
4.修改main.js
import './assets/main.css'
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { renderWithQiankun, qiankunWindow} from 'vite-plugin-qiankun/dist/helper'
let instance = null
function render(props = {}) {
instance = createApp(App) // 必须放到函数里面,否则会提示重新创建
const { container } = props
instance.use(router)
// instance.use(store);
instance.mount(
container ? container.querySelector('#app') : document.getElementById('app')
)
if (qiankunWindow.__POWERED_BY_QIANKUN__) {
console.log('我正在作为子应用运行')
}
}
// some code
renderWithQiankun({
mount(props) {
console.log('viteapp mount')
render(props)
},
bootstrap() {
console.log('bootstrap')
},
unmount(props) {
console.log('vite被卸载了')
instance.unmount()
// instance._container.innerHTML = ''
// history.destroy() // 不卸载 router 会导致其他应用路由失败
// instance = null
}
})
if (!qiankunWindow.__POWERED_BY_QIANKUN__) {
render({})
}
完整代码
https://gitee.com/hammer1010_admin/qiankun-cro.git
希望能帮助到大家,同时祝愿大家在开发旅途中愉快!!!