MF 2.0 与沙箱

共 20 题
📑 题目列表 20 题
#
★★★

1. Module Federation 2.0 相比 1.0 的运行时插件与共享依赖治理

Module Federation 2.0 相比 1.0 引入了哪些运行时能力?其 runtimePlugins 插件体系如何工作,在共享依赖治理上带来了哪些改进?

  • MF 2.0 的 runtime 模块化架构与 1.0 打包期代码注入的差异
  • runtimePlugins 钩子体系与插件生命周期
  • 共享依赖的版本协商、回退与热更新的治理能力

Module Federation 2.0 的核心变化是把联邦运行时从「构建期代码模板注入」重构为「独立、可插拔的运行时包」。1.0 中 runtime 逻辑由 webpack 在编译期生成并内联进产物,难以替换和扩展;2.0 中 runtime 成为独立模块,可通过 runtimePlugins 在运行时加载插件,钩子覆盖 resolveShare、resolveSnapshot、beforeLoadShare、afterResolve、loadRemote 等关键节点,实现对共享依赖解析、远程模块加载的完全控制。在共享依赖治理上,2.0 通过 snapshot 机制记录依赖版本状态,插件可注入自定义的共享策略,例如按环境选择版本、动态降级到本地副本、注入监控与错误上报,从而把「版本协商」从黑盒变成可观测、可编排的治理点。

回答本题应抓住 1.0 与 2.0 的本质差异:前者是构建期固化的运行时,后者是运行时可编程的架构。先讲清楚插件钩子链,再落到共享依赖治理的具体收益(版本回退、动态选择、可观测性),体现从「机制」到「治理价值」的完整认知。

#
★★★

2. 共享作用域(shared scope)下依赖去重与冲突解决

Module Federation 的 shared scope 如何实现依赖去重?当宿主与远程应用请求同一依赖的不同版本时,版本协商(version negotiation)如何运作,冲突如何解决?

  • shared 配置与共享作用域注册机制
  • 版本协商:requiredVersion、singleton、strictVersion 的语义
  • 冲突时的降级行为与单例依赖的坑

当依赖被声明为 shared 后,各应用运行时通过共享作用域(share scope)注册已加载的依赖版本;宿主与远程加载同一依赖时,联邦运行时按 semver 规则协商:若远程请求的 requiredVersion 与宿主已提供的版本满足范围则复用宿主实例,否则远程自行加载自己的副本,实现「能共用则共用、不能共用则隔离」。singleton: true 强制全局唯一实例,忽略版本差异但会校验范围,不满足时默认降级复用宿主已加载的实例并告警(strictVersion 可把告警升级为报错)。冲突解决的要点是:版本范围越宽复用率越高但兼容风险越大,跨大版本共存时需保证依赖自身的多实例可容(如 React 的多实例会导致 hooks 状态错乱)。

核心是讲清协商的决策路径:先看是否 singleton,再看 requiredVersion 是否满足,决定复用还是自载。同时指出冲突的两个层面——版本不满足时的自载降级,以及 singleton 下的版本校验与告警,最后落到工程实践(统一版本策略、契约测试)上。

#
★★★

3. Module Federation 的「联邦雪崩」与循环依赖防护

什么是 Module Federation 的「联邦雪崩」(federation avalanche)?它如何发生,又该如何从依赖治理与运行时两侧防护?

  • 联邦雪崩的定义:共享依赖未命中导致的连锁重复加载
  • 触发根因:requiredVersion 过严、共享配置不一致
  • 防护手段:版本策略、契约测试与 runtime 校验

「联邦雪崩」指多个远程应用因共享依赖协商失败而各自打包一份依赖副本,导致页面加载同一库的多份实例、体积膨胀、性能劣化甚至运行时状态错乱(例如多个 React 实例)。根因通常是 requiredVersion 写死精确版本、各子应用 shared 配置不一致、或共享包升级后没有同步更新契约,使协商链路逐环失配,形成「雪崩式」的副本蔓延。防护要从三方面入手:治理上统一依赖版本矩阵并用 CI 契约测试锁定兼容范围;配置上放宽 requiredVersion 到合理 semver 范围、对框架类依赖使用 singleton;运行时利用 snapshot 与监控检测副本数量,一旦发现多实例告警并回滚版本。

