繁体   English   中英

如何使用带有模块联合和 NX 的通用 shell 创建基于不同技术的微前端?

[英]How to create micro frontends based on different technologies using a common shell with module federation and NX?

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

因此我使用了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() 调用的结果。 而是收到:[对象模块]

您的代码应如下所示:RenderedRoute (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:4840:5) 处的 const MyComponent = lazy(() => import('./MyComponent'))路由(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 error @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.devel opment.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 run @task.js:35 listener @task.js:46 react_devtools_backend.js:4012 警告:惰性:预期动态 import() 调用的结果。 而是收到:[对象模块]

你的代码应该是这样的: const MyComponent = lazy(() => import('./MyComponent')) at Lazy at 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) :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 error @ 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 workLoop @scheduler.development.js:266 flushWork @scheduler.development.js:239 performWorkUntilDeadline @scheduler.development.js:533 队列。 @task.js:61 run @task.js:35 listener @task.js:46 react_devtools_backend.js:4012 警告:惰性:预期动态 import() 调用的结果。 而是收到:[对象模块]

你的代码应该是这样的: const MyComponent = lazy(() => import('./MyComponent')) at Lazy at 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) :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 error @ 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 workLoop @ scheduler.development.js:266 flushWork @ scheduler.development.js:239 performWorkUntilDeadline @ scheduler.development.js:533 队列。 @task.js:61 run @task.js:35 listener @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) 在对象。在 performUnitOfWork(反应- 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 renderRootC oncurrent @ 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 run @task.js:35 listener @task.js:46 react_devtools_backend.js:4012 警告:惰性:预期动态 import() 调用的结果。 而是收到:[对象模块]

您的代码应如下所示:RenderedRoute (http://localhost:4200/vendors-node_modules_react-router-dom_dist_index_js.js:4840:5) 处的 const MyComponent = lazy(() => import('./MyComponent'))路由(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 error @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.devel opment.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 run @task.js:35 listener @task.js:46 react_devtools_backend.js:4012 警告:惰性:预期动态 import() 调用的结果。 而是收到:[对象模块]

你的代码应该是这样的: const MyComponent = lazy(() => import('./MyComponent')) at Lazy at 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) :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 error @ 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.d evelopment.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 run @task.js:35 listener @task.js:46 react_devtools_backend.js:4012 警告:惰性:预期动态 import() 调用的结果。 而是收到:[对象模块]

你的代码应该是这样的: const MyComponent = lazy(() => import('./MyComponent')) at Lazy at 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) :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 error @ 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 run @task.js:35 listener @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) 在对象。在 performUnitOfWork(反应- 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。开发 elopment.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 run @task.js:35 listener @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以了解有关错误边界的更多信息。 overrideMethod @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 run @task.js:35 listener @task.js:46 react-dom.development.js:26923 Uncaught TypeError: 无法在 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 执行相同的步骤,则效果很好。

希望有人能帮忙..

角度微前端: 在此处输入图像描述

外壳应用: 在此处输入图像描述

反应微前端在此处输入图像描述

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM