以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下:
前言
Module Federation 的Webpack.config.js核心配置包括:
-
name
+filename
(定义应用标识) -
remotes
(引用远程模块) -
exposes
(暴露本地模块) -
shared
(共享依赖,优化加载)
Host应用中:
javascript
// host/webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { ModuleFederationPlugin } = require('webpack').container;
const webpack = require('webpack');
module.exports = {
// 📦 模式:development(开发)或 production(生产)
mode: 'development',
// 📂 构建入口:Webpack 构建从这里开始
entry: './src/index.js',
// 📤 构建输出
output: {
// 构建目录(dist 文件夹)
path: path.resolve(__dirname, 'dist'),
// 输出 JS 文件名(可以使用哈希做缓存)
filename: '[name].[contenthash].js',
// 所有静态资源的基础路径,必须指向 devServer 地址(用于加载 remote)
publicPath: 'http://localhost:3000/',
// 每次构建自动清空 dist 文件夹
clean: true,
},
// 🌐 Dev Server 本地开发服务器配置
devServer: {
port: 3000, // 主机端口
static: {
directory: path.join(__dirname, 'dist'), // 静态资源路径
},
compress: true, // 启用 gzip 压缩
hot: true, // 启用模块热替换
historyApiFallback: true, // SPA 路由兼容
open: true, // 启动时自动打开浏览器
client: {
overlay: true, // 编译错误以浮层形式显示
},
},
// 📚 Source Map(方便调试)
devtool: 'eval-source-map',
// 📦 模块加载规则
module: {
rules: [
{
test: /\.js$/, // 匹配 JS 文件
exclude: /node_modules/,
use: 'babel-loader', // 使用 Babel 编译
},
{
test: /\.css$/, // 匹配 CSS 文件
use: ['style-loader', 'css-loader'], // 加载样式
},
{
test: /\.(png|jpg|gif|svg)$/, // 图片加载
type: 'asset/resource', // 转成文件资源
},
],
},
// 🔧 模块解析配置
resolve: {
extensions: ['.js', '.jsx', '.json'], // 自动补全扩展名
alias: {
'@': path.resolve(__dirname, 'src'), // 设置路径别名
},
modules: [path.resolve(__dirname, 'src'), 'node_modules'], // 优先搜索路径
},
// 🎯 性能提示控制
performance: {
hints: false, // 不提示 bundle 过大
},
// ⚙️ 缓存配置
cache: {
type: 'filesystem', // 文件系统缓存(构建更快)
},
// 💡 Webpack 插件
plugins: [
// 自动生成 HTML 页面,并注入输出的 JS 脚本
new HtmlWebpackPlugin({
template: './public/index.html',
favicon: './public/favicon.ico',
}),
// 允许定义全局变量(编译时替换)
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
}),
// 🌐 模块联邦核心插件
new ModuleFederationPlugin({
// 当前应用唯一标识
name: 'host',
// 使用远程模块的声明
remotes: {
remote1: 'remote1@http://localhost:3001/remoteEntry.js',
remote2: 'remote2@http://localhost:3002/remoteEntry.js',
},
// 如果你要暴露本地组件(可选)
exposes: {
'./LocalComponent': './src/components/LocalComponent.js',
},
// 共享模块(版本控制、避免重复加载)
shared: {
react: {
// 必须的库名称
requiredVersion: '^17.0.0',
// 是否单例模式(防止重复加载)
singleton: true,
// 是否立即加载(false为异步)
eager: true,
// 允许的版本范围
version: '17.0.2',
// 严格版本检查
strictVersion: false,
// 共享作用域名称
shareScope: 'default'
}
},
}),
],
// 🧠 优化配置(可选)
optimization: {
// 代码分割:把 node_modules 拆出来
splitChunks: {
chunks: 'all', // 所有模块分割
},
runtimeChunk: 'single', // 单独抽出运行时代码
moduleIds: 'deterministic', // 稳定 moduleId,有利于长期缓存
},
// 🌍 目标环境(默认是 web)
target: 'web',
};
Remote 应用的配置:
javascript
new ModuleFederationPlugin({
name: 'remote1',
filename: 'remoteEntry.js', //定义远程入口文件的名称,默认值: remoteEntry.js
library: { type: 'var', name: 'app1' }, //定义如何暴露模块
exposes: {
'./Button': './src/components/Button.js',
},
shared: {
lodash: {
singleton: true,
import: 'lodash', // 精确指定导入包名
eager: true, // 提前加载,避免延迟加载风险
},
react: { singleton: true, requiredVersion: '^18.2.0' },
},
});
跟host应用的稍微差别,主要体现在下面两个属性:
-
filename(字符串)
-
定义远程入口文件的名称
-
默认值: remoteEntry.js
-
示例: filename:remoteEntry.js
-
注意区分这个属性与下面表格中的output.filename,output.filename的全称是module.output.filename,但是这个属性的全称是module.filename
-
-
library
(对象)-
定义如何暴露模块
-
常用配置:
javascriptlibrary: { type: 'var', name: 'app1' }
-
type:暴露类型,可选值有
var
,module
,assign
,this
,window
,self
,global
,commonjs
,commonjs2
,amd
,amd-require
,umd
,umd2
,jsonp
-
name:暴露的全局变量名
-
总结表:
- 常用属性总结:
模块 | 属性 | 含义 |
---|---|---|
entry |
./src/index.js |
应用入口文件 |
output.path |
dist |
构建输出目录 |
output.filename |
bundle.js |
输出文件名 |
output.publicPath |
CDN 或本地路径 | 用于动态加载 remote |
devServer.port |
3000 |
本地开发端口 |
module.rules |
babel-loader , css-loader , asset |
加载规则 |
plugins |
HtmlWebpackPlugin , ModuleFederationPlugin |
插件系统 |
ModuleFederationPlugin.name |
'host' |
当前模块名 |
ModuleFederationPlugin.remotes |
远程模块映射 | remote 应用位置 |
ModuleFederationPlugin.exposes |
本地暴露模块 | 可供 remote 使用 |
ModuleFederationPlugin.shared |
共享模块 | 避免重复打包 |
optimization.splitChunks |
公共依赖提取 | 减少重复代码 |
resolve.alias |
路径别名 | 简化导入 |
cache.type |
'filesystem' |
启用构建缓存 |
performance.hints |
'false' |
忽略性能提示 |
- 共享模块属性总结:
属性名 | 类型 | 说明 |
---|---|---|
singleton |
boolean |
是否只加载一份模块(如 React 必须 true ) |
strictVersion |
boolean |
是否强制匹配 requiredVersion, 严格匹配版本 |
requiredVersion |
string |
版本约束,所期望的依赖版本号(SemVer),要求的版本范围 |
version |
string |
实际运行时模块的版本(建议提供) |
eager |
boolean |
是否在启动时立即加载,默认懒加载(默认 false,建议 false) |
import |
`string | false` |
includeSecondaries |
boolean |
是否包含子模块(如 react/jsx-runtime) |
shareScope |
string |
指定共享作用域(默认为 default) |