高频问答与回答框架
1) Plate 和 Slate 的关系是什么?
短答
Slate 是底层编辑器引擎;Plate 在其上提供插件系统、类型封装、生态插件、UI/文档/模板。
加分点
Plate 不是简单封装:它重构了能力组织方式(例如 api/tf 分层)并提供了插件解析管线。
2) Plate 插件系统如何保证顺序可控?
短答resolvePlugins 先按 priority 排序,再按 dependencies 递归重排,最后缓存执行路径。
源码证据packages/core/src/internal/plugin/resolvePlugins.ts
3) 为什么要把方法从 editor 顶层迁移到 api/tf?
短答
为了解决接口污染、增强可读性,并支持 transform-only middlewares 与覆盖机制。
证据docs/migration/v48.mdx 对动机有直接解释。
4) createSlatePlugin 和 createPlatePlugin 差别?
短答
前者是无 React 基础插件工厂;后者在其上注入 Plate React 能力(通过 toPlatePlugin)。
追问可答
这让 SSR/静态链路和 React 链路共享核心插件语义。
5) 如何理解 overrideEditor 与 extendEditor?
短答overrideEditor 更偏“覆写已有方法”,边界清晰;extendEditor 更偏直接扩展 editor,适合整合 legacy withX 能力。
证据
文档 docs/(guides)/plugin.mdx 已明确建议优先 overrideEditor。
6) 为什么 NodeIdPlugin 默认重要?
短答
很多高级交互依赖稳定块 ID(块选择、DND、表格、TOC、toggle 等);没有 ID 会导致跨插件语义不稳。
证据docs/(guides)/editor.mdx 对依赖 ID 的插件有清单说明。
7) serializeHtml 出现 invalid hook call 的根因可能是什么?
短答
静态序列化链路误用了依赖 React runtime 的插件,跨层边界被破坏。
证据
Issue #2804
工程建议
维护独立 serialize plugin profile,不直接复用编辑态完整插件数组。
8) Plate 如何做大文档性能优化?
短答
chunking、热路径短路、初始化启发式检查、规则化 API 变更减少无效工作。
证据ChunkingPlugin、SlateExtensionPlugin.apply、NodeIdPlugin。
9) Yjs 协同初始化为什么容易踩坑?
短答
关键在“先同步远端再决定是否写本地初始值”,否则会覆盖远端文档。
证据BaseYjsPlugin 的 init 流程里有显式判断 sharedRoot 是否为空。
10) AI 插件设计里最关键的工程点是什么?
短答
不是“调用 LLM”,而是把 AI 输出纳入编辑器选择语义、历史系统、流式中间态管理。
证据AIChatPlugin 的 options/transforms/api 设计(streaming、chatSelection、reload/stop/accept)。
11) 为什么 Plate 强调 migration 文档?
短答
因为它是高迭代框架,重构频率高。迁移文档是“设计意图 + 迁移策略”的正式输出,不只是变更日志。
12) 你会如何在业务里引入 Plate?
建议回答框架
- 先按场景拆插件 profile(编辑、导出、只读)
- 对核心节点(paragraph/list/table/link)建立业务约束
- 自定义插件时优先 rules/override,不先改底层
- 对协同和 AI 做 feature flag
- 建立版本升级 checklist(看 migration + issue)
13) 如果让你评价 Plate 的架构优缺点?
优点
- 插件系统可组合且可治理
- 类型体系强,扩展边界清晰
- 生态覆盖广(AI、Yjs、表格、序列化等)
挑战
- 学习曲线相对高
- 升级需要读 migration 和 issue/PR
- 场景分层(edit/serialize/static)配置不当容易踩坑
14) 一句话总结(终极题)
Plate 是一个“插件编排型编辑器平台”:它用明确的分层和可追踪的演进策略,把复杂富文本能力拆成可组合的工程模块。