MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释

以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下:

前言

Module Federation 的Webpack.config.js核心配置包括:

  1. name + filename(定义应用标识)

  2. remotes(引用远程模块)

  3. exposes(暴露本地模块)

  4. 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 (对象)

    • 定义如何暴露模块

    • 常用配置:

      javascript 复制代码
      library: {
        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)
相关推荐
云水一下36 分钟前
从零开始!VMware安装Fedora Workstation 44桌面系统完整教程
前端
小码哥_常2 小时前
安卓黑科技:实现多平台商品详情页一键跳转APP
前端
killerbasd2 小时前
还是迷茫 5.3
前端·react.js·前端框架
网络工程小王2 小时前
【LangChain 大模型6大调用指南】调用大模型篇
linux·运维·服务器·人工智能·学习
qq_571099352 小时前
学习周报四十三
学习
不会敲代码13 小时前
TCP/IP 与前端性能:从数据包到首次渲染的底层逻辑
前端·tcp/ip
kyriewen3 小时前
奥特曼借GPT-5.5干杯,而你的Copilot正按Token收钱
前端·github·openai
小郑加油3 小时前
python学习Day12:pandas安装与实际运用
开发语言·python·学习
AC赳赳老秦3 小时前
投标合规提效:用 OpenClaw 实现标书 / 合同自动审核、关键词校验、格式优化,降低废标风险
开发语言·前端·python·eclipse·emacs·deepseek·openclaw
kyriewen3 小时前
代码写成一锅粥?3个设计模式让你的项目“起死回生”
前端·javascript·设计模式