0009. React 适配器直接挂载 Core
This page is only available in Chinese. It is shown in its original language.
- Status: Proposed
- Date: 2026-10-09
- Deciders: 363045841(owner), tseka
- Source: v1.1 ADR-006
Context
@363045841yyt/klinechart-react 目前只导出 KLineChartWC,它渲染由 Vue 打包的 <kline-chart> 自定义元素。v0.10.4 曾主动移除直连 Core 的工厂、hooks 和 KLineChart 组件,理由是 SSR 安全(docs/release/v0.10.4.md)。因此 v1.1 ADR-006 是对既有决定的反转,需要回答两点:
- SSR:Core 模块在加载期会访问浏览器全局(实测在 Node 中加载
config时模块求值期即访问localStorage;在 jsdom 等有 DOM 的环境中还会创建 canvas 并调用getContext),静态导入会进入服务端求值路径。 - 功能对等:Web Component 带完整产品 UI(工具栏、指标、画线、设置、Agent 面板),直连适配器只有图表本身。
同时,docs/architecture/adapter-architecture.md §5.2 仍描述着已不存在的 useChart / KLineChart,文档与代码不一致。packages/angular 已经直接调用 createChartController,React 是三个适配器中唯一绕道 Vue 的。
Decision
React 包同时提供两个层级,KLineChartWC 保持不变:
| 导出 | 用途 | Vue 运行时 |
|---|---|---|
KLineChartWC | 需要完整 KCQ 产品 UI 的 React 宿主 | 需要 |
KLineChart、useKLineChart、useCoreSignal | 自建外围 UI 的宿主、Expo DOM component(ADR 0010)、未来的 React 产品 UI | 不需要 |
实现约束:
- Core 只在客户端 effect 中通过动态
import()加载,SSR 只输出容器节点。服务端渲染有专门测试(@vitest-environment node)。 - 控制器创建是异步的:卸载或 StrictMode 双挂载时,迟到的控制器在 resolve 后立即
dispose()。 - 挂载参数只在首次挂载时读取;之后
data、theme、settings通过控制器方法增量同步,主题优先级与 Angular 适配器一致(显式theme>settings.theme,auto只注入系统主题)。 useCoreSignal基于useSyncExternalStore,与 Core signal 的引用相等语义一致,不做额外拷贝。- 控制器创建失败时抛给最近的 Error Boundary。
Consequences
- v1.1 验收标准「React 直接使用 Core,无 Vue 运行时依赖」:做 tree-shaking 的打包器(Vite、webpack、Next)只用
KLineChart时不会打入 Vue。Metro 不做 tree-shaking,会顺着KLineChartWC的动态导入把整套 Vue UI 和字体打进产物(P3 实测 14.5 MB),因此另设@363045841yyt/klinechart-react/direct入口,只含直连挂载。安装层面仍会装上 Vue 包,因为它是dependencies;改为可选 peer 属于破坏性变更,留到下一个 minor。 - 直连挂载依赖 Core 自建的 DOM 骨架(
buildDom)。P3 发现该路径此前从未在真实浏览器中渲染验证:缺少 Vue 组件 CSS 对应的布局、WebKit 首帧不布局 pane、恢复的布局会清空挂载数据。三处已修复,并由createChartController.directMount.test.ts覆盖;packages/react/preview/direct.html用于人工核对。宿主需提供有确定尺寸的容器。 - 输入接线由 ADR 0008 P1b 的
bindChartInput提供,与 Vue 组件共用;宿主可通过input选项注入拦截钩子,或传false自行转发事件。 adapter-architecture.md§5.2 更新为实际 API。- 如果 owner 仍倾向 v0.10.4 的单一 WC 路线,可以只合入 ADR、不合入代码;代码是纯增量,回滚即删除新文件和导出。