我正在使用React和Vite创建微前端.我很难完成我想要的路由.

path page
'/' host-app homepage
'/some-tenant' remote-app TenantPage
'/some-tenant/some-subscription' remote-app SubscriptionPage

当运行主机应用程序时,我导航到"/some-tenant",什么也不会出现.当我导航到"/some-tenant/some-sub"时,TenantPage个负载."/tenant/sub/test"加载SubscriptionPage.

我try 了一些方法来让它正常工作,但棘手的部分是我想在独立运行远程应用程序时使用相同的路由.有什么 idea 如何完成both吗?这是一个用于重新创建该问题的存储库.https://github.com/lestersconyers/react-routes/

摘录供参考

主机应用程序.tsx

const RemoteRootApp = lazy(() => import('remoteApp/RemoteRootApp') as any);

function App() {
  return (
    <div className="app">
      <React.Suspense fallback="Loading">
        <Routes>
          <Route path="/" element={<HomePage />} />
          <Route path=":tenant" element={<RemoteRootApp />} />
          <Route path=":tenant/*" element={<RemoteRootApp />} />
        </Routes>
      </React.Suspense>
    </div>
  )
}

远程应用程序App.tsx

function App() {
  return (
    <div className="app">
      <Routes>
        <Route path=":tenant" element={<TenantPage />} />
        <Route path=":tenant/:subscription" element={<SubscriptionPage />} />
        <Route
          path=":tenant/:subscription/manage"
          element={<ManageSubscriptionPage />}
        />
      </Routes>
    </div>
  )
}

remote-app main.tsx

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>,
)

推荐答案

Issue

如果"远程应用程序"在"主应用程序"的"/:tenant/*"路由路径上呈现,则其所有子路由将构建101至此父路由路径.问题是"远程应用程序"有一个额外的"重叠"/"重复""租户"路径段,该路径段混淆了您期望匹配的内容.

您现在拥有的内容,以及标记的匹配路由:

主机应用程序.tsx

const RemoteRootApp = lazy(() => import('remoteApp/RemoteRootApp') as any);

function App() {
  return (
    <div className="app">
      <React.Suspense fallback="Loading">
        <Routes>
          <Route path="/" element={<HomePage />} />

          {/* Matches
            *   - "/some-tenant/some-sub"
            *   - "/tenant/sub/test"
            *   - "/some-tenant"
            */}
          <Route path="/:tenant/*" element={<RemoteRootApp />} />
        </Routes>
      </React.Suspense>
    </div>
  );
}

远程应用程序App.tsx

function App() {
  return (
    <div className="app">
      <Routes>
        {/* Nothing matches "/some-tenant" */}

        <Route
          // "/:tenant/:tenant" matches "/some-tenant/some-sub"
          path=":tenant"
          element={<TenantPage />}
        />
        <Route
          // "/:tenant/:tenant/:subscription" matches "/tenant/sub/test"
          path=":tenant/:subscription"
          element={<SubscriptionPage />}
        />
        <Route
          path=":tenant/:subscription/manage"
          element={<ManageSubscriptionPage />}
        />
      </Routes>
    </div>
  );
}

Solution

您希望在"远程应用程序"中省略前面的"重复"tenant路径段.

远程应用程序App.tsx

function App() {
  return (
    <div className="app">
      <Routes>
        {/* Nothing matches "/tenant/sub/test" */}

        <Route
          // "/:tenant" matches "/some-tenant"
          path="/"
          element={<TenantPage />}
        />
        <Route
          // "/:tenant/:subscription" matches "/some-tenant/some-sub"
          path="/:subscription"
          element={<SubscriptionPage />}
        />
        <Route
          path="/:subscription/manage"
          element={<ManageSubscriptionPage />}
        />
      </Routes>
    </div>
  );
}

当"远程应用程序"单独运行时,您可以通过basename Prop向路由提供根tenant路径段,并且所有路由/链接/等将相对于this路径起作用.

import { BrowserRouter } from 'react-rotuer-dom';

...

<BrowserRouter basename="/some-tenant">
  {/* Remote App */}
  <RootApp />
</BrowserRouter>

Typescript相关问答推荐

具有映射返回类型的通用设置实用程序

当类型断言函数返回假时,TypScript正在推断从不类型

TypeScript Page Routing在单击时不呈现子页面(React Router v6)

输入元素是类型变体的对象数组的正确方法是什么?'

如何使用Zod使一个基于其他字段值的字段为必填字段?

泛型类型联合将参数转换为Never

如何从扩展接口推断泛型?

Fp-ts使用任务的最佳方法包装选项

将带点的对象键重新映射为具有保留值类型的嵌套对象

将对象的属性转换为正确类型和位置的函数参数

为什么发送空字段?

抽象类对派生类强制不同的构造函数签名

如何从上传文件中删除预览文件图标?

如何在具有嵌套数组的接口中允许新属性

如何为带有参数的函数类型指定类型保护?

VUE 3类型';字符串';不可分配给类型';参考<;字符串&>

如何在TypeScript中描述和实现包含特定属性的函数?

Typescript 和 Rust 中跨平台的位移数字不一致

Select 器数组到映射器的Typescript 泛型

为什么 typescript 在对象合并期间无法判断无效键?