标准答案

  1. host 是消费远程模块的应用,remote 是暴露模块给别人使用的应用。
  2. remote 会生成类似 remoteEntry 的入口,描述它暴露了哪些模块以及如何加载。
  3. host 在运行时拉取 remoteEntry,再按需加载远程模块。
  4. exposes 用来声明 remote 暴露的模块,remotes 用来声明 host 可以访问哪些远程应用。
  5. shared 用来声明共享依赖,减少重复加载,但也会带来版本兼容和单例治理问题。

题目解析

Module Federation 的核心不是“把代码拆出去”,而是让不同构建之间形成运行时模块关系。每个应用可以独立构建部署,但 host 能在运行时拿到 remote 暴露的页面、组件或工具模块。

shared 是最容易出问题的部分。React、Vue、状态库、组件库这类依赖如果重复加载或版本不一致,可能导致上下文不共享、样式错乱或运行时异常;如果强制单例,又要面对版本兼容约束。

它适合需要独立发布、运行时组合和模块共享的场景,但对构建配置、版本治理、错误兜底和发布顺序要求更高。

代码示例

remote 暴露模块,host 在运行时消费。

JavaScript
// remote app
new ModuleFederationPlugin({
  name: 'catalog',
  filename: 'remoteEntry.js',
  exposes: {
    './ProductList': './src/ProductList'
  },
  shared: ['react', 'react-dom']
})

// host app
new ModuleFederationPlugin({
  remotes: {
    catalog: 'catalog@https://cdn.example.com/catalog/remoteEntry.js'
  }
})

常见误区

  • 只记住 remoteEntry 名字,讲不清 host、remote、exposes、shared 的关系。
  • 把所有依赖都 shared,导致版本协商复杂且排障困难。
  • 没有处理远程模块加载失败时的降级 UI 和监控告警。

作者信息