关键设计决策与 Issue/PR 依据
本章给出“设计结论 -> 为什么 -> 证据”的对照,便于回答“依据是什么”。
1. configure 应继承父链而非制造重复链
- 设计结论:
configure需要保留正确 parent 语义,避免 hook 重复执行。 - 原因:扩展继承链如果错位,会导致插件重复注册、回调重复触发。
- 证据:
- Issue/PR #5147
packages/core/src/Extendable.ts中configure/extend逻辑
2. insertContent 需要可选触发 rules
- 设计结论:命令写入不应绕开输入/粘贴规则。
- 原因:流式文本、程序化输入等场景希望与用户输入行为一致。
- 证据:
- Issue/PR #5046
- core 命令与 InputRule/PasteRule 联动演进
3. React 默认行为要平衡首屏可用与 SSR 安全
- 设计结论:引入
immediatelyRender+useSyncExternalStore体系。 - 原因:既要减少无意义中间渲染,又要避免 SSR hydration 风险。
- 证据:
- PR #5161
- Issue #5856
packages/react/src/useEditor.ts
4. 多实例下 CSS 不应被单实例 unmount 误删
- 设计结论:仅在“页面无其他编辑器实例”时移除注入 CSS。
- 原因:共享样式被提前移除会导致存活实例 UI 损坏。
- 证据:
- Issue #6836
- PR #7109
packages/core/src/Editor.ts与packages/core/__tests__/unmounted.spec.ts
5. Suggestion 必须支持事务级显示过滤
- 设计结论:
shouldShow提供事务上下文过滤。 - 原因:协同环境中远端事务不应触发本地候选框;同时兼容 IME 组合输入边界。
- 证据:
- Changelog v3.15.1(Suggestion
shouldShow) packages/suggestion/src/suggestion.tspackages/suggestion/src/__tests__/suggestion.test.ts- Issue #1449
- Changelog v3.15.1(Suggestion
6. BubbleMenu props 响应要防止插件抖动回归
- 设计结论:props 响应能力与插件实例稳定性需要折中设计。
- 原因:依赖项一旦过多,可能导致频繁 unregister/register,引发 selection 问题。
- 证据:
7. 协同历史必须单一化(Yjs 与本地 history 不能叠加)
- 设计结论:协同模式下使用 Yjs UndoManager,不与
undoRedo并用。 - 原因:两个历史栈会产生冲突语义与不可预测行为。
- 证据:
packages/extension-collaboration/src/collaboration.ts中警告与命令实现- 历史协同相关 bug 修复记录(issue #1973 及 changelog)
8. Markdown 必须“扩展驱动”,不能只靠固定语法映射
- 设计结论:Markdown parse/render 与 extension schema 同步注册。
- 原因:编辑器能力可组合,Markdown 输入输出必须与当前 extension 集一致。
- 证据:
packages/markdown/src/MarkdownManager.tspackages/markdown/src/Extension.ts- Issue #7107
9. 一句话总括(一句话总括)
Tiptap 的设计核心是:把不可避免的复杂度(事务、时序、兼容性)收敛在内核与扩展基础设施里,把业务侧暴露成稳定、可组合的 API。