会议室里,Angular写的日程表、某主流框架做的白板、Svelte绘的流程图,正在同一块屏幕上实时协作。这不是技术 demo 的炫技,而是一家公司真实的技术债现状——三个团队、三种框架、同一个业务域。

事件现场

打开网易新闻 查看精彩图片

想象这个场景:产品总监打开一个会议管理应用。左侧是 Angular 写的参会人列表,中间嵌入某主流框架驱动的 Excalidraw 白板,右侧弹出 Svelte 实现的 Mermaid 流程图编辑器。三个框架没有互相"翻译",没有渐进式重写,没有 iframe 沙盒。它们共享同一份会议上下文,用户的每一次涂改、每一个节点调整,都实时同步到同一个状态池。

这是「弗兰肯斯坦架构」的演示现场——不是缝合尸体,而是缝合技术栈。

作者开宗明义:一个企业里存在三种前端框架,是常态而非例外。A 团队多年前选了 Angular,B 团队爱上某主流框架,并购部门又带进来一套 Vue。标准答案是重写——两年周期、十人团队、数百万投入,然后失败。

但作者提出了另一条路:让它们共存。

为什么重写总是输

企业前端的技术异质性,被很多人当成"暂时的混乱"——仿佛只要足够努力,就能扫进历史的垃圾堆。作者直接否定了这个前提。

并购会带来新栈。团队会选自己熟悉的工具。行业浪潮比代码寿命更短,曾经的主流框架会在应用停止盈利之前就先过气。重写优先的文化把这一切视为必须消灭的问题:两年、十名工程师、一个框架统天下。

结果通常是:重写上线时,主流框架又换了,原团队已经离职,业务方开始质疑投入产出比。

作者的核心判断很直接——异质性不是病,是永久性条件。设计目标不该是"如何统一成一个框架",而是"如何让多个框架共享一个产品"。

一条规则定生死

整个架构规范浓缩成一句话:

「Remote 拥有能力。Host 拥有业务上下文与持久化。」

拆解来看:每个远程模块(Remote)只负责自己擅长的——画图、制表、排程、报表。宿主(Host)只负责业务本质——会议、客户、订单、理赔。远程模块不碰状态、不碰路由、不碰用户身份。它们被塞入一个上下文时开始渲染,用户在界面操作时向外发射变更事件。

演示中的分工很明确:Angular 宿主掌管会议上下文,某主流框架远程托管 Excalidraw 白板,Svelte 远程托管 Mermaid 图表编辑。能力可以替换——白板换成报表,图表换成排程,骨架不变。

这里有个关键的技术现实:当宿主跑 Angular、远程跑某主流框架时,不存在共享的组件模型,不存在共享的 Hook 系统,不存在共享的响应式机制。那种"把某主流框架组件塞进 Angular 模板"的技巧,经不起生产环境的检验。

所以每个远程模块必须是一个完整、自包含的应用——一座孤岛。它向宿主暴露的不是某主流框架组件或 Svelte 组件,而是一个自定义元素(Custom Element),把整个应用包进去,在挂载时启动。

代码示例展示了标准做法:

class WhiteboardRemote extends HTMLElement {

connectedCallback() {

this.root = createRoot(this);

this.root.render();

disconnectedCallback() {

this.root?.unmount();

customElements.define('whiteboard-remote', WhiteboardRemote);

宿主像消费普通 DOM 元素一样消费远程模块:

[context]="meetingContext"

(change)="onWhiteboardChange($event)">

Angular 的语法糖包裹了标准