---
title: useModuleApps
---
# useModuleApps

返回所有微前端子应用的 React 组件，用于可自由控制路由。

## 使用姿势

```tsx
import { useModuleApps } from '@modern-js/plugin-garfish/runtime';
```

## 函数签名

`function useModuleApps(): Record<string, React.FC<any>>`

分别返回包裹每个子应用后的 React 组件。

## 示例

需要先配置微前端子应用信息。

import EnableMicroFrontend from "@site-docs/components/enable-micro-frontend";

<EnableMicroFrontend />

这里演示主应用为自控式路由的场景，全部场景参考 [体验微前端](/guides/topic-detail/micro-frontend/c02-development.html)
```tsx title=App.tsx
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 MicroRuntimeConfig from "@site-docs/components/micro-runtime-config";

<MicroRuntimeConfig />

然后在主应用中使用 `useModuleApp` 方法获取 `MApp` 组件, 并在主应用渲染 `MApp`。

```tsx title=主应用：App.tsx
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` 子应用。

## 加载动画

可以通过以下方式，自定义组件加载过程的过渡动画。

```js title="App.tsx"
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} />
    </>
  );
};
```
