[英]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 应用程序。
Home
和ReactMicrofrontend
的路由工作正常,但只要我点击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 执行相同的步骤,则效果很好。
希望有人能帮忙..
我不完全知道你的配置有什么问题,但是要将不同的技术与模块联合结合使用,请看这里:
有一个很好的例子,说明如何将不同的技术结合在一起。 我希望这有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.