Webpack 是一个现代 JavaScript 应用程序的静态模块打包工具,它能够将多个模块(包括 JavaScript、CSS、图片等)打包成一个或多个 bundle 文件,便于浏览器加载和运行。
而 Module Federation(模块联邦)是 Webpack 5 引入的一项重要特性,它解决了多个独立 Webpack 构建之间代码共享的问题,让不同应用可以像使用本地模块一样使用对方的模块,实现了真正的微前端架构支持。
一、Module Federation 的核心概念
- Host(宿主):加载其他应用的应用
- Remote(远程):被其他应用加载的应用
- Shared(共享):可以在多个应用间共享的依赖(如 React、Lodash 等)
二、基本使用方式
要使用 Module Federation,需要在 Webpack 配置中添加 ModuleFederationPlugin
:
远程应用配置(remote):
// webpack.config.js
const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
// ...其他配置
plugins: [
new ModuleFederationPlugin({
name: 'remoteApp', // 远程应用名称
filename: 'remoteEntry.js', // 生成的远程入口文件
exposes: {
'./Button': './src/components/Button', // 暴露的模块
'./utils': './src/utils',
},
shared: {
react: { singleton: true }, // 共享 React
'react-dom': { singleton: true },
},
}),
],
};
宿主应用配置(host):
// webpack.config.js
const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
// ...其他配置
plugins: [
new ModuleFederationPlugin({
name: 'hostApp',
remotes: {
remoteApp: 'remoteApp@http://localhost:3001/remoteEntry.js',
// 远程应用名称@远程应用入口文件地址
},
shared: {
react: { singleton: true },
'react-dom': { singleton: true },
},
}),
],
};
在宿主应用中使用远程模块:
// 动态导入
import('remoteApp/Button').then(({ default: Button }) => {
// 使用远程应用的 Button 组件
});
// 或在 React 中使用
const RemoteButton = React.lazy(() => import('remoteApp/Button'));
function App() {
return (
<div>
<React.Suspense fallback="Loading Button...">
<RemoteButton />
</React.Suspense>
</div>
);
}
三、Module Federation 的优势
- 独立部署:每个应用可以独立开发、测试和部署
- 代码共享:避免重复加载相同依赖,减少整体体积
- 运行时集成:应用间可以实时共享模块,无需提前打包
- 灵活性:可以按需加载远程模块,提高性能
Module Federation 特别适合大型应用拆分为微前端架构,或者需要在多个项目间共享组件和逻辑的场景。