Template-system 研发成功|远程组件用宿主 React 的完整思路纪要

背景与目标

昨天的核心问题:React 实例重复(远程主题各自带 React,与宿主不一致,导致 hooks/上下文失效)。
今天的目标:远程主题共享宿主 React 实例,并把首屏链路、时序与缓存都调顺。


核心方案总览

  1. React 实例单点来源

    • 远程主题不再自带 React。

    • import mapreactreact/jsx-runtime 指向宿主侧的 bridge 代理

    • 代理使用 Proxy 懒绑定:只有真正访问 API 时才从 window.__REACT__ / window.__REACT_JSX__ 取值,避免时序开箱即炸。

  2. 时序与可见性保证

    • ReactBridge(客户端组件)在 useEffect 中把宿主的 React / jsx-runtime 赋值到 window,这是副作用,放在 effect 更符合语义。

    • Bridge 赋值后 dispatchEvent('react-ready') 对外广播“可用了”。

    • 远程加载流程在真正 import(url)await waitForReactGlobal()

      • 事件优先唤醒,requestAnimationFrame 轮询兜底,可设超时/可中断。

      • 本质是一个 Promise,把“React 注入就绪”变成可等待的条件。

  3. 页面装配方式

    • RootLayoutbody 顶部挂 ReactBridge(最早可用的位置)。

    • 在具体 page 里再去加载远程组件(在 loader 内部已 await waitForReactGlobal())。

    • import map scopes(可选强化):仅对 CDN 前缀生效,确保宿主自身 import 不被代理污染。


构建与一致性

  1. vendor manifest 升级

    • 远程产物的 manifest 新增 "versions",记录 react / react-dom / react/jsx-runtime官方版本号

    • "files" 仅保留需要从 CDN 拉的部分(如 react-dom / react-dom/client 等)。

  2. import map 构建策略

    • reactreact/jsx-runtimebridge 代理(宿主提供)

    • react-domreact-dom/client(以及可选 scheduler)→ CDN 路径

    • 版本校验:在构建 import map 之前,比较“宿主本地包版本”与 “vendor manifest.versions”。

      • Dev:不一致直接抛错;Prod:仅记录错误日志并继续(不中断业务)。


性能与网络

  1. modulepreload 精准化

    • 只预热 react-dom/client(“钥匙带大门”),让首个远程 ESM 链路更快进入可执行态。

    • react/jsx-runtime 已走宿主代理,无需 CDN 预热。

    • 可加 preconnect 到 CDN,抢先建链路。

  2. ETag 与强缓存友好

    • 远程产物文件名包含官方版本 + hash

    • 请求使用 cache: 'no-cache' + ETag,让“未变更 304 / 已变更更新”逻辑清晰。


正确性要点(踩坑清单→反坑方案)

  • 竞态:任何在 ReactBridge 赋值前执行的 import 'react' 都会炸 → 通过 waitForReactGlobal() 统一“就绪条件”,并让 proxy 惰性取值

  • CSP:避免 new Function原生 dynamic import 加忽略注释,规避 unsafe-eval

  • 宿主污染:使用 scopes 限定 import map 只影响 CDN 来源模块。

  • 版本漂移:manifest 与宿主包版本比对,Dev fail-fast,Prod 打点报警。

  • 可演进性:proxy 使用 Reflect.get 保持 accessor/原型链/符号键行为一致,兜底未来 API。


当前落地状态

  • ✅ 远程主题组件已成功加载并共享宿主 React。

  • ✅ 首屏链路稳定:Bridge → ready 事件 → loader 等就绪 → import 远程模块。

  • ✅ 版本一致性与预热策略闭环。

  • ✅ 方案不绑定框架特性,可复用于多主题/多租户/按需上线的场景。


后续可选优化(展望)

  • 更细颗粒的 modulepreload:根据远程入口 URL 自动生成预热列表。

  • 运行时观测:对版本不一致、加载失败、超时的路径埋点上报。

  • RSC 兼容轨道:在 server 侧补“远程清单预计算与签名”,为后续 RSC/SSR 组合打底。


一句话总结:

我们通过 import map + bridge + Proxy 懒绑定 + 时序等待,把远程主题的 React 依赖切换为“宿主单例”,配合 版本校验精准预热,从根上解决了“React 实例重复”的老大难问题,并把整条加载链路收敛成可维护、可观测、可演进的工程系统。

posted @ 2025-08-16 11:29  PEAR2020  阅读(14)  评论(0)    收藏  举报