0Pricing
React Academy · 课时

使用 Webpack 5 的 Module Federation

使用 Webpack Module Federation 配置宿主应用和远程应用,以便在运行时共享组件。

使用 Webpack 5 的 Module Federation 是 CoddyKit 上的免费 React Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 React Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 React Academy 课程共包含 4 节课。

模块联邦概览

Webpack 5 的模块联邦允许您在运行时在分别打包的应用之间共享 JavaScript 模块——一个应用暴露组件,另一个应用无需构建步骤即可使用这些组件。

角色:主应用与远程应用

一个远程应用会暴露模块。一个主应用会使用一个或多个远程应用中的模块。同一个应用可以同时充当主应用和远程应用。

远程应用配置

在远程应用的 webpack.config.js 中,使用 ModuleFederationPlugin 暴露组件。

// Remote: apps/products/webpack.config.js
const { ModuleFederationPlugin } = require('webpack').container;

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: 'products',              // remote name
      filename: 'remoteEntry.js',    // entry file
      exposes: {
        './ProductCard': './src/components/ProductCard', // exposed module
        './CartButton': './src/components/CartButton',
      },
      shared: ['react', 'react-dom'], // share deps to avoid duplication
    }),
  ],
};

主应用配置

在主应用的 webpack 配置中,声明要使用哪些远程应用,以及从哪里加载它们。

// Host: apps/shell/webpack.config.js
new ModuleFederationPlugin({
  name: 'shell',
  remotes: {
    products: 'products@http://localhost:3001/remoteEntry.js',
    cart: 'cart@http://localhost:3002/remoteEntry.js',
  },
  shared: ['react', 'react-dom'],
})

使用远程模块

使用远程应用名称作为路径前缀来导入远程模块。将它们包裹在 React.lazy 和 Suspense 中,以实现延迟加载。

import React, { lazy, Suspense } from 'react';

const ProductCard = lazy(() => import('products/ProductCard'));

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <ProductCard productId="123" />
    </Suspense>
  );
}

共享依赖

使用 singleton: true 列出共享软件包,以确保所有微前端只加载一份 React。

shared: {
  react: { singleton: true, requiredVersion: '^18.0.0' },
  'react-dom': { singleton: true, requiredVersion: '^18.0.0' },
  '@company/design-system': { singleton: true },
},

动态远程应用

在运行时从配置(例如清单端点)动态加载远程应用,而不是将 URL 硬编码在 webpack 配置中。

async function loadRemote(scope, module) {
  await __webpack_init_sharing__('default');
  const container = window[scope];
  await container.init(__webpack_share_scopes__.default);
  const factory = await container.get(module);
  return factory();
}

const ProductCard = React.lazy(() => loadRemote('products', './ProductCard'));

使用 TypeScript 配合模块联邦

使用 @module-federation/typescript 插件为暴露的模块生成类型声明,以便主应用获得完整的自动补全功能。

远程应用故障的错误边界

将远程组件包裹在错误边界中。如果远程应用加载失败,主应用可以优雅降级,而不是崩溃。

<ErrorBoundary fallback={<div>Product unavailable</div>}>
  <Suspense fallback={<Skeleton />}>
    <ProductCard productId={id} />
  </Suspense>
</ErrorBoundary>

Vite 模块联邦

@originjs/vite-plugin-federation 插件以相似的 API 将模块联邦引入基于 Vite 的项目。

// vite.config.ts (remote)
import federation from '@originjs/vite-plugin-federation';

export default defineConfig({
  plugins: [
    federation({
      name: 'products',
      filename: 'remoteEntry.js',
      exposes: { './ProductCard': './src/ProductCard' },
      shared: ['react'],
    }),
  ],
});

快速检查

在模块联邦中为共享软件包设置 singleton: true 有什么作用?

回顾

模块联邦在远程应用中使用 ModuleFederationPlugin 来暴露模块,在主应用中使用它来使用模块。使用 lazy() 导入远程模块,将 react 作为单例共享以避免重复,并将远程应用包裹在错误边界中以实现优雅降级。

常见问题解答

「使用 Webpack 5 的 Module Federation」课时是免费的吗?

是的 — 「使用 Webpack 5 的 Module Federation」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 React Academy 课程的其余内容,请升级到 CoddyKit PRO。 React Academy 课程共包含 4 节课。

「使用 Webpack 5 的 Module Federation」这节课中我会学到什么?

使用 Webpack Module Federation 配置宿主应用和远程应用,以便在运行时共享组件。 你通过在浏览器中直接运行的动手代码来练习 React Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 React Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 React Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「使用 Webpack 5 的 Module Federation」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 React Academy 课中编写并运行代码吗?

能。每节 React Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 微前端概念与权衡
  2. 使用 Webpack 5 的 Module Federation
  3. MFE 之间的共享状态与路由
  4. MFE 的独立部署与 CI 流水线
← 返回 React Academy