【问题标题】:How to create micro frontends based on different technologies using a common shell with module federation and NX?如何使用带有模块联合和 NX 的通用 shell 创建基于不同技术的微前端?
【发布时间】:2022-12-15 22:55:06
【问题描述】:

我正在尝试使用 Webpacks Module Federation 在基于 React(主机/shell)的 shell 应用程序中使用 React 和 Angular(遥控器)创建微前端。

因此我使用了NX提供的官方文档--> Advanced Angular Micro Frontends with Dynamic Module Federation

这是我所做的:

1. npx create-nx-workspace pace-microfrontends
2. npm install @nrwl/react --save-dev
3. npm install @nrwl/angular --save-dev
4. npx nx g @nrwl/react:host shell
5. npx nx g @nrwl/angular:remote angular-microfrontend --host=shell
6. npx nx g @nrwl/react:remote react-microfrontend --host=shell

因此,我创建了一个新的 NX 工作区,添加了缺失的依赖项,生成了基于 React 的 shell/主机应用程序,并添加了两个应该托管在 shell 中的微前端(一个基于 React,一个基于 Angular)。

之后需要将缺少的路由添加到 shell 中的 Angular 微前端,因为它不像 React 微前端那样由 NX​​ 生成,如下所示:

应用程序/shell/src/app/app.tsx

import * as React from 'react';
import NxWelcome from './nx-welcome';
import { Link, Route, Routes } from 'react-router-dom';

const ReactMicrofrontend = React.lazy(
  () => import('react-microfrontend/Module')
);

const AngularMicrofrontend = React.lazy(
  () => import('angular-microfrontend/Module')
);

export function App() {
  return (
    <React.Suspense fallback={null}>
      <ul>
        <li>
          <Link to="/">Home</Link>
        </li>
        <li>
          <Link to="/react-microfrontend">ReactMicrofrontend</Link>
        </li>
        <li>
          <Link to="/angular-microfrontend">AngularMicrofrontend</Link>
        </li>
      </ul>
      <Routes>
        <Route path="/" element={<NxWelcome title="shell" />} />
        <Route path="/react-microfrontend" element={<ReactMicrofrontend />} />
        <Route
          path="/angular-microfrontend"
          element={<AngularMicrofrontend />}
        />
      </Routes>
    </React.Suspense>
  );
}

export default App;

由于模块联合配置也不正确(找不到 remoteEntry.js 文件),我也不得不将其更改为:

应用程序/shell/module-federation.config.js

// @ts-check

/**
 * @type {import('@nrwl/devkit').ModuleFederationConfig}
 **/
