Skip to content
目录

架构总览与包分层

1. 先看结论(可先说)

Slate 的核心是一个operation 驱动的、schema-less 的编辑引擎。渲染层(React/DOM)和历史层(undo/redo)是插件叠加,而不是写死在 core。

一句话分层:

  • slate:数据模型、操作系统、变换与规范化(纯编辑核心)
  • slate-dom:DOM <-> Slate 的映射与浏览器兼容层
  • slate-react:React 组件、事件管线、渲染优化
  • slate-history:基于 operation 的历史批次管理

2. Monorepo 包职责

packages/slate

核心编辑器对象与算法层,入口由 createEditor() 组装:

  • editor.children / selection / operations / marks
  • 可覆写行为:isInlineisVoidnormalizeNodeinsertText
  • 核心执行器:editor.apply(op)

packages/slate-dom

把抽象位置(Path/Point/Range)映射到真实 DOM:

  • toDOMPoint / toDOMRange
  • toSlatePoint / toSlateRange
  • findPathtoSlateNode

packages/slate-react

React 集成层:

  • <Slate /> 上下文
  • <Editable /> 输入事件编排(selectionchange/beforeinput/composition)
  • selector 订阅机制 + chunk 渲染优化

packages/slate-history

历史栈插件 withHistory

  • undos / redos 两个 batch 栈
  • Operation.inverse 做可逆回放
  • merge/saving/split 策略控制批次边界

3. 关键执行链路(从用户输入到文档更新)

  1. 浏览器触发输入事件(beforeinput、composition、selectionchange)
  2. slate-react 把事件转换为 Slate 命令(Editor.* / Transforms.*
  3. 命令内部发出一个或多个 operation(如 insert_textset_selection
  4. editor.apply(op) 执行统一管线(更新 refs、更新 dirtyPaths、应用变换、normalize、onChange)
  5. React 层在下一个 flush 中拿到 editor.operations,做 UI 同步/订阅分发

这条链路是最重要的“系统观”。


4. 源码证据(建议背)

4.1 createEditor 是可覆写能力的装配点

文件:packages/slate/src/create-editor.ts

  • 默认 isInline: () => false / isVoid: () => false
  • 表示 core 不绑定业务 schema,由业务 plugin 覆写

4.2 apply 是唯一可信执行入口

文件:packages/slate/src/core/apply.ts

  • 先更新 PathRef/PointRef/RangeRef
  • Transforms.transform(editor, op)
  • Editor.normalize(editor, { operation: op })
  • 最后异步 flush editor.onChange({ operation: op })

4.3 React 层只消费 editor,不替代 core

文件:packages/slate-react/src/components/slate.tsx

  • <Slate /> 只把 onChange 与 editor 绑定
  • editor.children = initialValue 初始化一次

5. 为什么要这样拆(设计动机)

  1. 可扩展性:复杂编辑器(表格、mention、嵌套 block)需要高度可定制,不适合硬编码 schema。
  2. 可维护性:输入法、浏览器差异属于 UI/DOM 问题,不应污染 core。
  3. 可组合性:历史、协作、序列化都可建立在 operation 之上。
  4. 可测试性:core 可在无 DOM 环境下做大量 fixture 测试,React 层做集成行为测试。

6. 口头表述模板

Slate 的架构是“core + adapters + plugins”。
slate 只处理文档与 operation,不关心浏览器细节;slate-dom 负责点位映射与兼容;slate-react 做事件编排与渲染;slate-history 在 operation 上实现 undo/redo。
这种拆分的结果是:核心稳定、UI 兼容性问题局部化、性能优化可以在 React 层独立演进。

MIT License.