本题考的是「多副本」问题的系统性认知:先给出定义与危害,再分析配置层面的根因,最后给出治理(版本策略、契约测试)与运行时(检测告警)结合的完整防护方案,避免只答「把版本写宽一点」这种单点措施。

#
★★★

4. qiankun/jsbox 的 JS 沙箱(Proxy/with)隔离原理与局限

qiankun 的 ProxySandbox 与 jsbox 的 with + Proxy 沙箱是如何实现 window 隔离的?它们各自有哪些局限?

  • with + Proxy 拦截 window 属性读写的基本原理
  • qiankun ProxySandbox 的多实例激活切换机制
  • 隔离盲区:Symbol、不可配置属性、第三方库缓存引用

jsbox 式沙箱用 with(proxy) 包裹子应用代码,把 window 属性读写转发到 Proxy 上:读操作先查自身 fakeWindow、再查真实 window,写操作落在 fakeWindow,从而形成「读得到全局、写不出去」的隔离层。qiankun 的 ProxySandbox 在此基础上为每个子应用维护独立的 proxy 与值表,激活时把全局 window 换成该子应用的 proxy,实现多实例并存时各自的状态隔离与切换。局限包括:同步调用链之外逃逸(如通过 iframe、Web Worker 或原生对象引用绕过代理);对 Symbol 属性、不可配置/不可代理对象(如 window.window)无法完全拦截;第三方库若在沙箱外缓存了 window 引用,沙箱内修改对其不可见;严格模式下 with 不可用,需要把代码包一层函数体规避;性能上高频属性访问会引入 Proxy trap 开销。

先讲清机制(with + Proxy 的读写转发与 fakeWindow 值表),再对比 qiankun 的多实例切换设计,最后必须列出局限——凡是 JS 语义上无法被代理完全覆盖的场景都是逃逸口,这既是考点也是工程上需要 iframe 兜底的原因。

#
★★★

5. 微前端的样式隔离(Shadow DOM/ scoped/运行时改写)方案对比

微前端样式隔离有哪些主流方案?Shadow DOM、CSS scoped(qiankun 运行时改写)与 CSS-in-JS / CSS Modules 在隔离强度、性能与工程成本上如何取舍?

  • 各方案隔离机制的本质差异
  • 运行时选择器改写(scoped css)的实现与边界
  • 方案选择的工程维度:样式穿透、动态样式、性能

主流方案分四类:CSS Modules / CSS-in-JS 在构建期把类名哈希化,隔离靠「类名唯一」,但只约束自己、不防外部污染且动态注入样式无法哈希;qiankun 的 scoped css 在运行时把子应用样式表的选择器整体加前缀(如 div[data-qiankun=app1]),实现低成本隔离,但正则有覆盖不到的场景(如 @media、@font-face 内的选择器),且对动态插入的 style 需要补丁;Shadow DOM 提供浏览器级的样式边界,隔离最彻底,但样式穿透(::part/::slotted)能力有限、表单控件与焦点管理有坑,且部分 UI 库对 Shadow 环境的适配成本高。工程上通常组合使用:构建期哈希保证自净,运行时前缀兜底历史包袱,关键场景用 Shadow DOM 强化边界。

回答要按「构建期 vs 运行时 vs 浏览器级」分层对比,每层给出机制、优点与代价,最后给出组合策略。重点说清 scoped css 是「字符串级改写」而非真正的作用域,这是其边界所在。

#
★★★

6. MF 2.0 snapshot 依赖锁定,CI 生成远程模块版本快照固定依赖,治理运行时依赖漂移与发布破坏

MF 2.0 的 snapshot 机制是什么?如何通过 CI 生成远程模块版本快照来固定依赖,从而治理运行时依赖漂移与发布破坏?

  • snapshot 的数据结构与作用域(share scope 快照)
  • CI 生成快照的流水线设计
  • 快照对依赖漂移、灰度与回滚的治理价值

