Fronts 2.0
运行时指南

Host 运行时 API

组合 Fronts Host,并使用解析、加载、生命周期、替换、观测与关闭 API 的操作指南。

Host 是解析、加载、授权、挂载、替换和清理应用的唯一事务边界。精确签名以 packages/core/src/host/types.ts 为准。平台 shell、本地 producer 开发、Storybook 和集成测试应走同一条 Host 路径;独立应用只需 静态 resolver 与本地 loader,不需要全局注册或第二套 lifecycle API。

组合边界

const host = createFrontsHost({
  hostId: 'store-shell',
  resolver: createStaticResolver([
    {
      match: { name: 'checkout', channel: 'stable' },
      resolve: { source: checkoutSource, version: '2.4.1' },
    },
  ]),
  loader: checkoutLoader,
  containers: [createDomContainer(), createShadowContainer()],
  services: { telemetry },
});

composition root 拥有 Host、resolver、transport loader、container adapter、静态 services 和 transport runtime。resolver 只选部署,不加载代码;loader 只返回包含有效 FrontsApp 的 module, 不拥有应用生命周期;container 拥有执行面和自己声明的资源;Host 拥有事务顺序、取消、readiness、 rollback 与 audit。Shell 还必须单独 dispose 自己创建的 MF instance plugin、registry client 等资源。

主要配置包括必需的 resolver/loader,容器集合和按 type 覆盖的 containerLoaders,静态 services、实例 createServicescapabilityPolicyreadyTimeoutMs,可控的 host/instance/ operation/trace ID factory,非阻塞 observer 与测试时钟。ID factory 必须返回非空字符串;timeout 必须有限且非负,0 只关闭该 deadline,不关闭取消。生产环境应从应用 SLO 设置有限值。

操作地图

API用途是否创建实例主要影响
resolve()查看策略选出的部署仅 resolver
load()解析、加载并验证 app,不挂载可能填充 transport cache
preload()预热可能使用的部署loader preload 或 fallback load
mount()完整事务并等待 readyservices、container、app handle
replace()保持当前实例可用并 staging 候选提交新实例后清理旧实例
get()/inspect()读取 live handle 或事务 snapshotinspect 会裁剪干净 terminal record
audit()/assertIdle()检查实例、pending、cleanup failure 和 retained DOMassert 转成稳定 leak error
subscribe()非阻塞观测 state/error event返回 unsubscribe
unmount()按 ID 卸载 live instance执行该实例完整清理
dispose()停止 Host、abort、卸载并证明清理terminal 且幂等

直接 resolve/load/preload 也计入 pending Host work;它们没有 application identity,但会出现在 audit().pendingOperations,并被 dispose() abort。

解析、加载和预加载

resolve() 适合在不取代码时显示 rollout 决策或不可变 artifact URL。environment、tenant、cohort 等字段是不可信的选择输入,不是授权凭证;registry 必须自行认证和授权。load() 返回 { app, resolved },但不创建 target、service scope 或 mounted identity,主要用于 producer contract 工具,普通导航应直接 mount。

preload() 只是优化,绝不是 readiness 证据。loader 没有 preload 时 Host 会普通 load;之后的 mount 必须重新解析,因为 channel、tenant assignment 或 registry decision 可能变化。可用相同 trace 关联 preload 和 mount,但不能重用 operation ID。

挂载事务

Host 在异步工作前校验并快照 instance/operation/trace ID。identity 只能由 Host 颁发,应用、loader 或浏览器输入不得提供授权身份。caller 仍拥有 props 与外部 target;reference、policy、resolution metadata 和 container request 等 Host envelope 会被快照。任一阶段失败或 abort 都走同一条回滚, readiness timeout 是失败,不能作为隐藏成功。

部署 metadata 决定隔离方式时,可传 container resolver:

container: ({ resolved }) =>
  resolved.metadata?.isolate === true
    ? { type: 'shadow', mode: 'closed' }
    : { type: 'dom', className: 'account-surface' };

它在 resolution 之后、loader 选择之前运行,收到可信 identity、operation、冻结的 policy/resolved、 signal 与 Host target;必须确定性地产生 request,不能自行 mount。

上下文服务

无状态共享实现使用静态 services;需要绑定实例、租户、trace 或 disposable resource 时使用 createServices。provider service 覆盖同名静态 service,之后 Host 才按声明和 policy 生成仅含 own keys 的可撤销 facade。abort/unmount 先 revoke,再 dispose provider;provider 必须响应 signal, 并在返回前抛错时自行回滚尚未移交的资源。

async createServices({ identity, operation, resolved, signal }) {
  const span = telemetry.startSpan('fronts.application', {
    instanceId: identity.instanceId,
    traceId: operation.traceId,
    version: resolved.version,
  });
  signal.addEventListener('abort', () => span.addEvent('aborted'), { once: true });
  return {
    services: { telemetry: { emit: (name, data) => span.addEvent(name, data) } },
    dispose: () => span.end(),
  };
}

实例控制与就绪替换

activate()update(nextProps)deactivate()unmount() 在每个实例上串行。producer 没有 activate/deactivate callback 时它们仍有效;没有 update 时则返回 lifecycle error。abort(reason) 触发 instance signal 并卸载。持有 handle 时调用 application.unmount(),集中跟踪 ID 时调用 host.unmount(id)

replace(id, options) 在 hidden/inert staging slot 中挂载候选;候选 resolve/load/mount/ready 全部成功前,当前实例保持可用。staging 失败必须保留旧实例;commit 后旧实例 cleanup 失败不回滚 已 ready 的新实例,而是返回 previousCleanupError 并留在 audit;同一 current instance 只能有一个 replacement。业务验证失败应回退 registry 决策再 replace,不能直接修改活跃 MF deployment cache。

观测、错误和关闭

subscribe() listener 不参与事务,不得在 Host call stack 中抛错或慢执行。inspect() 看事务状态, audit() 还包含 live instance、cleanup failure、direct operation、replacement 和 terminal state 后 仍保留的容器。instance/trace ID 放日志与 trace,不要做高基数 metric label;metric 应按 app、version、 container type、phase、error code 聚合。

捕获 FrontsError 时使用稳定的 codephase,不要解析 message;保留 cause 但在 telemetry 中移除 tenant-sensitive metadata 与 service 参数。composition root 在 shell shutdown 和每个集成测试 后调用 dispose():它拒绝新任务、abort signals、等待 pending mount/replace、卸载全部 live app、 清除 listener,并在 audit 仍证明泄漏时 reject。最后用 host.assertIdle() 明确验证。

验证

core host/replacement/observability/services 测试覆盖顺序、取消、替换、审计与 provider disposal; core-only E2E 验证无 MF 路径,vertical-slice E2E 验证 React、Vue、DOM、Shadow DOM 和 iframe 的同一契约。

本页目录