Webpack5模块联邦与微前端
Webpack5引入的Module Federation(模块联邦)是一个革命性的特性,它允许多个独立构建的应用在运行时共享模块,这让微前端架构的实现变得前所未有的简单。本文将深入介绍模块联邦的原理和实战应用。
一、模块联邦核心概念
// 远程应用 - 暴露模块
const ModuleFederationPlugin = require("webpack").container.ModuleFederationPlugin;
new ModuleFederationPlugin({
name: "remoteApp",
filename: "remoteEntry.js",
exposes: {
"./UserList": "./src/components/UserList",
"./Dashboard": "./src/components/Dashboard",
"./utils": "./src/utils",
},
shared: ["react", "react-dom"],
})
// 主应用 - 消费远程模块
new ModuleFederationPlugin({
name: "hostApp",
remotes: {
remoteApp: "remoteApp@http://localhost:3001/remoteEntry.js",
},
shared: {
react: { singleton: true, requiredVersion: "^18.0.0" },
"react-dom": { singleton: true },
},
})
二、动态加载远程组件
// 使用React.lazy动态加载
const UserList = React.lazy(() => import("remoteApp/UserList"));
const Dashboard = React.lazy(() => import("remoteApp/Dashboard"));
function App() {
return (
<Suspense fallback={<Loading />}>
<UserList />
<Dashboard />
</Suspense>
);
}
// 运行时动态加载 - 支持配置化
async function loadRemoteComponent(remoteUrl, moduleName) {
// 动态注入remoteEntry
await new Promise((resolve, reject) => {
const script = document.createElement("script");
script.src = remoteUrl + "/remoteEntry.js";
script.onload = resolve;
script.onerror = reject;
document.head.appendChild(script);
});
// 初始化容器并获取模块
const container = window[moduleName];
await container.init(__webpack_share_scopes__.default);
const factory = await container.get("./" + moduleName);
return factory();
}
三、微前端架构实践
// 基座应用配置
new ModuleFederationPlugin({
name: "shell",
remotes: {
userApp: "userApp@http://localhost:3001/remoteEntry.js",
orderApp: "orderApp@http://localhost:3002/remoteEntry.js",
adminApp: "adminApp@http://localhost:3003/remoteEntry.js",
},
shared: ["react", "react-dom", "react-router-dom"],
})
// 共享状态管理
shared: {
"@shared/store": { singleton: true },
"@shared/utils": { singleton: true },
}
四、Shared配置详解
shared: {
react: {
singleton: true, // 只加载一个实例
requiredVersion: "^18.0.0",
eager: false, // 是否同步加载
strictVersion: true, // 严格版本检查
},
lodash: {
singleton: false, // 允许多版本共存
},
}
Webpack5的模块联邦让微前端架构的实现变得简单优雅,无需额外的框架和复杂的通信机制。但在使用时要注意版本管理、样式隔离和错误边界等问题。建议从小范围试点开始,逐步推广到整个项目。