方案选型:无界(wujie-micro.github.io/doc/)
微前端使用场景:
- 比如制作一个企业管理平台,把已有的采购系统和财务系统统一接入这个平台;
- 比如有一个巨大的应用,为了降低开发和维护成本,分拆成多个小应用进行开发和部署,然后用一个平台将这些小应用集成起来;
- 又比如一个应用使用
vue框架开发,其中有一个比较独立的模块,开发者想尝试使用react框架来开发,等模块单独开发部署完,再把这个模块应用接回去
实际用例:在目前的超视界前端项目中使用了wujie-vue3的插件,改造为主应用,将另一个项目做为子应用接入
父应用改造实现步骤
- 安装wujie
npm i wujie-vue3 -S
Plain Text
- 修改 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
- 添加子应用路由
{ path: '/vue3', name: 'vue3', component: () => import('@/pages/vue3/index.vue'), meta: { key: 'vue3', pageName: 'vue3', hide: true },}
JavaScript
- 添加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");}