webpack 模块联邦
模块联邦是什么 是Webpack 5 的新特性之一,允许在多个 webpack 编译产物之间共享模块、依赖、页面甚至应用 提供了一种轻量级的、在运行时,通过全局变量组合,在不同模块之前进行数据的获取 提供了一种解决应用集的官方方案。 每个构建都充当一个容器,也可将其他构建作为容器。通过这种方式,每个构建都能够通过从对应容器中加载模块来访问其他容器暴露出来的模块。 属性配置 shared 可选: shared 配置项指示 remote 应用的输出内容和 host 应用可以共用哪些依赖。 shared 要想生效,则 host 应用和 remote 应用的 shared 配置的依赖要一致。 shared的设置有利于当前exposes的组件/方法和当前host引用的依赖保持一致,同时也能够减少不必要的开销;“求近策略” remotes 将会首先依赖来自 host 的依赖,如果 host 没有依赖,它将会下载自己的依赖。没有代码层面的冗余,而只有内置的冗余 Module Federation 使 JavaScript 应用得以从另一个 JavaScript 应用中动态地加载代码 —— 同时共享依赖。如果某应用所消费的 federated module 没有 federated code 中所需的依赖,Webpack 将会从 federated 构建源中下载缺少的依赖项。 原理 期望模块联邦的是非特殊性的,具备独立功能且能够动态加载和引入的可复用性较强的功能; 通过share的模块会自动在执行链路过程中生成share scope,而本地host和remote都会进行提供相对应的modules, 在进行使用的时候通过校验share scope中的provided模块是否符合当前的版本等信息,如果符合则进行加载模块并存储,从而达到了共享模块的目的 模块加载是通过异步加载,只有在使用的时候才会进行加载对应的模块内容,在未加载前只存储对应的相关模块属性信息 容器是由容器入口创建的,该入口暴露了对特定模块的异步访问。暴露的访问分为两个步骤 加载模块: 异步加载,将在 chunk 加载期间完成 执行模块: 将在与其他(本地和远程)的模块交错执行期间完成。这样一来,执行顺序不受模块从本地转换为远程或从远程转为本地的影响。容器可以嵌套使用,容器可以使用来自其他容器的模块。容器之间也可以循环依赖。 优缺点 使用
解决了多个应用代码共享的问题,更加优雅的实现跨应用代码共享 异步方式提供和使用共享模块,相对节约资源 共享模块
容器和应用程序都可以将共享模块和版本信息放在共享范围,共享范围中使用共享模块以及要求版本检查功能, 对于重复的模块数据不进行加载 学习成本
基于webpack生态,学习成本、实施成本低 工程化, 发布模式等随意 配置简单易上手,官方也提供了基于各种框架的版本 相关概念脉络清晰易懂 使用 通过 ModuleFederationPlugin 来引入或者导出模块 引用远程模块 - 基于 Promise 的动态 Remote 一般来说,remote 是使用 URL 配置的,示例如下: module.exports = { plugins: [ new ModuleFederationPlugin({ name: 'host', remotes: { app1: 'remote@http://localhost:3001/myremote.js', }, }), ],}; 导出模块联邦 module.exports = { entry: { remote: './public-path', }, plugins: [ new ModuleFederationPlugin({ filename: 'myremote.js', // 对外提供打包后的文件名, 导入时会使用 name: 'remote', // 微应用的名字,该名称必须与入口名称相匹配 exposes: { './app': './public-path' }, // ... }), ],}; 使用远程模块 const publicPath = await import('remote/app');publicPath.自定义方法(); const ExposedModule = React.lazy(() => import('remote/app'));
补充
补充:Module Federation 在 webpack 5 中实现得最完善,由
ModuleFederationPlugin提供。要点:
- host / remote:host 是"消费方"(主应用),remote 是"提供方"(子应用)。
exposes在 remote 中声明"暴露哪些模块",remotes在 host 中声明"远端应用名 → 远端入口 URL"。shared(如react,react-dom)会做"双向共享 + 版本协商",避免重复打包。- 加载流程:异步
import("remote/Button")→ 加载remoteEntry.js→ 获取暴露模块 → 由 host runtime 接管。- 现已被 Vite 的
vite-plugin-federation借鉴为 "Module Federation 2",可与 Vite/Rollup 项目互通。
来源整理自:我的有道云笔记