const moduleFederationConfig = {
  name: 'shell',
  remotes: [react-microfrontend'],
};

module.exports = moduleFederationConfig;

..对此:

应用程序/shell/module-federation.config.js

// @ts-check

/**
 * @type {import('@nrwl/devkit').ModuleFederationConfig}
 **/
const moduleFederationConfig = {
  name: 'shell',
  remotes: [
    ['angular-microfrontend', 'http://localhost:4201/remoteEntry.mjs'],
    ['react-microfrontend', 'http://localhost:4202/remoteEntry.js'],
  ],
};

module.exports = moduleFederationConfig;

在这些调整之后,可以使用npm start 启动 shell 应用程序。

HomeReactMicrofrontend 的路由工作正常,但只要我点击AngularMicrofrontend,我就会收到以下错误:

react_devtools_backend.js:4012 警告:懒惰:预期的结果 动态 import() 调用。而是收到:[对象模块]

您的代码应如下所示:const MyComponent = lazy(() => 导入('./MyComponent')) 在 RenderedRoute (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:4840:5) 在路线 (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:5272:5) 在悬念 在应用 在路由器 (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:5204:15) 在 BrowserRouter (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:3464:5) overrideMethod @ react_devtools_backend.js:4012 printWarning @ react.development.js:209 错误@react.development.js:183 lazyInitializer @ react.development.js:1400 resolveLazy @ react-dom.development.js:14907 reconcileSingleElement @ react-dom.development.js:15718 reconcileChildFibers @ react-dom.development.js:15808 reconcileChildren @ react-dom.development.js:19174 updateContextProvider @ react-dom.development.js:21154 beginWork @ react-dom.development.js:21649 beginWork$1 @ react-dom.development.js:27426 performUnitOfWork @ react-dom.development.js:26557 workLoopConcurrent @ react-dom.development.js:26543 renderRootConcurrent @ react-dom.development.js:26505 performConcurrentWorkOnRoot @ react-dom.development.js:25738 workLoop @scheduler.development.js:266 flushWork @ scheduler.development.js:239 performWorkUntilDeadline @ scheduler.development.js:533 队列。 @ task.js:61 运行@ task.js:35 监听器@task.js:46 react_devtools_backend.js:4012 警告:懒惰:需要动态 import() 调用的结果。反而 收到:[对象模块]

您的代码应如下所示:const MyComponent = lazy(() => 导入('./MyComponent')) 在懒 在 RenderedRoute (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:4840:5) 在路线 (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:5272:5) 在悬念 在应用 在路由器 (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:5204:15) 在 BrowserRouter (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:3464:5) overrideMethod @ react_devtools_backend.js:4012 printWarning @ react.development.js:209 错误@react.development.js:183 lazyInitializer @ react.development.js:1400 mountLazyComponent @ react-dom.development.js:19944 beginWork @ react-dom.development.js:21593 beginWork$1 @ react-dom.development.js:27426 performUnitOfWork @ react-dom.development.js:26557 workLoopConcurrent @ react-dom.development.js:26543 renderRootConcurrent @ react-dom.development.js:26505 performConcurrentWorkOnRoot @ react-dom.development.js:25738 工作循环@scheduler.development.js:266 flushWork @ scheduler.development.js:239 performWorkUntilDeadline @ scheduler.development.js:533 队列。 @ task.js:61 运行@ task.js:35 监听器@task.js:46 react_devtools_backend.js:4012 警告:惰性:预期动态 import() 调用的结果。反而 收到:[对象模块]

您的代码应如下所示:const MyComponent = lazy(() => 导入('./MyComponent')) 在懒 在 RenderedRoute (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:4840:5) 在路线 (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:5272:5) 在悬念 在应用 在路由器 (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:5204:15) 在 BrowserRouter (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:3464:5) overrideMethod @ react_devtools_backend.js:4012 printWarning @ react.development.js:209 错误@react.development.js:183 lazyInitializer @ react.development.js:1400 mountLazyComponent @ react-dom.development.js:19944 beginWork @ react-dom.development.js:21593 callCallback @ react-dom.development.js:4164 invokeGuardedCallbackDev @ react-dom.development.js:4213 invokeGuardedCallback @ react-dom.development.js:4277 beginWork$1 @ react-dom.development.js:27451 performUnitOfWork @ react-dom.development.js:26557 workLoopConcurrent @ react-dom.development.js:26543 renderRootConcurrent @ react-dom.development.js:26505 performConcurrentWorkOnRoot @ react-dom.development.js:25738 工作循环@scheduler.development.js:266 flushWork @ scheduler.development.js:239 performWorkUntilDeadline @ scheduler.development.js:533 队列。 @ task.js:61 运行@ task.js:35 监听器@task.js:46 react-dom.development.js:20013 未捕获的错误:元素类型无效。收到承诺 解析为:未定义。惰性元素类型必须解析为类或 功能。 在 mountLazyComponent (react-dom.development.js:20013:1) 在 beginWork (react-dom.development.js:21593:1) 在 HTMLUnknownElement.callCallback (react-dom.development.js:4164:1) 在 Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1) 在 invokeGuardedCallback (react-dom.development.js:4277:1) 在 beginWork$1 (react-dom.development.js:27451:1) 在 performUnitOfWork (react-dom.development.js:26557:1) 在 workLoopConcurrent (react-dom.development.js:26543:1) 在 renderRootConcurrent (react-dom.development.js:26505:1) 在 performConcurrentWorkOnRoot (react-dom.development.js:25738:1) mountLazyComponent @react-dom.development.js:20013 beginWork @ react-dom.development.js:21593 callCallback @ react-dom.development.js:4164 invokeGuardedCallbackDev @ react-dom.development.js:4213 invokeGuardedCallback @ react-dom.development.js:4277 beginWork$1 @ react-dom.development.js:27451 performUnitOfWork @ react-dom.development.js:26557 workLoopConcurrent @ react-dom.development.js:26543 renderRootConcurrent @ react-dom.development.js:26505 performConcurrentWorkOnRoot @ react-dom.development.js:25738 工作循环@scheduler.development.js:266 flushWork @ scheduler.development.js:239 performWorkUntilDeadline @ scheduler.development.js:533 队列。 @ task.js:61 运行@ task.js:35 监听器@task.js:46 react_devtools_backend.js:4012 警告:惰性:预期动态 import() 调用的结果。反而 收到:[对象模块]

