Vite
@module-federation/vite 为 Vite 5、6、7 和 8 提供 Module Federation 支持:
- 能够构建出满足
Module Federation加载规范的模块 - 能够使用别名消费
Module Federation规范的模块 - 能够设置模块的共享依赖配置,当加载模块的宿主环境已经存在对应依赖时将不会重复加载
- 当模块具备远程类型时会自动下载并消费远程模块的类型
- 开发时能够在宿主应用中热更新远程��块
- 能够为服务端渲染(SSR)宿主应用在服务端渲染远程模块
快速开始
安装
你可以通过如下的命令安装插件:
创建 module-federation.config.ts
创建 module-federation.config.ts 文件,内容如下:
注册插件
在 Vite 中,你可以通过 vite.config.ts 配置文件中的 plugins 配置项来添加插件:
省略 type 的对象形式 remotes 会沿用旧的默认值 "var",并输出一条警告。Vite 远程应用请使用 type: 'module';仅当远程应用是全局格式时才使用 type: 'var',例如 Webpack 或 Rspack 容器,或 Vite 远程应用的 varFilename 产物。
配置构建插件
-
类型:
federation(options: ModuleFederationOptions) -
Module Federation 插件的配置结构如下所示:
你可以在 Config 总览 页面找到通用配置项的详细说明。以下选项是 Vite 插件特有的:
manifest 选项也接受一个对象,包含 fileName、filePath、disableAssetsAnalyze 以及 additionalData 钩子,用于修改生成的 mf-manifest.json 和 mf-stats.json。
跨远程应用热更新
在宿主应用上启用 dev.remoteHmr,即可在两个应用都以开发模式运行时热更新远程模块:
设置为 true 时,React(@vitejs/plugin-react 或 @vitejs/plugin-react-swc)和 Vue(@vitejs/plugin-vue 或 @vitejs/plugin-vue-jsx)远程应用会使用框架原生的 HMR,其他框架则回退为整页刷新。设置为 'full-reload' 则始终刷新整个页面。remoteHmr 默认关闭。其他 dev 选项请参阅 dev。
服务端渲染
远程应用会在浏览器入口旁生成一个服务端入口,默认命名为 <filename base>.ssr.js,设置了 ssrFilename 时则使用该名称,并在 mf-manifest.json 中以 metaData.ssrRemoteEntry 声明。通过 manifest 消费远程应用的服务端渲染(SSR)宿主应用会自动选择浏览器入口或服务端入口。
ssrEntryLoader 控制宿主应用在构建和预览期间如何执行远程入口:
'temp-file'(默认)会拉取远程模块图,将其中的导入重写为宿主应用的共享包,写入临时文件,再通过import()加载。'vm'使用vm.SourceTextModule在内存中执行模块图。它要求 Node.js 以--experimental-vm-modules运行,缺少该标志时会回退到'temp-file'并输出警告。maxAgeMs会在指定时间后重新检查每个远程应用的 manifest,以便识别在同一 URL 重新部署的远程应用。省��时会一直缓存到进程退出。fetchTimeoutMs和fetchMaxBytes限制每个请求,默认分别为 10 秒和 10 MiB。设置为0可取消限制。
Vite 8 开发模式使用 Vite 的 ModuleRunner,因此这些选项主要影响构建和预览。
SSR 入口会将 @module-federation/runtime、@module-federation/runtime-core 和 @module-federation/sdk 保持为 external,由 Node 从宿主应用中解析。如果宿主应用无法解析这些包(例如单纯的 @module-federation/enhanced 宿主应用),请在远程应用上设置 Vite 的 ssr.noExternal,以生成自包含的入口。
实验性功能
外部运行时
由宿主应用共享一个 @module-federation/runtime-core 实例,这样远程应用就无需打包各自的副本。在宿主应用上设置 experiments.provideExternalRuntime: true,并在每个远程应用上设置 experiments.externalRuntime: true。页面上应当只有一个容器提供运行时,并且它必须在任何使用该运行时的远程应用之前加载。
宿主应用提供所有共享依赖
当由单个宿主应用提供所有共享依赖、远程应用只负责消费时,experiments.hostProvidesAllShared: true 会通过浏览器原生 import map 而非 federation 运行时来解析共享依赖。请在宿主应用和每个远程应用上都进行设置:
共享模块会变成普通的静态 ES 导入,因此在模块执行期间读取共享值的代码无需 eager 也能正常工作。该模式不会加载 federation 运行时,因此不支持版本协商、import: false、运行时插件、服务端渲染(SSR)、loadRemote,也无法与 Webpack 和 Rspack 容器互操作。
React 服务端渲染岛
experiments.ssrMode: 'ISLAND' 允许不共享 React 的远程应用在服务端渲染,并在宿主应用的 React 树之外使用自己的 React 进行水合。参阅 隔离的 React 岛。
分块
插件会管理代码分块,确保 federation 运行时和共享依赖包装模块按正确顺序加载。将 codeSplitting 设置为 false 会被忽略并输出警告。
在 Vite 8 上,你配置的 build.rolldownOptions.output.codeSplitting.groups 会保留在 federation 分组之后,而 manualChunks 会被忽略并输出警告;请将相应的分组迁移到 codeSplitting.groups。在 Vite 5 到 7 上,函数形式的 manualChunks 仍会对插件未接管的模块生效,而对象形式则会被忽略。