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)
相关推荐
橙子家33 分钟前
浏览器缓存之【身份与会话管理】:Cookies 和 Private state tokens
前端
最新资讯动态2 小时前
HDC 2026 | 对话鲸鸿动能:存量时代,品牌如何夺回营销“主动权”?
前端
最新资讯动态2 小时前
游戏出海,从产品走向体系
前端
最新资讯动态2 小时前
20人团队跑出百万DAU、大厂也来抢量:谁在鸿蒙生态跑出加速度
前端
最新资讯动态2 小时前
千万开发者背后,鸿蒙商业化的B面
前端
爱勇宝4 小时前
AI 时代:智商决定起点,情商决定走多远
前端·ai编程
kyriewen4 小时前
用了半年 Claude Code 后,我尝试关掉它写了一周代码——结果比想象中严重
前端·javascript·ai编程
IT_陈寒5 小时前
Vite的静态资源打包让我熬夜到三点,这坑千万别跳
前端·人工智能·后端
徐小夕5 小时前
万字拆解 JitWord:企业级实时协同文档底层架构 + 大模型 AI 融合完整实践
前端·vue.js·github
一份执念6 小时前
uni-app 小程序分包限制处理与主包体积优化实战
前端·微信小程序