Fronts 2.0
核心概念

应用契约

Fronts 2.0 的框架无关应用协议、生命周期所有权、就绪、服务和兼容规则。

协议身份

每个 producer 都导出由 defineApp()defineReactApp()defineVueApp() 创建的 FrontsApp。helper 添加不可枚举的 symbol brand,并公开可枚举的协议名称和版本。symbol 只是 同一 JavaScript realm 内的标记;跨 package ABI 是结构化 mount shape、协议名称和 major 版本。 Host 始终验证 ABI,symbol 不能绕过协议版本检查。

Module Federation expose 通常导出默认应用:

export interface FrontsAppModule<Props, Services extends object> {
  readonly default: FrontsApp<Props, Services>;
}

默认 expose 为 ./application,也可在 AppRef 中显式选择其他 expose。

Mount 输入

interface MountContext<Props, Services extends object> {
  readonly identity: {
    readonly instanceId: string;
    readonly name: string;
    readonly version?: string;
    readonly expose?: string;
    readonly traceId?: string;
  };
  readonly props: Readonly<Props>;
  readonly services: Readonly<Services>;
  readonly signal: AbortSignal;
  readonly target: Element | ShadowRoot;
}

instanceId 在挂载事务或 retained record 存在期间唯一。Host 在事务开始时捕获 props 引用, 但不深拷贝也不冻结调用者对象,双方必须把它当作只读输入。services 只包含应用声明且被 Host 授权的能力;signal 在取消或强制 abort 时触发;target 由当前容器提供并控制。producer 只能在 target 内渲染,除非通过已声明的平台 capability 明确取得其他副作用权限。

Mount 输出与就绪

interface AppHandle<Props> {
  readonly ready?: PromiseLike<void>;
  update?(props: Readonly<Props>): void | PromiseLike<void>;
  activate?(): void | PromiseLike<void>;
  deactivate?(): void | PromiseLike<void>;
  unmount(): void | PromiseLike<void>;
}

mount() 表示应用已接受资源,ready 表示可用 UI 已提交;省略 ready 时,mount 返回即视为 就绪。首次渲染失败必须让 ready reject,不能等待可选 analytics、后台任务或不一定发生的交互。 替换事务只有在候选 ready 后才能提交。

update() 在身份、部署、target、service scope 不变的情况下更新 props;不支持时 Host 报 typed lifecycle error,不会悄悄 remount。activate()/deactivate() 是可选活动提示,必须保留状态, 适合暂停 timer、subscription、media 或昂贵渲染。unmount() 必须存在,并释放 render root、 listener、timer、observer、subscription 和 producer DOM;container element 由 adapter 清理。

状态机与取消

resolving → loading → preparing → mounting → ready

                 ┌──────── updating ◄────────┤
                 ├──────── active   ◄────────┤
                 └──────── inactive ◄────────┘

                                      unmounting → destroyed

任一 pending phase ── failure/abort + rollback ──► failed | aborted

每个实例的操作串行执行;当前状态不允许的调用会以 FrontsError 拒绝,不会跨 destruction 隐式排队。 外部 mount signal 与实例 signal 合并,任一 abort 都阻止新阶段并触发回滚。resolver/loader 应继续 把 signal 传给网络请求。取消是协作式的:同 realm 已执行的 JavaScript 无法强制停止;需要更强 隔离时使用 iframe,并在必要时销毁 child realm。

Capability 与实例服务

应用用字符串声明所需能力:

export default defineApp<Props, HostServices>({
  capabilities: ['navigation', 'telemetry'],
  // ...
});

声明是必要条件而非授权。capabilityPolicy 针对具体 identity 判断每个 key,并收到 instance signal;取消时 runtime 会停止等待异步授权。能力不存在或被拒绝会让普通挂载失败;未声明 service 永远不会进入 facade。清理时 facade 先 revoke,因此应用即使保留 method proxy 也不能继续影响 Host。

静态 services 适合简单情况;需要绑定 identity、tenant、trace 或资源时使用 createServices

createServices({ identity, operation, resolved, resolution, capabilities, signal }) {
  const channel = telemetry.open({
    app: identity.name,
    instanceId: identity.instanceId,
    tenant: resolution.tenant,
    traceId: operation.traceId,
    version: resolved.version,
    signal,
  });
  return {
    services: { telemetry: channel },
    dispose: () => channel.close(),
  };
}

provider 每个 mount/replace 事务只运行一次。它返回的同名服务覆盖静态服务,之后 Host 才做可用性 与 policy 检查。返回即把所有权交给 Host;dispose 最多调用一次,覆盖授权失败、取消、普通卸载和 shutdown。若 provider 在返回前抛错,它仍负责清理自己已分配但尚未移交的资源。

iframe 中,proxy 配置的 capability 是 Host 控制的最大集合,不是最终 grant。child agent 加载 真实应用后协商声明子集,只有精确交集生成 RPC stub,父端每次调用还会复核 grant;child 自己声明 但 offer 中不存在的能力仍会拒绝挂载。应优先提供 navigation.go()telemetry.emit() 这类窄意图 API,而不是 window、整个 Redux store 或泛化全局 event bus。

框架适配器与兼容规则

defineReactApp() 管理 React root、context、error boundary、commit-based readiness、props 更新、可选 Strict Mode 和卸载;defineVueApp() 管理 Vue app、provide context、reactive props、 nextTick() readiness、configure hook 和卸载。它们刻意少于官方 MF Bridge 的路由、数据、SSR 功能:需要这些能力时直接用 Bridge,需要参与 Fronts Host ABI 时才用 Fronts adapter。

协议 major 严格匹配。Host 必须拒绝未知 major,不能猜测行为;新增可选 handle method 可以兼容, 改变 mount 语义、readiness、服务授权或 cleanup 所有权必须提升 protocol major。

验证

packages/core/test/app.test.tshost.test.ts 验证品牌、校验、顺序、就绪和清理; services.test.tsiframe.test.ts 验证 service scope、provider cleanup 和 iframe 协商; React/Vue package 测试证明两个 producer 实现相同契约。

本页目录