前言
最近公司由于项目里模块太多,导致项目很是繁冗,所以想说把部分业务抽离出来分开维护。经过讨论之后,决定使用qiankun来进行处理。然后我也是做了一个demo来实践了一下。那什么是qiankun以及qiankun的优缺点我们这里不讨论,本文纯粹是告诉大家如何使用qiankun来集成微前端服务。
主项目改造
我们的主项目是一个sass管理系统,布局就是左侧菜单+右侧内容这样,需求就是把菜单的一部分给抽离出去单独维护,然后主项目的功能保持不变。我的demo主项目页面如下图所示:
路由文件是正常写的,如下:
好,可以看到,其实主项目就跟平常项目一样。接下来我们在主项目开始安装qiankun
yarn add qiankun # 或者 npm i qiankun -S
然后注册微应用,我这里新建了一个micros文件夹,里面一个js文件,如下图:
js文件里代码如下,我这是已经约定好了我配置的微应用的名称等信息,因为我是本地启动的,所以写的本地url,里面配置的意思可以去看文档,我们这里不多说
import { registerMicroApps, start } from 'qiankun';
registerMicroApps([
{
name: 'micro-project', // 微应用名
entry: '//localhost:8081', // 微应用运行域名,与微应用的devServer port相对应
container: '#micro', // 微应用挂载的DOM容器
activeRule: '/micro', // 微应用触发规则,当url有与之匹配的情况时,启动微应用
},
]);
export default start; // 启动qiankun的方法
到这里,qiankun在主项目的配置已经完成,是不是很简单。接下来我们要考虑这个start方法要在哪里运行,我想的是根据监听路由的变化来运行微应用,在上图的路由文件中我们是有两个微应用的路由的,所以就是当路由切换到微应用的路由就执行start。那如何判断是否进入呢,要知道,我们之后是要把这两个微应用的路由抽离出去的,配套的页面也是一样。其实路由是可以不写component的,同时还有个meta属性让我们加一些路由配置,修改后的路由文件如下图所示:
布局页router-view的展示也要一起判断一下
layouts.vue
<div class="content">
<router-view v-show="!isSubApp" />
<div v-show="isSubApp">
<div id="micro"></div>
</div>
</div>
watch: {
$route: {
handler() {
if (this.isSubApp) {
this.subAppInit();
}
},
immediate: true,
},
},
computed: {
isSubApp() {
return this.$route.meta.isSubApp;
},
},
methods: {
subAppInit() {
start();
},
},
ok,到这里,主项目改造完成,接下来我们进行子项目的改造
子项目改造
我们这里就直接新建一个项目,先什么都不改,按照qinakun的文档添加一些内容
1.在 src 目录新增 public-path.js:
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
2.修改mian.js,把原来的new Vue({})这些删除,我代码贴一下:
let router = null;
let instance = null;
function render(props = {}) {
const { container } = props;
router = new VueRouter({
//这里注意一下 当在qiankun环境下时 router要加一个前缀,跟主项目路由保持一致
base: window.__POWERED_BY_QIANKUN__ ? '/micro' : '/',
mode: 'history',
routes,
});
instance = new Vue({
router,
store,
render: (h) => h(App),
}).$mount(container ? container.querySelector('#micro') : '#micro'); //子项目根节点改一下,避免冲突
}
// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
export async function bootstrap() {
console.log('[vue] vue app bootstraped');
}
export async function mount(props) {
console.log('[vue] props from main framework', props);
render(props);
}
export async function unmount() {
instance.$destroy();
instance.$el.innerHTML = '';
instance = null;
router = null;
}
router如下:
3.打包配置修改(
vue.config.js):
const { name } = require('./package');
module.exports = {
devServer: {
headers: {
'Access-Control-Allow-Origin': '*',
},
},
configureWebpack: {
output: {
library: `${name}-[name]`,
libraryTarget: 'umd', // 把微应用打包成 umd 库格式
jsonpFunction: `webpackJsonp_${name}`, // webpack 5 需要把 jsonpFunction 替换成 chunkLoadingGlobal
},
},
};
到此,子项目改造结束,看看页面吧
加载出来了!!!
本文纯教程,同时也是个demo示例,没考虑一些css方面的覆盖和生产配置啥的,有说的不详细的地方可以评论区讨论~~~