微前端改造

294 阅读1分钟

方案选型:无界(wujie-micro.github.io/doc/)

微前端使用场景:

  • 比如制作一个企业管理平台,把已有的采购系统和财务系统统一接入这个平台;
  • 比如有一个巨大的应用,为了降低开发和维护成本,分拆成多个小应用进行开发和部署,然后用一个平台将这些小应用集成起来;
  • 又比如一个应用使用vue框架开发,其中有一个比较独立的模块,开发者想尝试使用react框架来开发,等模块单独开发部署完,再把这个模块应用接回去

实际用例:在目前的超视界前端项目中使用了wujie-vue3的插件,改造为主应用,将另一个项目做为子应用接入

父应用改造实现步骤

  1. 安装wujie
npm i wujie-vue3 -S
Plain Text
  1. 修改 main.js 文件
// 引入无界微前端import WujieVue from 'wujie-vue3';import lifecycles from './config/lifecycle';const { setupApp, preloadApp, bus } = WujieVue;bus.$on('click', (msg) => window.alert(msg));
// 在 xxx-sub 路由下子应用将激活路由同步给主应用,主应用跳转对应路由高亮菜单栏bus.$on('sub-route-change', (name, path) => {    const mainName = `${name}-sub`;    const mainPath = `/${name}-sub${path}`;    const currentName = router.currentRoute.name;    const currentPath = router.currentRoute.path;    if (mainName === currentName && mainPath !== currentPath) {        router.push({ path: mainPath });    }});
export const app = createApp(App);app.use(WujieVue);
const props = {    jump: (name) => {        router.push({ name });    },};
// 设置子应用demosetupApp({    name: 'vue3',    url: 'http://localhost:7300/',    exec: true,    props,    fetch: function fetch(url, options) {        return window.fetch(url, { ...options, credentials: 'omit' });    },    ...lifecycles,});
// 预加载,可以极大的提升子应用首次打开速度// 资源的预加载会占用主应用的网络线程池// 资源的预执行会阻塞主应用的渲染线程preloadApp({    name: 'vue3',});

JavaScript
  1. 添加子应用路由
{	path: '/vue3',	name: 'vue3',	component: () => import('@/pages/vue3/index.vue'),	meta: { key: 'vue3', pageName: 'vue3', hide: true },}
JavaScript
  1. 添加lifecycles文件
// 无界提供一整套的生命周期钩子供开发者调用// 如果子应用没有做生命周期的改造,那么 beforeMount、afterMount、beforeUnmount、afterUnmount 这四个生命周期将不会调用
const lifecycles = {    beforeLoad: (appWindow) => console.log(`${appWindow.__WUJIE.id} beforeLoad 生命周期`),    beforeMount: (appWindow) => console.log(`${appWindow.__WUJIE.id} beforeMount 生命周期`),    afterMount: (appWindow) => console.log(`${appWindow.__WUJIE.id} afterMount 生命周期`),    beforeUnmount: (appWindow) => console.log(`${appWindow.__WUJIE.id} beforeUnmount 生命周期`),    afterUnmount: (appWindow) => console.log(`${appWindow.__WUJIE.id} afterUnmount 生命周期`),    activated: (appWindow) => console.log(`${appWindow.__WUJIE.id} activated 生命周期`),    deactivated: (appWindow) => console.log(`${appWindow.__WUJIE.id} deactivated 生命周期`),    loadError: (url, e) => console.log(`${url} 加载失败`, e),};export default lifecycles;
JavaScript

子应用改造(vue3)

if (window.__POWERED_BY_WUJIE__) {  let instance;  window.__WUJIE_MOUNT = () => {    const router = createRouter({ history: createWebHistory(), routes });    instance = createApp(App);    instance.use(router);    instance.mount("#app");  };  window.__WUJIE_UNMOUNT = () => {    instance.unmount();  };} else {  createApp(App).use(createRouter({ history: createWebHistory(), routes })).mount("#app");}