微前端是一种多个团队通过独立发布功能的方式来共同构建现代化 web 应用的技术手段及方法策略,下面这张图来了解下。
qiankun
qiankun 蚂蚁金服基于single-spa 的微前端解决方案,生产可用。
特性
基于 single-spa 封装,提供了更加开箱即用的 API。
技术栈无关,任意技术栈的应用均可 使用/接入,不论是 React/Vue/Angular/JQuery 还是其他等框架。
HTML Entry 接入方式,让你接入微应用像使用 iframe 一样简单。
样式隔离,确保微应用之间样式互相不干扰。
JS 沙箱,确保微应用之间 全局变量/事件 不冲突。
资源预加载,在浏览器空闲时间预加载未打开的微应用资源,加速微应用打开速度。
主应用搭建
选择用 vue-cli 初始化了主应用,不了解的可自行阅读官方文档
项目中引入 qiankun :
$ yarn add qiankun # 或者 npm i qiankun -S
复制代码
注册微应用
定义需要加载的微应用
// src/micro/apps.ts
//此时我们还没有微应用,所以暂时为空
const apps: any = [
];
export default apps;
复制代码
注册微应用并对外暴露方法
// src/micro/index.ts
import {
registerMicroApps,
addGlobalUncaughtErrorHandler,
start,
} from “qiankun”;
import NProgress from “nprogress”;
import { Message } from ‘element-ui’;
import ‘nprogress/nprogress.css’;
NProgress.configure({ parent: ‘.scrollbar.scroll’ });
export default function (apps: []) {
registerMicroApps(apps, {
beforeLoad: () => {
// 加载微应用前,加载进度条
NProgress.start();
return Promise.resolve();
},
afterMount: () => {
NProgress.done();
return Promise.resolve();
},
});
addGlobalUncaughtErrorHandler((event: any) => {
const { msg } = event as any;
NProgress.done();
// 加载失败时提示
if (msg && msg.includes("died in status LOADING_SOURCE_CODE")) {
Message.error('微应用加载失败,请检查应用是否可运行');
}
});
start();
}
复制代码
由于我们的微应用可能是登录后,根据用户左侧菜单权限而生成该用户的微应用。所以,暴露方法以及入参方便登录完成调用注册微应用。
启动微应用
import startQiankun from “@/micro”;
startQiankun(…); //在需要启动的地方调用传入数据就行
复制代码
这边是我在全局路由守卫处启动,供大家参考。
//router
import Vue from ‘vue’;
import VueRouter, { RouteConfig } from ‘vue-router’;
import store from “@/store”;
import { getToken } from “@/utils/auth”;
import startQiankun from “@/micro”;
import apps from “@/micro/apps”;
Vue.use(VueRouter);
const routes: Array = [
{
path: ‘/login’,
name: ‘login’,
component: () => import(’@/views/login/index.vue’)
},
{
path: ‘/’,
name: ‘main’,
component: () => import(’@/views/Layout/index.vue’),
children: [
{
path: ‘’,
name: ‘Home’,
component: () => import(’@/views/Home.vue’)
}
]
},
{
path: ‘*’,
name: ‘redirect’,
redirect: ‘/’
}
];
const createRouter: any = () => new VueRouter({
mode: “history”,
routes,
});
const router: any = createRouter()
/**