snapshot 是 MF 2.0 引入的「依赖状态快照」:记录共享作用域中每个依赖的消费方、提供方及其版本信息(与 module federation 的 remoteEntry 元数据绑定),运行时通过快照决策版本复用,而不是每次临时协商。工程上由 CI 在构建产物生成时同步产出 snapshot 文件(列出各远程模块的构建指纹、共享依赖版本范围),发布时随产物归档;消费方加载远程时先核对 snapshot,若远程提供的版本与快照不符(依赖漂移),可自动降级、告警或阻断发布。这样把「运行时碰运气」的协商变成「发布时可审计的契约」,配合灰度与回滚,能显著降低「主应用没动、子应用升级后整体崩」的发布破坏。

本题把快照机制与发布治理串起来:先说清 snapshot 记录什么,再说 CI 如何生成与归档,最后落到治理闭环(漂移检测、阻断发布、回滚依据)。回答中应强调 snapshot 是「发布期的契约快照」,与运行时协商互补。

#
★★★

7. MF 2.0 loadRemote 动态加载的失败编排,远程模块超时、重试与降级 UI,及运行时插件钩子的监控接入

MF 2.0 的 loadRemote 动态加载远程模块时,如何编排超时、重试与降级 UI?运行时插件钩子如何接入监控?

  • loadRemote 的异步加载与错误语义
  • 超时/重试/降级的编排模式
  • runtimePlugins 钩子接入监控与上报

loadRemote 返回 Promise,加载失败时需在调用侧做编排:外层 Promise 加超时控制(如 AbortController 或 Promise.race),超时或失败后按退避策略重试若干次,仍失败则渲染降级 UI(占位组件、错误页或本地兜底实现),并把失败信息写入错误边界统一处理。MF 2.0 的 runtimePlugins 提供 loadRemote、beforeLoadRemote、errorLoadRemote 等钩子,可在插件里统一注入超时时间、重试次数、上报埋点与 fallback 逻辑,避免每个调用点重复写编排代码;同时钩子可捕获远程加载的耗时、成功率等指标接入监控大盘,形成「加载失败可观测、降级可统一」的工程闭环。

本题是典型的「能力 + 工程化」题:先答 loadRemote 的失败形态与调用侧编排(超时、重试、降级),再答插件钩子如何把这些横切逻辑收敛为公共能力并接入监控。突出「集中编排优于调用点各自处理」的设计判断。

#
★★

8. 微前端的拆分粒度与团队边界(康威定律)对齐

微前端的拆分粒度如何确定?为什么拆分要与团队边界(康威定律)对齐?

  • 康威定律对微前端拆分方向的指导意义
  • 按业务域而非技术层拆分的依据
  • 粒度失控(过细/过粗)的代价

康威定律指出系统的结构会镜像组织的沟通结构,因此微前端的拆分边界应与团队职责边界对齐:一个团队负责一块完整业务域(如订单、用户),拥有从 UI 到接口的完整闭环,避免跨团队频繁协调。按业务域拆分使团队可独立迭代、独立发布、独立演进技术栈;若按技术层(公共组件层、业务层)拆分则每个需求都横跨多个团队,反而放大协作成本。粒度把控上,过细则应用数量爆炸、公共依赖与路由治理失控;过粗则退化为巨石应用。判断标准是「一个团队能否在最小协调下独立交付一个用户可感知的完整功能」。

本题考架构决策的元原则:先背出康威定律的表述,再推导拆分应与团队边界对齐、按业务域拆分,最后给出过细/过粗的权衡与判断标准,体现架构师的系统思考而非罗列工具。

#
★★

9. 微前端应用的生命周期(加载/卸载/保活)管理

微前端子应用的生命周期包含哪些阶段?加载、卸载与保活(keep-alive)各有什么管理要点?

  • bootstrap/mount/unmount 生命周期契约
  • 卸载时的副作用清理(事件、定时器、全局状态)
  • 保活模式的缓存与状态恢复

