关键设计决策:动机、取舍与证据
这一章是本章最为重要:把“看起来分散的实现细节”归并成可复述的架构决策。
决策 1:Monorepo + 高颗粒度包拆分
动机
- 降低单包耦合
- 提升 tree-shaking 和按需安装能力
- 让插件生态独立演进
证据
packages/*多包结构(本地可见 48 个)tooling/CONTRIBUTING.md的 workspace 结构约定- Discussion #363 早期就讨论了 modularisation、renderless、包拆分方向
取舍
- 发布编排复杂度上升(需要 changesets + turbo)
- 但长期可维护性、生态扩展能力明显提升
决策 2:插件系统做“编译式解析”,不是运行时零散拼接
动机
- 插件顺序、依赖、覆盖可预测
- 降低插件规模变大后的隐式冲突
证据
resolvePlugins的 flatten/merge/sort/dependency passresolvePluginOverrides的覆盖模型- PR #1882 动态插件修复影响范围巨大,说明这是系统关键路径
取舍
- 初始化逻辑更复杂
- 换来执行时更稳定、更可调试的插件行为
决策 3:editor.api / editor.tf 分层
动机
- 降低顶层 editor 方法污染
- 统一“只读能力”和“变更能力”的边界
- 为 transform middleware 与 override 铺路
证据
docs/migration/v48.mdx(@udecode/plate-core@42.0.0)对 Why 有明确解释withSlate.ts的方法注入实现
取舍
- 存量代码迁移成本
- 换来更清晰类型系统和长期可扩展性
决策 4:React 绑定与核心能力分层
动机
- 让静态/服务端/纯数据链路不被 React 运行时绑死
- 避免导出/序列化流程受 UI 插件影响
证据
withSlate与withPlate双入口ReactPlugin作为独立增强- Issue #2804 暴露“序列化链路混入 React 依赖插件”的真实问题
取舍
- 开发者需要区分编辑态插件和静态态插件配置
- 换来更清晰边界与更少跨层故障
决策 5:性能优化优先从“热路径和默认行为”下手
动机
- 富文本编辑是高频交互,任何额外开销都会被放大
证据
SlateExtensionPlugin.apply无监听器时直接快路径NodeIdPlugin首尾启发式检查ChunkingPlugin默认大文档优化- Issue #2627 把构建体验也纳入性能议程
取舍
- 需要维护更多“默认策略 + 可配置开关”
- 换来普适性能与大文档稳定性
决策 6:AI 与协同都走插件一等公民路线
动机
- 避免“外挂能力”破坏编辑器一致性(历史、选择、变更语义)
证据
BaseAIPlugin/AIChatPlugin的 transforms + state 设计BaseYjsPlugin的 init/connect/sync 一体化流程
取舍
- 插件复杂度上升
- 但可维护性和可观测性优于旁路集成
总结话术(可直接复述)
Plate 的核心设计哲学是:
把编辑器当作可编排平台,而不是富文本组件集合。
所以它优先做的是边界清晰(core/react)、执行可预测(resolve pipeline)、能力可治理(api/tf + plugin stores),再通过 issue/PR 驱动持续性能和体验优化。