仓库与整体架构总览
1. Monorepo 分层结构
Formily 是标准 monorepo(Yarn workspace + Lerna),核心关注包:
@formily/reactive:响应式引擎(Proxy + 依赖追踪 + 调度)。@formily/core:表单领域模型(Form / Field / ArrayField / ObjectField / VoidField)。@formily/json-schema:Schema 协议、表达式编译、x-reactions 结构化联动。@formily/react:React 绑定层(SchemaField、RecursionField、ReactiveField)。@formily/reactive-react:将 reactive 与 React 组件生命周期桥接(observer/useObserver)。@formily/path:路径 DSL 与匹配系统(字段寻址、批量匹配、解构路径)。@formily/validator:校验能力(被 core 调用)。
表述建议:Formily 不是“一个表单组件库”,而是“表单领域模型 + 响应式运行时 + 协议层 + 多端绑定层”的组合架构。
2. 顶层设计目标(从 README 与源码反推)
从仓库 README 与代码实现可明确看到三大目标:
- 高性能:避免传统受控表单整树重渲染,转为字段级状态管理。
- 动态化:以 JSON Schema +
x-*协议承载后端驱动和低代码场景。 - 联动友好:支持主动式(事件)与被动式(依赖)两套联动范式。
源码层面的关键实现抓手:
- 字段状态拆分在
Form.fields图结构中(而非仅 React state)。 - 响应式触发通过
@formily/reactive在模型层完成。 - React 层只负责“按需消费模型状态”并渲染。
3. 运行时主链路(从创建到渲染)
3.1 创建 Form(模型初始化)
Form 构造阶段依次做:
initialize:初始化模型属性、Graph、Heart。makeObservable:定义可观察字段(computed/action/batch)。makeReactive:监听values/initialValues深变更并触发生命周期。onInit:发布ON_FORM_INIT。
这意味着 Formily 的“核心状态机”在领域模型层,而不是 UI 层。
3.2 创建字段(按需挂载)
React 层 Field 组件调用 form.createField。核心逻辑是:
- 若同路径字段已存在则复用(除 designable 模式外)。
- 创建后发布
ON_FORM_GRAPH_CHANGE,供生态层(调试、插件、联动)感知。
3.3 Schema 渲染(声明式转运行态)
SchemaField -> RecursionField -> Field|ArrayField|ObjectField|VoidField:
Schema协议先转toFieldProps()。 -(x-reactions被编译为 reactions 函数)- 最终变成 core 可执行的字段创建参数。
4. 为什么是“领域模型优先”而不是“UI 优先”
这套架构的本质优势:
- 跨框架迁移成本低:核心逻辑在
core/reactive/path/json-schema,React/Vue 只是绑定层。 - 业务可测试性更好:模型 API(
setFieldState/query/validate/reset)可直接单测。 - 复杂场景更稳:动态字段、数组迁移、联动校验等不用完全依赖组件生命周期。
代价:
- 学习曲线比纯组件库高;
- 调试需要理解地址路径、数据路径、生命周期事件。
5. 可落地的 30 秒总结
“Formily 的核心不是表单组件,而是一个 MVVM 化的表单领域运行时。@formily/reactive 负责精细依赖追踪,@formily/core 负责表单模型和生命周期,@formily/json-schema 负责协议与动态编译,@formily/react 只是把模型投影到 React。
因此它在复杂联动、动态字段和大表单性能上比传统受控方案更有结构性优势。”