您的代码应如下所示:const MyComponent = lazy(() => 导入('./MyComponent')) 在 RenderedRoute (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:4840:5) 在路线 (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:5272:5) 在悬念 在应用 在路由器 (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:5204:15) 在 BrowserRouter (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:3464:5) overrideMethod @ react_devtools_backend.js:4012 printWarning @ react.development.js:209 错误@react.development.js:183 lazyInitializer @ react.development.js:1400 resolveLazy @ react-dom.development.js:14907 reconcileSingleElement @ react-dom.development.js:15718 reconcileChildFibers @ react-dom.development.js:15808 reconcileChildren @ react-dom.development.js:19174 updateContextProvider @ react-dom.development.js:21154 beginWork @ react-dom.development.js:21649 beginWork$1 @ react-dom.development.js:27426 performUnitOfWork @ react-dom.development.js:26557 workLoopSync @ react-dom.development.js:26466 renderRootSync @ react-dom.development.js:26434 recoverFromConcurrentError @ react-dom.development.js:25850 performConcurrentWorkOnRoot @ react-dom.development.js:25750 workLoop @scheduler.development.js:266 flushWork @ scheduler.development.js:239 performWorkUntilDeadline @ scheduler.development.js:533 队列。 @ task.js:61 运行@ task.js:35 监听器@task.js:46 react_devtools_backend.js:4012 警告:惰性:预期动态 import() 调用的结果。反而 收到:[对象模块]

您的代码应如下所示:const MyComponent = lazy(() => 导入('./MyComponent')) 在懒 在 RenderedRoute (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:4840:5) 在路线 (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:5272:5) 在悬念 在应用 在路由器 (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:5204:15) 在 BrowserRouter (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:3464:5) overrideMethod @ react_devtools_backend.js:4012 printWarning @ react.development.js:209 错误@react.development.js:183 lazyInitializer @ react.development.js:1400 mountLazyComponent @ react-dom.development.js:19944 beginWork @ react-dom.development.js:21593 beginWork$1 @ react-dom.development.js:27426 performUnitOfWork @ react-dom.development.js:26557 workLoopSync @ react-dom.development.js:26466 renderRootSync @ react-dom.development.js:26434 recoverFromConcurrentError @ react-dom.development.js:25850 performConcurrentWorkOnRoot @ react-dom.development.js:25750 workLoop @scheduler.development.js:266 flushWork @ scheduler.development.js:239 performWorkUntilDeadline @ scheduler.development.js:533 队列。 @ task.js:61 运行@ task.js:35 监听器@task.js:46 react_devtools_backend.js:4012 警告:懒惰:需要动态 import() 调用的结果。反而 收到:[对象模块]

您的代码应如下所示:const MyComponent = lazy(() => 导入('./MyComponent')) 在懒 在 RenderedRoute (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:4840:5) 在路线 (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:5272:5) 在悬念 在应用 在路由器 (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:5204:15) 在 BrowserRouter (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:3464:5) overrideMethod @ react_devtools_backend.js:4012 printWarning @ react.development.js:209 错误@react.development.js:183 lazyInitializer @ react.development.js:1400 mountLazyComponent @ react-dom.development.js:19944 beginWork @ react-dom.development.js:21593 callCallback @ react-dom.development.js:4164 invokeGuardedCallbackDev @ react-dom.development.js:4213 invokeGuardedCallback @ react-dom.development.js:4277 beginWork$1 @ react-dom.development.js:27451 performUnitOfWork @ react-dom.development.js:26557 workLoopSync @ react-dom.development.js:26466 renderRootSync @ react-dom.development.js:26434 recoverFromConcurrentError @ react-dom.development.js:25850 performConcurrentWorkOnRoot @ react-dom.development.js:25750 workLoop @scheduler.development.js:266 flushWork @ scheduler.development.js:239 performWorkUntilDeadline @ scheduler.development.js:533 队列。 @ task.js:61 运行@ task.js:35 监听器@task.js:46 react-dom.development.js:20013 未捕获的错误:元素类型无效。收到承诺 解析为:未定义。惰性元素类型必须解析为类或 功能。 在 mountLazyComponent (react-dom.development.js:20013:1) 在 beginWork (react-dom.development.js:21593:1) 在 HTMLUnknownElement.callCallback (react-dom.development.js:4164:1) 在 Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1) 在 invokeGuardedCallback (react-dom.development.js:4277:1) 在 beginWork$1 (react-dom.development.js:27451:1) 在 performUnitOfWork (react-dom.development.js:26557:1) 在 workLoopSync (react-dom.development.js:26466:1) 在 renderRootSync (react-dom.development.js:26434:1) 在 recoverFromConcurrentError (react-dom.development.js:25850:1) mountLazyComponent @react-dom.development.js:20013 beginWork @ react-dom.development.js:21593 callCallback @ react-dom.development.js:4164 invokeGuardedCallbackDev @ react-dom.development.js:4213 invokeGuardedCallback @ react-dom.development.js:4277 beginWork$1 @ react-dom.development.js:27451 performUnitOfWork @ react-dom.development.js:26557 workLoopSync @ react-dom.development.js:26466 renderRootSync @ react-dom.development.js:26434 recoverFromConcurrentError @ react-dom.development.js:25850 performConcurrentWorkOnRoot @ react-dom.development.js:25750 workLoop @scheduler.development.js:266 flushWork @ scheduler.development.js:239 performWorkUntilDeadline @ scheduler.development.js:533 队列。 @ task.js:61 运行@ task.js:35 监听器@task.js:46 react_devtools_backend.js:4012 上述错误发生在 <Route.Provider> 组件中:

