qiankun虽然有官方文档说明,但由于各种包版本不同,可参考的文档并不完善。以下基于几种框架进行开发实践,选择react作为主应用,接入子项目vue2(前后端不分离)、vue3、antdesignpro(umi)。
主应用
以react-create-app生成的react18项目为例,搭配react-router-dom 6.x
- 安装 qiankun:
$ yarn add qiankun # 或者 npm i qiankun -S
- 注册微应用并启动:
- 基于路由配置
import { registerMicroApps, start } from 'qiankun';
registerMicroApps([{
name: 'aaa',
entry: process.env.NODE_ENV == 'production'?'/vue2App/':'//localhost:8066',
container: '#container',
activeRule: '/vue2',
props: {...}
}, {
name: 'bbb',
entry: process.env.NODE_ENV == 'production'?'/vue3App/':'//localhost:8077',
container: '#container',
activeRule: '/vue3',
props: {...}
}]);
start();
name需保持唯一,当微应用信息注册完之后,一旦浏览器的url发生变化,便会自动触发qiankun的匹配逻辑,所有activeRule规则匹配上的微应用就会append到指定的container中,同时依次调用微应用暴露出的生命周期钩子。
如果微应用不是直接跟路由关联时,可选择手动加载微应用的方式。
- 手动加载微应用
import { loadMicroApp } from 'qiankun';
loadMicroApp({
name: 'ccc',
container: '#container',
entry: process.env.NODE_ENV == 'production'?'/umiApp/':'//localhost:8099'
})
- webpack配置:原有写在微应用中
devServer.proxy接口代理均需迁移至主应用 - nginx配置:
server {
listen 80;
server_name localhost;
access_log /export/Logs/access.log main;
error_log /export/Logs/error.log warn;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
if ($request_method = 'OPTIONS') {
return 204;
}
location / {
try_files $uri $uri/ /index.html;
root /export/App/dist/ ;
}
location /vue2App/ {
rewrite ^/vue2App/(.*)$ /$1 break;
proxy_pass http://vue2.xx.com;
}
location /vue3App/ {
rewrite ^/vue3App/(.*)$ /$1 break;
proxy_pass http://vue3.xx.com;
}
location /umiApp/ {
rewrite ^/umiApp/(.*)$ /$1 break;
proxy_pass http://umi.xx.com;
}
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
微应用
vue2微应用
以vue-cli 3+ 生成vue 2.x,webpack4构建项目为例
- 在
src目录新增public-path.js:
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
- 入口文件
main.js修改
- 导入
public-path.js需放在入口文件最顶部 。 - 建议使用
history模式的路由,base设置的值必须与注册时activeRule保持一致。
import './public-path';
import Vue from 'vue';
import App from './App';
import routes from '@/router/index.js';
import VueRouter from 'vue-router';
import store from '@/store';
let router = null;
let instance = null;
function render(props = {}) {
const { container } = props;
Vue.use(VueRouter)
router = new VueRouter({
base: window.__POWERED_BY_QIANKUN__ ? '/vue2/' : '/',
mode: 'history',
routes,
});
instance = new Vue({
store,
router,
template: '<App/>',
components: { App }
}).$mount(container ? container.querySelector('#app') : '#app');
}
// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
export async function bootstrap(props) {
console.log(props);
}
export async function mount(props) {
render(props);
}
export async function unmount() {
instance.$destroy();
instance.$el.innerHTML = '';
instance = null;
router = null;
}
- 打包配置:
output.publicPath在生产环境路径必须要与注册时entry保持一致
// wepack.base.conf.js
const { name } = require('./package.json');
module.exports = {
output: {
library: name,
libraryTarget: 'umd',
jsonpFunction: `webpackJsonp_${name}`,
publicPath: process.env.NODE_ENV === 'production'?'/vue2App/':'/'
}
}
// webpack.dev.conf.js
module.exports = {
devServer: {
headers: {
'Access-Control-Allow-Origin': '*',
'Cache-Control': 'no-cache'
}
}
}
vue3微应用
以vue-cli 4+ 生成vue 3.x,webpack5构建项目为例
- 在
src目录新增public-path.js:
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
- 入口文件
main.js修改
- 导入
public-path.js需放在入口文件最顶部 。 - 建议使用
history模式的路由,base设置的值必须与注册时activeRule保持一致。
import './public-path';
import { createApp } from 'vue';
import App from './App.vue';
import ElementPlus from 'element-plus';
import { createRouter, createWebHistory } from 'vue-router';
import routes from './router';
let router = null;
let instance = null;
let history = null;
function render(props = {}) {
const { container } = props;
history = createWebHistory(window.__POWERED_BY_QIANKUN__ ? '/vue3' : '');
router = createRouter({
history,
routes
})
instance = createApp(App);
instance.use(router).use(ElementPlus);
instance.mount(container ? container.querySelector('#app') : '#app');
}
// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
export async function bootstrap(props) {
console.log(props);
}
export async function mount(props) {
render(props);
}
export async function unmount() {
instance.unmount();
instance._container.innerHTML = '';
instance = null;
router = null;
history.destroy();
}
- 打包配置(vue.config.js):
publicPath在生产环境路径必须要与注册时entry保持一致
const { defineConfig } = require('@vue/cli-service');
const { name } = require('./package.json');
module.exports = defineConfig({
transpileDependencies: true,
devServer: {
headers: {
'Access-Control-Allow-Origin': '*',
'Cache-Control': 'no-cache'
}
},
publicPath: './',
// 上下两种方式均可
// publicPath: process.env.NODE_ENV === 'production'?'/vue3App/':'/',
configureWebpack: {
output: {
library: name,
libraryTarget: 'umd',
chunkLoadingGlobal: `webpackJsonp_${name}`,
}
}
})
- nginx配置:
server {
listen 80;
server_name localhost;
access_log /export/Logs/access.log main;
error_log /export/Logs/error.log warn;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
if ($request_method = 'OPTIONS') {
return 204;
}
location / {
try_files $uri $uri/ /index.html;
root /export/App/dist/ ;
add_header Cache-Control no-cache;
}
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
umi3微应用
以ant-design/pro-cli 2+生成 umi 3.x,webpack5构建项目为例
- 安装qiankun
npm install @umijs/plugin-qiankun
- 入口文件
app.jsx修改
export const qiankun = {
async bootstrap(props) {
console.log('app1 bootstrap', props)
},
async mount(props) {
console.log('app1 mount', props);
},
async unmount(props) {
console.log('app1 unmount', props);
},
};
- 配置qiankun开启(config.js):
base设置的值建议与手动加载微应用时路由保持一致。publicPath在生产环境路径必须要与注册时entry保持一致
export default {
qiankun: {
slave: {}
},
devServer: {
headers: {
'Access-Control-Allow-Origin': '*'
}
},
base: '/rms',
publicPath: process.env.NODE_ENV === 'production' ? '/umiApp/' : '/',
}
- nginx配置同上