JavaScript中的模块联邦(Module Federation)原理是什么?

来源:网络编程作者:桃乃木香奈头衔:网络博主
导读:本期聚焦于小伙伴创作的《JavaScript中的模块联邦(Module Federation)原理是什么?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《JavaScript中的模块联邦(Module Federation)原理是什么?》有用,将其分享出去将是对创作者最好的鼓励。

JavaScript中的模块联邦是webpack5引入的重要特性,它允许不同构建产物之间直接共享模块,不需要把依赖重复打包到各自的bundle中,在微前端、多应用协同等场景中应用十分广泛。它的核心目标是解决多应用之间的模块复用和依赖管理问题,让跨应用的代码共享变得更灵活高效。

JavaScript中的模块联邦(Module Federation)原理是什么?

模块联邦的核心概念

要理解模块联邦的原理,首先需要明确几个核心角色:

  • 宿主应用(Host):主动加载其他应用模块的应用,也就是消费者角色,会在运行时请求远程应用的模块资源。
  • 远程应用(Remote):对外暴露模块供其他应用使用的应用,也就是提供者角色,会把自身需要共享的模块打包成独立的远程入口文件。
  • 共享依赖(Shared):多个应用共同依赖的第三方库或者公共模块,模块联邦可以约定共享版本,避免重复加载。
  • 远程入口(Remote Entry):远程应用生成的特殊文件,里面包含了远程应用暴露的所有模块的信息和加载逻辑,宿主应用通过加载这个文件来获取远程模块的访问能力。

模块联邦的构建时原理

在构建阶段,webpack会根据模块联邦的配置做特殊的处理,主要分为远程应用和宿主应用两部分:

远程应用的构建处理

远程应用需要在webpack配置中通过ModuleFederationPlugin声明要暴露的模块和共享依赖,配置示例如下:

const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      // 远程应用的名称,其他应用通过这个名称来引用当前应用的模块
      name: 'remote_app',
      // 远程入口文件的名称,默认是remoteEntry.js
      filename: 'remoteEntry.js',
      // 暴露给外部的模块,键是外部引用的路径,值是本地模块的路径
      exposes: {
        './Button': './src/components/Button.jsx',
        './utils': './src/utils/index.js'
      },
      // 共享的依赖,这里声明react和react-dom为共享依赖
      shared: {
        react: { singleton: true },
        'react-dom': { singleton: true }
      }
    })
  ]
};

构建时webpack会为远程应用生成两个关键部分:

  • 独立的远程入口文件(remoteEntry.js),这个文件不包含具体模块的代码,只包含模块的元信息、加载函数和共享依赖的版本校验逻辑。
  • 暴露的模块会被打包成独立的chunk文件,只有当宿主应用真正请求对应模块的时候才会被加载。

宿主应用的构建处理

宿主应用同样需要配置ModuleFederationPlugin,声明要加载的远程应用和共享依赖:

const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      // 宿主应用的名称
      name: 'host_app',
      // 声明远程应用的引用,键是远程应用的别名,值是远程入口文件的地址
      remotes: {
        remote_app: 'remote_app@http://localhost:3001/remoteEntry.js'
      },
      // 共享的依赖,需要和远程应用的共享依赖配置匹配
      shared: {
        react: { singleton: true },
        'react-dom': { singleton: true }
      }
    })
  ]
};

构建时webpack会在宿主应用的bundle中注入远程模块的加载逻辑,把对远程模块的引用替换成异步加载的函数,不会把远程模块的代码打包到宿主应用的bundle中。

模块联邦的运行时原理

构建完成后,模块联邦的核心工作流程在运行时展开,主要分为几个步骤:

1. 加载远程入口文件

当宿主应用执行到引用远程模块的代码时,比如下面的代码:

// 动态导入远程应用的Button组件
const RemoteButton = React.lazy(() => import('remote_app/Button'));

webpack注入的加载逻辑会先检查远程应用remote_app的远程入口文件是否已经加载,如果没有加载,就会发起网络请求获取http://localhost:3001/remoteEntry.js,这个文件执行后会在全局注册一个和远程应用名称对应的容器对象,里面包含了该远程应用所有暴露模块的信息。

2. 模块加载与依赖解析

远程入口文件加载完成后,宿主应用会调用容器对象上的模块获取方法,这时候会触发远程模块对应chunk的加载。如果远程模块依赖了共享依赖,会先检查当前宿主应用中是否已经加载了符合版本要求的共享依赖:

  • 如果已经加载,就直接使用宿主应用的共享依赖,不会重复加载。
  • 如果没有加载或者版本不匹配,才会加载远程应用自带的对应依赖。

这里的singleton: true配置就是保证共享依赖只会加载一个实例,避免多实例导致的状态冲突问题。

3. 模块缓存与复用

模块联邦会在内部维护一个模块缓存池,所有加载过的远程模块和共享依赖都会被缓存起来。如果后续其他地方的代码再次引用同一个远程模块,会直接从缓存中读取,不需要再次发起网络请求,提升了再次访问的性能。

核心原理总结

模块联邦的本质是在构建时拆分模块的职责,把模块的元信息和实际代码分离,运行时通过动态加载的方式按需获取远程模块,同时通过共享依赖的机制避免重复打包和加载。它打破了传统模块打包的边界,让不同构建产物之间的模块可以直接通信和复用,这也是它能在微前端场景中快速流行起来的核心原因。

需要注意的是,模块联邦目前主要是webpack生态的特性,其他构建工具如vite也有类似的实现,但核心原理都是基于运行时的动态模块加载和共享逻辑。

Module_FederationJavaScriptwebpack微前端模块共享修改时间:2026-06-11 18:09:36

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。