基于 single-spa 的框架把子应用生命周期抽象为 bootstrap(初始化,执行一次)、mount(挂载,可多次)、unmount(卸载,可多次),qiankun 等框架在此之上增加 load(加载 HTML/CSS/JS)。管理要点:mount 阶段要幂等,反复挂载不能累积副作用;unmount 必须清理 DOM、事件监听、定时器、全局变量与 store 状态,否则切换应用会泄漏内存并造成状态污染。保活(keep-alive)则跳过真实卸载:应用切走后仅隐藏容器、冻结状态,再进入时直接恢复,避免重建成本;代价是内存常驻与「隐藏期间的后台运行」需要约束(如暂停动画与轮询)。选择依据是切换频率与重建成本:高频切换且重建贵才值得保活。

先答生命周期的阶段契约与「mount 幂等、unmount 清理」的铁律,再展开保活机制的实现与代价,最后给出取舍依据,覆盖机制、工程细节与决策三个层次。

#
★★

10. 微前端下的统一监控与错误归属

微前端架构下如何实现统一监控?主子应用的错误如何正确归属?

  • 监控 SDK 的注入方式与统一上报
  • 错误归属:应用标识、source map 与依赖版本快照
  • 跨应用堆栈的归一化处理

统一监控的做法是让监控 SDK 随基座注入或各子应用接入同一 SDK,统一配置上报地址与采样策略,事件携带统一的 appName、版本号与应用路由上下文,落库后按应用维度聚合。错误归属的关键是「给错误打上可靠的应用标签」:运行时通过入口标识(qiankun 的应用名、MF 的 remote 名)标记来源;还原堆栈时用各子应用自己的 source map,配合构建产物清单避免多应用同名 bundle 混淆;把子应用依赖版本快照一并上报,定位「版本漂移导致的问题」时能快速锁定是哪个应用的哪个版本。跨应用边界(如事件冒泡、跨应用调用)的错误还需在边界处附加上下文,形成完整调用链。

回答分两层:统一性(SDK 统一、上报统一、聚合统一)与归属准确性(应用标签、source map 隔离、版本快照)。突出「错误归属依赖构建产物与运行时标签的闭环」,这是微前端监控区别于单应用监控的核心。

#
★★

11. 微前端部署(独立部署/版本矩阵)与灰度

微前端的独立部署与版本矩阵如何组织?灰度发布在主应用与子应用并存时如何实施?

  • 子应用独立部署的产物组织与资源路径约定
  • 版本矩阵:主应用锁定子应用版本的机制
  • 主子应用独立的灰度与回滚边界

独立部署指每个子应用在自身 CI 中构建、上传 CDN、按版本号管理产物,主应用通过运行时配置(如 qiankun 的 registerMicroApps 配置或 MF 的 remote 地址表)指向子应用的版本入口,从而形成「版本矩阵」:主应用版本 × 子应用版本。矩阵的治理靠配置中心:发布新子应用时先在小流量上切换入口配置,观测后再放量。灰度实施上主子应用可分别灰度:子应用按用户维度灰度时,基座根据灰度规则下发不同的子应用入口地址;回滚时只需把配置切回旧版本入口,无需重新发版。边界在于:跨应用变更(如接口契约破坏)不能靠单边灰度掩盖,需要契约测试与联合验证。

本题考发布模型:先讲独立部署的产物与版本矩阵,再讲配置驱动的灰度(入口切换而非代码发版),最后点明跨应用变更的联合验证边界,体现对「独立」与「协同」两面的平衡。

#
★★

12. Module Federation 在构建(Rspack/Turbopack)下的新配置

Module Federation 在 Rspack、Turbopack 等新一代构建工具下如何使用?配置上有哪些新特性与注意点?

  • Rspack/Turbopack 对 MF 的原生或兼容支持方式
  • 新构建器下 MF 配置的差异与等价项
  • 生态成熟度与迁移注意事项

Rspack 提供与 webpack 高度对齐的 ModuleFederationPlugin,配置项(name、exposes、remotes、shared、runtimePlugins)基本兼容,可直接迁移,且构建性能显著提升;Vite 生态则通过 @module-federation/vite 插件支持 MF,把 webpack 的联邦语义映射到 Vite 的构建体系;Turbopack 目前对 MF 的支持仍在演进,官方立场是优先对齐 webpack 的核心联邦能力,实验特性(如 runtimePlugins、snapshot 全量能力)需关注版本进度。新构建器下的注意点:产物格式与 runtime 入口(remoteEntry)的生成路径、publicPath 的解析方式、共享依赖的检测规则可能不同,迁移后必须做联邦契约测试验证共享协商与远程加载行为一致。

