跳转到内容

微前端最终留下了什么?

这一系列最开始有一句话一直留在我脑子里:

TRUE independent teams

TRUE 被完全大写了。听起来很像营销,而营销承诺并不会因为写得更大声就变得更真实。

在写完 21 篇关于边界、Ownership、Release、Runtime Integration、运维与成本的文章之后,可以重新看一次这句话——这次不必再带着第一次看到它时应有的嘲讽。

这个承诺并不是根本错误,只是不完整。真正的团队自治,不会因为一个应用技术上被拆成一个 Host 和多个 Remote 就自动出现。它需要一整套其他条件同时成立:清晰的业务边界、清晰的 Ownership、显式 Contract、独立的可变更性和可测试性、受控 Release、可管理的 Runtime Dependency、明确的故障边界、Observability、平台 Guidance、Governance——以及一个在真正不方便时,依然愿意尊重这些边界的组织。

技术上的 Remote 只是其中一部分。它从来不是目标本身,而始终只是实现目标的若干手段之一。

Host 和 Remote 都只是技术手段。真正的目标是变化自治:一个团队能够决定、实现、测试、发布并运行某项修改,而不必为日常变化反复协调组织里的其他团队。

一个产品完全可以拥有十个 Remote,却依然高度耦合:

修改 Members Remote
Shell 必须同步修改
Tasks 团队也必须修改
需要共享测试环境
需要联合验收
需要共同 Release 时间

技术架构是分布式的。

工作方式并不是。

这个 Remote 可以独立部署。只是下一次修改还需要另外三个团队批准而已。

任何架构图都不会展示这种状态。图里只有方框和箭头,不会画出 Slack 里一个团队等另一个团队批准的消息。正因为如此,真正的自治不能通过方框数量判断,只能看一次修改实际上如何穿过整个组织。

有一个主题贯穿整套文章:URL 属于谁?某个业务 State 属于谁?某个业务流程属于谁?UI、故障、Release、API Contract 属于谁?什么应该放在 Shell,什么应该放在 Remote?谁有权激活一套新的产品组合?

这些问题反复出现不是偶然。几乎每个微前端问题,最后都会变成 Ownership 问题。

清晰边界
清晰职责空间
清晰 Ownership
减少必须的协调
更多真实团队自治

当然,边界本身不会自动产生这一切。没有 Ownership 的边界,意味着没有人真正承担这个区域。没有清晰边界的 Ownership,则意味着多个团队在修改同一职责空间。没有业务边界的 Deployment Boundary,依然只是技术分布、组织耦合。缺少运维责任的业务边界,则会让团队虽然“拥有代码”,却在测试、Release 或生产运行时继续等待别人。

清晰边界不是目的本身。它创建了一个团队可以真正负责的空间。只有这种责任,才可能带来自治。

因此,每次画出新边界时,都值得问同一个检查问题:这个区域半夜出故障时谁负责?客户投诉时谁负责?需要 Migration 时谁负责?如果这个答案很难给出,那么这条边界很可能只是技术切分,而并没有真正形成组织意义上的职责。

TRUE independent teams 不能被理解成完全隔离。共同产品中的团队仍然共享产品目标、用户、平台、设计原则、技术标准、安全要求、API、部分业务流程以及同一生产环境。完全独立既不现实,也通常没有必要。

真正值得关注的是那些会强迫多个团队共同修改、共同等待、共同协调的依赖关系。

一个团队不是因为“没有依赖”才独立。真正的独立,是它的职责足够清晰,使大多数修改都能在自己的边界内决定、实现、测试、发布并运行。

独立团队仍然需要共同 Guidance。这和自治并不矛盾,反而是自治的前提:没有统一的技术护栏,每个团队都会重新解决一遍同样的平台问题——Integration Contract、Observability、Security、Release Metadata、Design System、Build 与 Deployment Convention。

Guidance 让好的局部决策更容易。中央控制则让局部决策变得不可能。Platform Team 可以帮助自治,也完全可能成为下一个瓶颈。分界点很简单:一个团队是否为了日常修改,仍然频繁依赖另一个组织单元。

Ownership 也不是组织结构图上的一个方框。仅仅把某个 Remote “分配”给一个团队不够。这个团队必须真的能够承担边界内的责任,包括生产运行、故障分析以及持续演进。

组织结构图可以把一个 Remote 指给某个团队。它不能强迫团队真正拥有与之对应的职责。这个差异决定了一张漂亮架构图最后会变成真实自治,还是只是责任矩阵里的又一行。

微前端不是组织“顺手引入”就能掌握的东西。即便是经验丰富的开发者,也不会因为熟悉 Angular、React 或 Module Federation,就自动掌握分布式前端架构。

