使用 Webpack 模块联合来 React 微前端

2025-06-10

使用 Webpack 模块联合来 React 微前端

微前端是当今前端领域非常热门的话题。大多数团队倾向于采用这种微前端策略来开发大型复杂的 Web 应用程序,因为它具有许多优势,例如:

  • 独立、解耦的代码库
  • 独立部署
  • 增量更新

下图展示了微前端的一些重要概念。

微前端概念

开发微前端最流行的方式是使用 HTML5 Web 组件(自定义元素)。类似 Angular 的 Web 框架已经扩展支持 Web 组件,而大多数其他库(例如React)也开箱即用地支持它。

有关微前端的更多信息,请参阅

Webpack 中的模块联合是什么?

Webpack 版本 5 附带了一个名为Module Federation 的新功能,它有助于在运行时在项目之间共享代码和依赖项。

在高层次上,应用程序exposes通过单独的 javascript 文件访问某些组件,而其他希望使用该组件的应用程序则异步加载该remotejavascript 文件并使用该组件。

Webpack 的模块联合

最近,此功能改变了我们开发微前端的方式。

在这篇文章中,我将介绍如何使用 Webpack 的 Module Federation 开发基于 React 的微前端,通过创建一个简单的银行应用程序来显示所选帐户的帐户列表和帐户详细信息。

这就是我们的最终应用程序架构的样子。

使用 React 的简单银行应用程序

让我们开始吧..

这篇文章中的所有代码都可以在这里找到,供您参考。

先决条件

首先,由于这是关于 React 和 webpack 的,所以你应该有一个使用 Webpack 配置的 React 应用程序。

如果您需要帮助,请参考此项目。

另外,如上所述,我们的应用程序需要三个 React 项目

  • accounts-summary-app- 提供所有账户摘要的微前端
  • account-details-app- 提供所选帐户详细信息的微前端
  • main-app- 托管上述两个组件的应用程序。同时充当彼此通信的媒介。

ModuleFederationPlugin在微前端项目中配置

ModuleFederationPlugin是一个高级 webpack 插件,它提供了一种非常便捷的方式来配置项目中的模块联合。此外,该插件自带 webpack 库,无需安装其他依赖项。

我们的微前端项目的责任在于expose组件。因此,让我们在项目中添加以下webpack.config.js内容accounts-summary-app

导入插件



const { ModuleFederationPlugin } = require("webpack").container;


Enter fullscreen mode Exit fullscreen mode

配置插件



  plugins: [
    new ModuleFederationPlugin({
      name: "AccountsSummaryApp",
      filename: "accountsSummaryApp_remote.js",
      exposes: {
        "./AccountsSummary": "./src/components/AccountsSummary",
      },
    }),
    ...
  ],


Enter fullscreen mode Exit fullscreen mode
  • name是模块的唯一标识。通常,这是您的微前端项目的名称。
  • filename是公开组件的 JavaScript 文件的名称
  • exposes是从此模块公开的组件的映射(键和值)。(键将作为组件的别名,而值是组件在项目中的位置)

现在,让我们在本地运行这个项目并看看会发生什么。

为暴露的模块提供单独的 JavaScript 文件

如您所见,现在 webpack 已将我们的AccountsSummary组件捆绑到一个单独的 javascript 文件中,正如我们在 webpack 配置中指示的那样。

我们account-details-app也对这个项目做同样的事情



  plugins: [
    new ModuleFederationPlugin({
      name: "AccountDetailsApp",
      filename: "accountDetailsApp_remote.js",
      exposes: {
        "./AccountDetails": "./src/components/AccountDetails",
      },
    }),
    ...
  ],


Enter fullscreen mode Exit fullscreen mode

如果你错过了什么,你可以参考这两个项目

账户摘要应用程序
账户详情应用程序

在 Host App 项目中配置ModuleFederationPlugin

就像我之前解释的那样,我们的主机应用程序main-app负责从微前端项目加载组件。

就像微前端配置定义一样exposes,主机应用程序的 webpack 配置定义remotes告诉 webpack 在哪里找到这些外部组件。



  plugins: [
    new ModuleFederationPlugin({
      remotes: {
        AccountsSummaryApp_Remote: "AccountsSummaryApp@http://localhost:9001/accountsSummaryApp_remote.js",
        AccountDetailsApp_Remote: "AccountDetailsApp@http://localhost:9002/accountDetailsApp_remote.js",
      },
    }),
    ...
  ],


Enter fullscreen mode Exit fullscreen mode

remotes是一个包含键和值的映射,定义了它所使用的所有外部模块。键将作为模块的别名,值定义该模块的远程 JavaScript 文件位置。

值应该具有如下特殊格式

<Name of the Exposed Module>@<Remote URL of the javascript file>

现在所有的webpack配置都完成了,下面我们来写一些javascript代码来加载外部组件。

将外部组件加载到主机应用程序

这个 webpack 模块联合的美妙之处之一在于,开发人员感觉不到从自己的项目导入本地组件和从外部 javascript 文件导入远程组件之间的区别。

React 代码看起来就像是延迟加载组件。



const AccountsSummary = React.lazy(() =>
  import("AccountsSummaryApp_Remote/AccountsSummary")
);


Enter fullscreen mode Exit fullscreen mode

并在你的 jsx 中使用它



<Suspense fallback={<h1>Error while loading Account Summary</h1>}>
  <AccountsSummary onAccountSelected={handleAccountSelected} />
</Suspense>


Enter fullscreen mode Exit fullscreen mode

关于导入需要注意的一点是,要使用在主机应用程序中定义的相同别名以及在微前端项目中定义的组件别名

模块联合配置

组件之间的通信

如前所述,外部组件与项目中的本地组件相同。因此,标准的通信方式也应该适用于此。

对于此应用程序,我在主机应用程序中定义了一个共享状态,并且每个组件都通过该共享状态进行通信。

请参阅main-app查看代码

结论

这是一篇关于如何使用 Webpack 的 Module Federation 功能开发微前端的入门教程。在这篇文章中,我简要介绍了

  • 什么是微前端
  • Webpack 的模块联合功能是什么
  • 配置微前端以公开组件
  • 配置主机应用程序以使用这些公开的组件
  • 组件之间如何通信

完整的工作示例可以在这里找到

您可以在此处找到此示例银行应用程序中使用的完整 React 模板

以上就是全部内容。欢迎分享你的反馈。感谢阅读。

鏂囩珷鏉ユ簮锛�https://dev.to/pahanperera/react-micro-frontends-with-webpacks-module-federation-32ii
PREV
CSR、SSR、SSG 和 ISR 的直观解释和比较
NEXT
[视频] 使用 Docker 进行开发 – 人人皆可使用容器!