本题考工具链动态:先答各构建器对 MF 的支持现状(Rspack 对齐、Vite 插件桥接、Turbopack 演进中),再答配置等价与迁移验证要点。回答体现「配置迁移 ≠ 行为一致,需契约测试兜底」的工程谨慎。

#
★★

13. 无界(Wujie)基于 WebComponent + iframe 的隔离创新

无界(Wujie)如何用 WebComponent + iframe 实现微前端隔离?相比纯 iframe 或纯 Proxy 沙箱方案有何创新与取舍?

  • 无界的双沙箱模型:iframe 提供 JS 运行环境,WebComponent 提供 DOM 容器
  • 与 qiankun Proxy 沙箱、传统 iframe 方案的对比
  • 通信与样式穿透的处理方式

无界的核心是「JS 与 DOM 分层隔离」:子应用 JS 在隐藏的 iframe 中执行(利用 iframe 天然独立的 window 与全局环境实现强 JS 隔离,规避 Proxy 沙箱的逃逸面),渲染结果通过 iframe 的 document 与基座 DOM 的桥接(shadowRoot 或 WebComponent 容器)呈现到主应用页面,配合样式在容器内的隔离,形成 WebComponent 承载 DOM、iframe 承载 JS 的双沙箱模型。相比传统 iframe:无界把 iframe 作为「运行引擎」而非「呈现容器」,避免 iframe 常见的地图/弹窗/焦点问题,且通信通过框架内部的桥接层完成,性能优于频繁 postMessage 的纯 iframe 方案。相比 qiankun 的 Proxy 沙箱,无界隔离更彻底(JS 天然隔离),但子应用内的跨域资源、定位与弹窗场景仍需特殊处理(如元素吸附到主文档的适配)。

本题考框架创新点:先讲清双沙箱模型的职责划分,再对比纯 iframe(呈现问题)与纯 Proxy 沙箱(逃逸面)的取舍,最后提通信与样式穿透的工程处理,展示对隔离方案的横向比较能力。

#
★★

14. 微前端间通信(props/事件总线/全局状态)与耦合控制

微前端主子应用间有哪些通信方式?各自适用什么场景,如何控制通信带来的耦合?

  • props 下发、事件总线(EventBus/CustomEvent)、全局状态(qiankun globalState)的机制对比
  • 通信方式的适用场景与耦合度分析
  • 通信契约化与命名空间治理

主流通信方式有三类:props 传递(基座在 mount 时下发数据与回调,单向、显式、适合初始化参数与少量事件);事件总线(基于 CustomEvent 或 mitt,松耦合、适合广播类事件,但全局可见、需命名空间治理);全局状态(qiankun globalState、共享 store,适合跨应用共享的会话与主题状态,但引入读写约定)。耦合控制的核心是「契约化」:把通信数据定义成稳定接口(字段、语义、版本),事件用统一前缀命名并集中管理生命周期;优先用 props 等显式通道承载强关联数据,事件与全局状态只承载弱关联广播,避免子应用直接依赖基座内部实现。同时做好清理:事件监听在 unmount 时注销,状态订阅在销毁时断开。

回答按「机制—场景—耦合控制」三层展开:先对比三种通道的语义,再给选型建议(强关联用 props、广播用事件、共享用全局状态),最后落到契约化与清理的工程治理,体现通信设计的克制。

#
★★

15. 微前端的路由(主子应用)协同与冲突处理

微前端主子应用的路由如何协同?切换与冲突如何处理?

  • 基座路由驱动子应用挂载的 activeRule 机制
  • 子应用内部路由与基座路由的同步(hash/ history 模式)
  • 路由冲突:路径前缀规划、激活规则重叠

