前言
之前已经实践过阿里微前端框架 qiankun,现在来使用一下京东推出的微前端解决方案 - MicroApp。
一、micro-app 的优势
single-spa 是通过监听 url change 事件,在路由变化时匹配到渲染的子应用并进行渲染。
micro-app 并没有沿袭 single-spa 的思路,而是借鉴了 WebComponent 的思想,通过 CustomElement 结合自定义的 ShadowDom,将微前端封装成一个类 WebComponent 组件,从而实现微前端的组件化渲染。并且由于自定义 ShadowDom 的隔离特性,micro-app 不需要像 single-spa 和 qiankun 一样要求子应用修改渲染逻辑并暴露出方法,也不需要修改 webpack 配置,是目前市面上接入微前端成本最低的方案。
二、基座应用
1⃣️、首先搭建 vue3 项目为基座应用
2⃣️、安装依赖
npm i @micro-zoe/micro-app --save
3⃣️、在入口文件 main.ts 中引入
// main.ts
import microApp from '@micro-zoe/micro-app'
microApp.start()
4⃣️、配置路由
import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router";
const routes: Array<RouteRecordRaw> = [
{
path: "/",
name: "home",
component: () => import("@/components/MyHome.vue"),
children: [
{
path: "/",
name: "hello",
component: () => import("@/views/HomeView.vue"),
},
// react-app 子应用路由
{
path: "/reactApp/:page*",
name: "reactApp",
component: () => import("@/views/MicroApp/ReactApp.vue"),
},
],
},
];
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
});
export default router;
5⃣️、嵌入子应用
<template>
<h1>react-app 子应用</h1>
<!-- name(必传):应用名称
url(必传): 应用地址
baseroute(可选):基座应用分配给子应用的基础路由 -->
<micro-app
name="react-app"
url="http://localhost:3000/"
baseroute="/reactApp"
></micro-app>
</template>
三、子应用
1⃣️、使用 create-react-app 搭建 react 子应用。
npx create-react-app react-app --template typescript
npm i react-router-dom
2⃣️、修改 webpack 配置,设置跨域支持
headers: {
'Access-Control-Allow-Origin': '*',
}
3⃣️、设置基础路由(如果基座是history路由,子应用是hash路由,这一步可以省略)
// router.js
import { BrowserRouter, Switch, Route } from 'react-router-dom'
export default function AppRoute () {
return (
// 👇 设置基础路由,如果没有设置baseroute属性,则window.__MICRO_APP_BASE_ROUTE__为空字符串
<BrowserRouter basename={window.__MICRO_APP_BASE_ROUTE__ || '/'}>
...
</BrowserRouter>
)
}
4⃣️、设置 publicPath,避免子应用的静态资源使用相对地址时加载失败
创建文件 src/public-path.ts
// __MICRO_APP_ENVIRONMENT__和__MICRO_APP_PUBLIC_PATH__是由micro-app注入的全局变量
if(window.__MICRO_APP_ENVIRONMENT__) {
// eslint-disable-next-line
__webpack_public_path__ = window.__MICRO_APP_PUBLIC_PATH__
}
在子应用入口文件的最顶部
引入 public-path.ts
import './public-path';
5⃣️、监听卸载
// 监听卸载操作
window.addEventListener('unmount', function () {
ReactDOM.unmountComponentAtNode(document.getElementById('root'))
})