Micro-App是京东零售推出的一款微前端框架,基于类WebComponent进行渲染,从组件化的思维实现微前端,能降低前端开发的上手难度、提升工作效率。Micro-App是目前接入微前端成本最低的框架,提供了JS沙箱、样式隔离、元素隔离、预加载、虚拟路由系统、插件系统、数据通信等一系列完善的功能。Micro-App与技术栈无关,不与业务绑定,对前端框架没有限制,任何框架都可以作为基座应用嵌入任何类型的子应用。
微前端由ThoughtWorks在2016年提出,借鉴微服务架构理念,将庞大前端应用拆分为多个独立小型应用,每个应用可独立开发、运行和部署,再融合为完整应用。微前端解决两大问题:
1、迭代应用日益庞大导致的维护困难
2、跨团队协作开发导致的效率低下
许多前端项目经过多年迭代或交接,技术架构落后,新接手者面对冗余项目难以处理。微前端架构减少新旧项目耦合,提升扩展性,前端仓库更小更简单。
常见微前端实现方式包括iframe和微前端框架:
iframe方案:
• 创建独立window窗口,完全隔离
• 天然样式和JS隔离特性
• 实现简单稳定
• 存在问题:性能不高、双滚动条、弹窗无法全局覆盖、刷新路由状态丢失
微前端框架:
• 较早框架如single-spa,负责多应用融合
• qiankun基于single-spa封装,增加样式隔离、JS沙箱等功能
• 接入难度高于iframe,上限更高
Micro-App未沿袭single-spa思路,而是借鉴WebComponent的思想,通过CustomElement结合自定义ShadowDom,将微前端封装成类WebComponent组件,实现组件化渲染。由于自定义ShadowDom的隔离特性,Micro-App不需要子应用修改渲染逻辑或暴露方法,不需修改webpack配置,是目前接入成本最低的微前端方案。
主要特点:
• 使用方式类似iframe,上手简单
• 对原代码几乎无影响,侵入性低
• 基于webComponents思想实现
• 功能完善:JS沙箱,样式隔离,预加载等
• 体积轻量:约10kb(gzip)
• 零依赖,不依赖第三方库
1、安装依赖:
npm i @micro-zoe/Micro-App --save
2、入口文件引入并启动:
import microApp from '@micro-zoe/Micro-App'
microApp.start({
destroy: true
})
3、页面中使用Micro-App组件:
<template>
<div class="container">
<Micro-App name="my-app-page1" url="http://localhost:5173/stand" disableSandbox inline></Micro-App>
</div>
</template>
1、路由配置:
import { createRouter, createWebHashHistory } from "vue-router";
export const routes = [
{
path: "/",
redirect: "/login",
},
{
name: "login",
path: "/login",
component: () => import("@/pages/login.vue"),
}
];
const router = createRouter({
history: createWebHashHistory(),
routes,
});
2、修改容器元素id确保唯一性:
<body>
<div id="my-vite-app"></div>
</body>
3、使用新id渲染:
import { createApp } from "vue";
import App from "./App.vue";
app.mount("#my-vite-app");
4、静态资源使用绝对地址:
new URL('../assets/logo.png', import.meta.url).href
通过EventCenterForMicroApp对象:
import { EventCenterForMicroApp } from '@micro-zoe/Micro-App';
window.eventCenterForAppNameVite = new EventCenterForMicroApp(name);
// 发送消息
microZoeApp.setData(name, { path: route.path });
通过data属性:
<Micro-App :url="url" :name="name" :data="data" />
监听主应用消息:
if (window.eventCenterForAppNameVite) {
window.eventCenterForAppNameVite.addDataListener(data => {
router.replace({ path: data.path })
})
}
获取data属性值:
window.eventCenterForAppNameVite.getData('app-child-vue3')
通过dispatch方法:
window.eventCenterForAppNameVite.dispatch({
from: '来自子系统的消息',
msg: '子应用发送的数据',
});
通过datachange事件:
<Micro-App @datachange="dataChange" />
const dataChange = v => {
console.log(v);
};
主应用和子应用都是vue-router4时可能相互冲突,导致浏览器返回按钮路由错误。解决方案:
if (window.__MICRO_APP_ENVIRONMENT__) {
const realBaseRoute = window.__MICRO_APP_BASE_ROUTE__;
router.beforeEach(() => {
if (typeof window.history.state?.current === 'string') {
window.history.state.current = window.history.state.current.replace(
new RegExp(realBaseRoute, 'g'), '')
}
})
router.afterEach(() => {
if (typeof window.history.state === 'object') {
window.history.state.current = realBaseRoute + (window.history.state.current || '')
}
})
}
克隆并运行项目:
git clone https://github.com/micro-zoe/Micro-App.git
cd Micro-App
yarn bootstrap
yarn start
默认启动主应用main-react16和子应用react16、react17、vue2、vue3、angular11、vite。
单独运行主应用:
yarn start:main-vue2
单独运行子应用:
cd dev/children/react16
yarn start
• 源码地址:http://github.com/micro-zoe/Micro-App
• 官网地址:http://zeroing.jd.com/Micro-App
• iPaaS地址:http://ipaas.jd.com