返回所有微前端子应用的 React 组件,用于可自由控制路由。
import { useModuleApps } from '@modern-js/plugin-garfish/runtime';
function useModuleApps(): Record<string, React.FC<any>>
分别返回包裹每个子应用后的 React 组件。
需要先配置微前端子应用信息。
import { appTools, defineConfig } from '@modern-js/app-tools';
import { garfishPlugin } from '@modern-js/plugin-garfish';
export default defineConfig({
runtime: {
router: true,
masterApp: {
apps: [{
name: 'Table',
entry: 'http://localhost:8081',
// activeWhen: '/table'
}, {
name: 'Dashboard',
entry: 'http://localhost:8082'
// activeWhen: '/dashboard'
}]
},
},
plugins: [appTools(), garfishPlugin()],
});
这里演示主应用为自控式路由的场景,全部场景参考 体验微前端
function App() {
const { apps, MApp, Table, Dashboard } = useModuleApps();
// 使用的不是 MApp 组件,需要使用 createBrowserRouter 来创建路由
const router = createBrowserRouter(
createRoutesFromElements(
<Route path="/" element={<AppLayout />}>
<Route key={'table'} path={'table/*'} element={<Table />} />
<Route key={'dashboard'} path={'dashboard/*'} element={<Dashboard />} />
</Route>
)
);
return (
// 方法一:使用 MApp 自动根据配置的 activeWhen 参数加载子应用(本项目配置在 modern.config.ts 中)
// <BrowserRouter>
// <MApp />
// </BrowserRouter>
// 方法二:手动写 Route 组件方式加载子应用,方便于需要鉴权等需要前置操作的场景
<>
<RouterProvider router={router} />
</>
);
}
defineConfig(App, {
masterApp: {
apps: [
{
// name 区分大小写,name 提供的是什么 useModuleApps 返回的就是什么
name: 'Table',
entry: 'http://127.0.0.1:8081/',
},
{
name: 'Dashboard',
entry: 'http://localhost:8082',
},
],
},
});
通过 useModuleApps()
获取到 Table
和 Dashboard
子应用组件(名称和配置里的 name
字段对应),之后就可以像使用普通的 React 组件一样去加载子应用。
集中式路由 是将子应用的激活路由集中配置的方式。我们给子应用列表信息添加 activeWhen
字段来启用 集中式路由。
import { defineConfig } from '@modern-js/runtime';
defineConfig(App, {
masterApp: {
apps: [{
name: 'Table',
entry: 'http://localhost:8081',
// activeWhen: '/table'
}, {
name: 'Dashboard',
entry: 'http://localhost:8082'
// activeWhen: '/dashboard'
}]
},
});
然后在主应用中使用 useModuleApp
方法获取 MApp
组件, 并在主应用渲染 MApp
。
import { useModuleApp } from '@modern-js/plugin-runtime';
function App() {
const { MApp } = useModuleApps();
return (
<div>
<MApp />
</div>
);
}
defineConfig(App, {
masterApp: {
apps: [
{
// name 区分大小写,name 提供的是什么 useModuleApps 返回的就是什么
name: 'Table',
activeWhen: '/table',
entry: 'http://127.0.0.1:8081/',
},
{
name: 'Dashboard',
activeWhen: '/dashboard',
entry: 'http://localhost:8082',
},
],
},
});
这样启动应用后,访问 /dashboard
路由,会渲染 Dashboard
子应用,访问 /table
路由,会渲染 Table
子应用。
可以通过以下方式,自定义组件加载过程的过渡动画。
import { useModuleApps } from '@modern-js/plugin-garfish/runtime';
import { RouterProvider, Route, createBrowserRouter, createRoutesFromElements, BrowserRouter, Link, Outlet } from '@modern-js/runtime/router';
const AppLayout = () => (
<>
<div><Link to={'/table'}>加载约定式路由子应用</Link></div>
<div><Link to={'/dashboard'}>加载自控式路由子应用</Link></div>
<div><Link to={'/'}>卸载子应用</Link></div>
<Outlet />
</>
)
export default () => {
const { apps } = useModuleApps();
// 使用的不是 MApp 组件,需要使用 createBrowserRouter 来创建路由
const router = createBrowserRouter(
createRoutesFromElements(
<Route path="/" element={<AppLayout />}>
{apps.map(app => {
const { Component } = app;
// 模糊匹配,path 需要写成类似 abc/* 的模式
return (
<Route
key={app.name}
path={`${app.name.toLowerCase()}/*`}
element={
<Component
loadable={{
loading: ({ pastDelay, error }: any) => {
if (error) {
return <div>error: {error?.message}</div>;
} else if (pastDelay) {
return <div>loading</div>;
} else {
return null;
}
},
}}
/>
}
/>
)
})}
</Route>
)
);
return (
<>
<RouterProvider router={router} />
</>
);
};