最近项目中遇到了一个问题,那就是老项目和新项目迭代的问题。
老项目能正常用,但是新的项目要替换,原有的功能集成在新项目直接使用会影响到进度。
于是想到了用微前端,将新的老的放在不同的项目中运行。
框架当然是用的qiankun,这是我认为国人比较习惯,也比较成熟的框架了。当然也可以集成不同技术的框架。
这里我用的是vue3做的基座项目。主应用:
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import { registerMicroApps, start, setDefaultMountApp } from "qiankun";
createApp(App)
.use(store)
.use(router)
.mount("#app");
registerMicroApps([
{
name: "vue2 app", // app name registered
entry: "//localhost:7101", // 子应用入口
container: "#yourContainer",
activeRule: "/vue2",
},
]);
// 启动默认应用
setDefaultMountApp("/vue2");
start();
子应用
import Vue from "vue";
import VueRouter from "vue-router";
import App from "./App.vue";
import routes from "./router";
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
// import './public-path';
Vue.config.productionTip = false;
Vue.use(ElementUI)
let router = null;
let instance = null;
function render(props = {}) {
const { container } = props;
router = new VueRouter({
base: "/vue2",
mode: "history",
routes,
});
instance = new Vue({
router,
render: (h) => h(App),
}).$mount(container ? container.querySelector("#app") : "#app");
}
// webpack打包公共文件路径
if (window.__POWERED_BY_QIANKUN__) {
// eslint-disable-next-line no-undef
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}else{
// 独立运行
render();
}
// 生命周期
export async function bootstrap() {
console.log("[vue] vue app bootstraped");
}
export async function mount(props) {
console.log("[vue] props from main framework", props);
// storeTest(props);
render(props);
}
export async function unmount() {
instance.$destroy();
instance.$el.innerHTML = "";
instance = null;
router = null;
}
主应用入口
<template>
<div id="nav">
<!-- 子应用容器 -->
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link> |
<a href="/vue2">vue</a>
<div id="yourContainer" style="width: 100%; border: 1px solid #ccc"></div>
</div>
<router-view />
</template>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
#nav {
padding: 30px;
}
#nav a {
font-weight: bold;
color: #2c3e50;
}
#nav a.router-link-exact-active {
color: #42b983;
}
</style>
子应用添加打包配置vue.config.js
const path = require('path');
const { name } = require('./package');
function resolve(dir) {
return path.join(__dirname, dir);
}
const port = 7101; // dev port
module.exports = {
outputDir: 'dist',
assetsDir: 'static',
filenameHashing: true,
devServer: {
// host: '0.0.0.0',
hot: true,
disableHostCheck: true,
port,
overlay: {
warnings: false,
errors: true,
},
// 跨域
headers: {
'Access-Control-Allow-Origin': '*',
},
},
// 自定义webpack配置
configureWebpack: {
resolve: {
alias: {
'@': resolve('src'),
},
},
output: {
// 把子应用打包成 umd 库格式(必须)
library: `${name}-[name]`,
libraryTarget: 'umd',
jsonpFunction: `webpackJsonp_${name}`,
},
},
};
下一篇文章再讲一下应用之间的传值与样式问题。当然参考中都写的非常明白,也可以查看官网参考 https://qiankun.umijs.org/zh