at RenderedRoute (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:4840:5)
at Routes (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:5272:5)
at Suspense
at App
at Router (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:5204:15)
at BrowserRouter (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:3464:5)

考虑向树中添加错误边界以自​​定义错误 处理行为。访问https://reactjs.org/link/error-boundaries即可 了解有关错误边界的更多信息。覆盖方法@ react_devtools_backend.js:4012 logCapturedError @ react-dom.development.js:18687 update.callback @ react-dom.development.js:18720 callCallback @ react-dom.development.js:13923 commitUpdateQueue @ react-dom.development.js:13944 commitLayoutEffectOnFiber @ react-dom.development.js:23391 commitLayoutMountEffects_complete @ react-dom.development.js:24688 commitLayoutEffects_begin @ react-dom.development.js:24674 commitLayoutEffects @ react-dom.development.js:24612 commitRootImpl @ react-dom.development.js:26823 commitRoot @ react-dom.development.js:26682 finishConcurrentRender @ react-dom.development.js:25892 performConcurrentWorkOnRoot @ react-dom.development.js:25809 workLoop @scheduler.development.js:266 flushWork @ scheduler.development.js:239 performWorkUntilDeadline @ scheduler.development.js:533 队列。 @ task.js:61 运行@ task.js:35 监听器@task.js:46 react-dom.development.js:26923 未捕获的类型错误:无法读取未定义的属性(读取 '显示名称') 在 getDisplayName (react_devtools_backend.js:261:19) 在 getDisplayNameForFiber (react_devtools_backend.js:6381:55) 在 Object.markComponentErrored (react_devtools_backend.js:5615:29) 在 markComponentErrored (react-dom.development.js:5053:1) 在 handleError (react-dom.development.js:26307:1) 在 renderRootSync (react-dom.development.js:26437:1) 在 recoverFromConcurrentError (react-dom.development.js:25850:1) 在 performConcurrentWorkOnRoot (react-dom.development.js:25750:1) 在 workLoop (scheduler.development.js:266:1) 在 flushWork (scheduler.development.js:239:1)

我做错了什么或这里缺少什么?是否有如何使用本文档结合 React 和 Angular 的示例?如果您仅使用 React 或仅使用 Angular 执行相同的步骤,则效果很好。

希望有人能帮忙..

角度微前端:

外壳应用:

反应微前端

【问题讨论】:

    标签: reactjs angular webpack nrwl webpack-module-federation


    【解决方案1】:

    我不完全知道你的配置有什么问题,但是要将不同的技术与模块联合结合使用,请看这里:

    https://www.angulararchitects.io/aktuelles/multi-framework-and-version-micro-frontends-with-module-federation-your-4-steps-guide/

    有一个很好的例子,说明如何将不同的技术结合在一起。 我希望这有帮助。

    【讨论】:

      猜你喜欢
      • 2022-11-28
      • 2021-05-11
      • 1970-01-01
      • 2022-07-29
      • 1970-01-01
      • 2022-12-21
      • 1970-01-01
      • 2022-08-16
      • 1970-01-01
      相关资源
      最近更新 更多