真正麻烦的地方很少出现在第一个 Tutorial 里。它们往往晚很多才出现:Remote 突然需要 Shell State。Global Event Bus 变成业务 Integration Layer。Shared Library 偷偷传递 Ownership。所谓独立 Release 仍然需要完整产品验收。Shell 不断积累更多产品知识。Runtime Version 漂移。Rollback 遇到已经不兼容的 API。Observability 无法把用户故障对应到具体 Build。Platform Team 变成中央排队系统。

最难的问题通常发生在第一次成功 Deployment 之后。

微前端架构是一种团队和组织都要学习的能力。这里的“学习”不是拿证书,而是积累经验、形成清晰架构原则、建立共同 Guidance、做 Review、从生产反馈中修正,并愿意在边界失效时重新划边界。

第一个 Remote 几天就能搭起来。真正理解“今天看起来无害的依赖,为什么两年后可能成为问题”,通常要慢得多——很多时候,只有亲自承担过类似决定的后果之后才会明白。

架构边界通常死于很多合理的小例外

Section titled “架构边界通常死于很多合理的小例外”

很多失败的 MFE 架构并不是因为技术选型本身错了,而是逐渐发生侵蚀。

“就这一个 Shared Package。”
“就这一个 Shell Service。”
“就这一个全局 Event。”
“就这一个共同 Release Step。”

每个例外单独看都很合理。几年之后,它们又重新组成了一个强耦合架构。

架构边界很少因为某个巨大错误决定瞬间消失。更多时候,它们是在一连串非常合理的小例外里一点点被磨掉的。

因此,自治不仅需要一开始画对边界,还需要持续维护这些边界。

成功不意味着 Remote 越多越好、越小越好、Repository 越多越好、Deployment 越多越好、Framework 越多越好,也不意味着 Shared Code 越少越好。

架构同样可以拆得过头。

真正重要的是:这种分布是否真的减少了协调,还是只是增加了基础设施。

只有当被减少的协调成本长期高于分布本身的成本时,分布才值得。

模块化 Monolith 并不是“失败的微前端系统”。如果一个团队,或者少数紧密协作的团队,能够共同修改、测试和发布某个业务区域,那么 Monolith 可能就是经济上和技术上更好的方案。

同样,Migration 完全可以有意识地停下来。曾经独立的 Remote 也完全可以在以后重新合并。

架构不是一个从 Monolith → 微前端 → 更多微前端不断向右推进的进度条。

如果一个团队能够在 Monolith 中从容地拥有自己的业务区域,它并不是“还没进化到更好的东西”。它已经实现了这一整套文章真正追求的目标。

读完这 21 篇文章之后,决定“这里根本不需要微前端”,与有意识地选择分布式方案一样,都是完全有效的架构决策。

好的 MFE 架构体现在日常工作中,而不是架构图里。

五个观察就足够:

一个团队可以修改自己的 Capability,而无需经常协调多个其他团队。Remote 可以独立开发并进行聚焦测试。普通修改不要求完整产品验收。故障和失效被限制在清晰边界内。生产问题可以对应到具体 Build 和具体产品组合。

反向检查同样有效:如果修改 Members Remote 时,经常还要修改 Shell、Tasks、某个 Shared Library,然后做联合验收,那么架构也许是分布式的。

变化本身并不是。

这些观察不需要 Dashboard。任何愿意诚实回顾最近几个 Release 的团队都能回答。

第一次看到 TRUE independent teams 时,我最不喜欢的其实是那个 TRUE。写完这一系列之后,视角变得更细了一些。

这个承诺确实可以实现——只要 independent 不被误解成“隔离”。它需要清晰 Ownership、可承载的边界、Platform Guidance、技术 Contract、合适的运维模型、纪律和经验。组织也必须真的愿意把这些责任交给团队。

架构可以支持团队自治。

组织仍然可以阻止它。

所以,也许真正有问题的词并不是 TRUE。有问题的是一种想象:好像第一个 Remote 建出来之后,这份自治就免费附送了。

微前端并不是为了复杂而复杂,也不会自动产生价值,更不是所有团队都必须追赶的“未来”。它只是针对一种特定情况的工具:多个团队共同工作在同一个前端产品上,但希望能够修改自己的区域,而不必因为日常变化不断等待彼此。

如果不存在这种问题,那么微前端也没有解决任何无法通过更简单方式解决的问题。

TRUE independent teams 是可能的。但它们是有意识设计架构和组织之后的结果,不是执行一次 nx generate 之后的默认状态。

判断一套微前端架构是否优秀,不要看前端有多分布式,而要看一次普通修改需要动用多少组织。