协同模式是「基座主导、子应用跟随」:基座监听路由变化,按 activeRule 匹配激活对应子应用,再把子应用挂载到指定容器;子应用内部保留自己的路由实例,负责自身页面的导航与状态。同步方式上,hash 模式下子应用路由天然挂在基座 hash 之下、冲突少;history 模式下需要约定子应用路由前缀(如 /app1/*),基座把匹配部分交给子应用,避免基座路由与子应用路由互相吞并。冲突处理的核心是「前缀规划 + 激活规则不重叠」:子应用路由统一挂自己的前缀,activeRule 精确匹配前缀,切换时按顺序卸载旧应用、挂载新应用,并处理边缘情况(如激活重叠时按注册顺序或显式优先级裁决、子应用内跳转到其他应用域的路径时交由基座接管)。

回答先立「基座主导」的协同模型,再分 hash/history 讲同步机制,最后落到前缀规划与激活规则去重等冲突治理,点明「路由是微前端最重要的集成点之一」的工程地位。

#
★★

16. remoteEntry 与 publicPath 配置陷阱,子应用独立部署换域或换路径后远程模块 404 的定位与修复

Module Federation 中子应用独立部署换域或换路径后远程模块 404,通常是什么原因?如何定位与修复?

  • publicPath 对 chunk 加载路径的影响机制
  • remoteEntry 地址与运行时入口配置的关系
  • 动态 publicPath 与部署规范的修复手段

404 的典型根因是「构建期写死路径」:webpack 打包时按 publicPath 生成 chunk 的相对/绝对引用,若 publicPath 写死为旧域名或旧路径,换域/换路径后运行时按旧地址请求资源即 404;remoteEntry 同理,其内部暴露的模块路径按构建时 publicPath 生成。定位方法:看 Network 中失败请求的完整 URL,对比当前部署地址与 publicPath 的差异,即可确认是路径问题而非模块问题。修复手段:部署域不固定时使用动态 publicPath(如 webpack_public_path 按运行时注入,或用 MF 的 runtime 配置动态指定);部署域固定时把 publicPath 配置为完整域名;同时统一产物目录规范(版本号子目录),让 remoteEntry 与 chunk 的相对关系稳定。

本题考构建产物路径依赖:先讲 publicPath 如何决定运行时资源地址、remoteEntry 内部引用的生成规则,再给定位方法(Network 对比 URL)与修复(动态 publicPath、规范部署),体现从现象到根因的排查思路。

#
★★

17. 沙箱内 window 全局对象身份分裂(非顶层 window)对缓存 window 引用的第三方库的影响与修复

沙箱内 window 全局对象身份分裂指什么?对缓存 window 引用的第三方库有什么影响,如何修复?

  • 沙箱 fakeWindow 与真实 window 身份分裂的本质
  • 第三方库缓存 window/document 引用的后果(事件绑定错位、全局状态丢失)
  • 修复:代理一致性、运行时补丁与构建期规避

身份分裂指沙箱代理(fakeWindow/proxy)与浏览器真实 window 不是同一个对象:第三方库若在初始化时把 window 缓存到局部变量(如 const win = window),后续所有操作都绕过沙箱代理,直接作用于真实全局——子应用沙箱内的隔离设置、全局变量与事件监听落点因此错位,出现「沙箱内设置了状态,库读到的却是另一个 window」的诡异问题。影响典型表现:基于缓存引用的全局事件绑定散落在真实 window 上无法随子应用清理、window.xxx 全局变量在两套对象间不同步。修复思路:库层面用代理对象替代真实 window 注入并保持引用一致(沙箱把代理作为唯一全局透出,缓存到代理);工程层面评估库是否依赖 window 身份(如 isTopWindow 判断、window.window 自引用),必要时用 iframe 强隔离规避;或改造库改为每次访问 window 而非缓存。

先定义身份分裂的产生机制(代理与真实对象不相等),再讲缓存引用如何绕过沙箱造成隔离失效,最后给出代理一致性、强隔离、改造库三层修复方案,体现对沙箱边界问题的深度理解。

#

18. Module Federation 与 SSR 的结合(服务端组装)难点

Module Federation 与 SSR 结合(服务端组装)有哪些难点?如何缓解?

  • 服务端联邦的时序问题:远程模块在 SSR 阶段的获取
  • 双端运行时一致性:共享状态与依赖单例
  • 降级与容错:服务端拉取失败的处理

难点主要有三:其一,时序问题——SSR 要求在服务端渲染前拿到远程模块代码与数据,而联邦依赖运行时获取,需要在 Node 端实现远程模块的同步/提前获取(如构建期预取产物、运行时加载 remoteEntry 再执行模块),把「浏览器端懒加载」变成「服务端可控加载」;其二,双端一致性——服务端渲染与客户端水合必须使用同一份依赖实例与共享状态,否则出现 invalid hook call、状态分叉,因此 shared 的 singleton 策略在双端都要生效,且水合用的模块版本必须与 SSR 产物一致;其三,容错——服务端远程拉取失败时要有降级(用本地副本渲染、或跳过该远程片段),避免整页 500。缓解手段:把联邦加载收敛到统一的 SSR 加载器、SSR 产物与 CSR 产物共用版本快照、远程模块在服务端做超时与降级编排。

本题考联邦与渲染模型的冲突:SSR 需要「渲染前可用」,联邦本质是「运行时按需」,所以三个难点都围绕这一矛盾展开(时序、双端一致性、容错),回答以矛盾为主线逐条展开并给缓解措施。

#

19. 微前端下的公共依赖(React/Vue)单例化策略

微前端下 React/Vue 等公共依赖为什么要单例化?有哪些实现策略?

  • 框架类依赖多实例的破坏性(hooks 状态、全局上下文)
  • 单例化的实现路径:CDN external、shared singleton、npm 对齐版本
  • 单例策略的约束与风险

框架类依赖必须单例化是因为框架普遍依赖全局单例状态:React 的 hooks 调度器、Vue 的全局配置与响应式系统、各自的 devtools 钩子,多实例并存会导致 invalid hook call、组件状态错乱、事件补丁重复等问题,且内存翻倍。实现策略有三类:CDN external——把框架打成全局脚本在基座加载,子应用 external 引用同一全局,最彻底但要求所有应用版本一致且无法按需加载;Module Federation shared + singleton——联邦运行时保证全局一份,配合 requiredVersion 校验版本范围,是最现代的做法;npm 对齐版本——各子应用独立打包但 CI 强制锁同一版本,简单但运行时无法验证,属于「靠约定」。约束与风险:单例化后框架升级是全量变更,需版本治理与灰度;external 模式下子应用脱离构建器管理,调试与 tree-shaking 受限。

回答先讲「为什么」——框架全局状态对多实例的敏感,再给三条策略并比较适用场景,最后点出单例化的治理代价(升级即全量变更),形成完整决策框架。

#

20. 微前端的渐进式迁移(存量系统绞杀者模式)

存量系统如何用绞杀者模式渐进式迁移到微前端?迁移过程如何保持系统可用?

  • 绞杀者模式的核心思想:以新应用逐步替代旧功能
  • 路由级别的绞杀落地:旧系统新功能并存
  • 迁移期的数据、鉴权与体验一致性

绞杀者模式(Strangler Fig)主张不重写巨石系统,而是在其外围逐步长出新的模块,用新功能「绞杀」旧功能,直到旧系统被完全替换。微前端是其天然载体:基座路由作为绞杀入口,新业务按域建成子应用挂到基座,旧功能继续由存量系统承接,用户无感。落地要点:路由级分流——旧系统与新的微前端基座通过网关或应用级路由共存,未迁移页面仍由旧系统渲染;数据层通过 API 兼容保证新旧模块对同一业务数据的一致性;鉴权由统一 SSO 承接,避免迁移期间登录态割裂。收益是每步迁移都可独立发布、独立回滚,风险面小;最终旧系统可整体下线。迁移顺序建议按「高价值低耦合」的功能优先,并保持对外 URL 与体验的渐进一致性。

本题考迁移方法论:先讲绞杀者模式的哲学(增量替代而非重写),再落到微前端路由级绞杀的具体架构与数据/鉴权一致性保障,最后给出迁移顺序建议,体现架构演进的节奏感。