自从前后端分离以来,一直都有个困惑,就是随着项目的功能的不断拓展,项目变得不断臃肿,每次打包编译,都要把整个项目编译,非常耗时。如果前端也能像后端一样,在项目搭建初期,有类似微服务的功能,那就好了。现在qiankun 可以实现前端项目的微前端功能。
qiankun官网:qiankun - qiankun
最近在开发vue2的项目,前端主框架依赖于若依,于是就拿着现有项目试了一下。几番周折,终于成功了。
部署步骤可以移步到官网,下面是自己改造的主要步骤。
主应用:
(主应用除了官方贴出的配置信息外,还有路由权限(路由守卫)的修改,否则就会进入404页面了,这个问题困扰我很久)
一、安装依赖包qiankun
yarn add qiankun
二、修改 main.js
import { registerMicroApps, start } from 'qiankun';
/**
* Step1 定义对应的微前端应用
*/
const apps = [
{
name: 'subapp',
entry: '//localhost:9091', // 子应用实际启动地址
container: '#subapp-viewport',// 子应用在主应用展示容器的id
activeRule: '/subapp', // 引入子应用的路由地址
},
];
/**
* Step2 注册
*/
registerMicroApps(apps, {
beforeLoad: [
(app) => {
console.log(`${app.name}的beforeLoad阶段`);
},
],
beforeMount: [
(app) => {
console.log(`${app.name}的beforeMount阶段`);
},
],
afterMount: [
(app) => {
console.log(`${app.name}的afterMount阶段`);
},
],
beforeUnmount: [
(app) => {
console.log(`${app.name}的beforeUnmount阶段`);
},
],
afterUnmount: [
(app) => {
console.log(`${app.name}的afterUnmount阶段`);
},
],
});
/**
* Step3 设置默认进入的子应用
*/
setDefaultMountApp('/subapp');
/**
* Step4 启动应用
*/
start();
三、App.vue 中添加容器(显示对应子应用的容器)
<template>
<div id="app">
<router-view />
<div id="subapp-viewport"></div>
</div>
</template>
四、配置代理
由于通过主应用IP地址访问子应用,此时子应用接口地址默认调用的主应用的配置的相关配置。在主应用 vue.config.js用添加 。具体微应用代理地址说明
proxy: {
// 微应用的代理
['/subapp'+process.env.VUE_APP_BASE_API]: {
target: `http://1.1.1.1:7070`, // 调用后端服务的地址
changeOrigin: true,
logLevel: 'debug',// 可以在控制台中看到调用接口代理后的真实地址
pathRewrite: {
["^/subapp" + process.env.VUE_APP_BASE_API]: process.env.VUE_APP_BASE_API,
},
},
// 主应用代理地址
[process.env.VUE_APP_BASE_API]: {
target: `http://1.1.1.2:6070`,// 调用后端服务的地址
changeOrigin: true,
logLevel: 'debug',
pathRewrite: {
["^" + process.env.VUE_APP_BASE_API]: process.env.VUE_APP_BASE_API,
},
},
},
子应用:
子应用主要是对路由信息的修改【子应用不需要安装qiankun包】。
一、新增 src/public-path.js (可以去官网复制粘贴内容)
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
console.log(window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__);
}
二、修改main.js
在mian.js最顶部引入public-path.js
把vue实例化 封装成render函数,由于子应用可以独立运行,也可以通过主应用打开,此时需要借助qiankun 插件主应用的为window添加的全局变量 __POWERED_BY_QIANKUN__ 来判断进入子应用的模式。
function render(props = {}) {
const { container } = props;
new Vue({
router,
store,
render: (h) => h(App),
}).$mount(container ? container.querySelector('#app') : '#app');
}
// 独立运行时
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() {
}
三、路由的修改
思考一下,对于子应用的中的菜单导航,在独立运行和在通过主应用点击对应的菜单,他们地址是要做出区别的,所以需要再实例化路由的时候,对运行环境做出判断,对路由 base属性添加属性值。
export default new Router({
base: window.__POWERED_BY_QIANKUN__ ? `/subapp` : '/',
mode: 'history', // 去掉url中的#
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes
})
需要特别注意的是,如果是主应用调用的子应用,此时base值就是主应用配置main.js中子自用用 activeRule的值。
四、vue.config.js修改
由于主应用、子应用都是独立部署,主应用调用子应用功能时候,就会出现跨域的问题,所以需要在子应用中添加允许跨域
devServer: {
host: "",
port: port,
headers: {
'Access-Control-Allow-Origin': '*',
},
open: true,
proxy: {
// detail: https://cli.vuejs.org/config/#devserver-proxy
[process.env.VUE_APP_BASE_API]: {
target: `http://10.10.10.10:2020`,
changeOrigin: true,
logLevel: 'debug',
pathRewrite: {
["^" +process.env.VUE_APP_BASE_API]: process.env.VUE_APP_BASE_API,
},
},
},
disableHostCheck: true,
},
配置子应用的打包模式
const packageName = require('./package.json').name;
module.exports = {
output: {
library: `${packageName}-[name]`,
libraryTarget: 'umd',
jsonpFunction: `webpackJsonp_${packageName}`,
},
};
配置到此处,正常情况下就可以实现主应用中调用子应用的页面地址了,如登录界面(不需要调用后端接口的模块)。
如果要实现主应用中调用子应用,子应用中对应的接口信息能够正常返回后端数据,需要往下看
qiankun 部署微前端-vue2 (二)_wuyu0920的博客-CSDN博客