整体架构与包分层
1. 一句话架构
Tiptap 是一个“基于 ProseMirror 的无头编辑器框架”:底层用 ProseMirror 负责文档模型与事务,中层用扩展系统组织能力,上层分别提供 React/Vue 等框架适配。
2. Monorepo 分层(可直接背)
packages/core:编辑器内核(Editor、命令系统、扩展系统、NodeView 基类)。packages/pm:对 ProseMirror 生态包的统一依赖出口(降低版本错配风险)。packages/react/packages/vue-*:框架绑定层(生命周期桥接、渲染优化、NodeView 适配)。packages/extension-*:功能扩展层(table、mention、collaboration、link、list…)。packages/markdown:Markdown 解析/序列化引擎(基于marked,通过扩展注册能力)。packages/suggestion:自动补全基础设施(mention/emoji/command palette 常用)。packages/starter-kit:开箱组合包(常见 node/mark/历史能力的“可裁剪预设”)。
3. 核心设计理念
3.1 无头(Headless)优先
- 官方 README 明确定位“headless + framework-agnostic”。
- 内核只关心状态、事务、扩展生命周期,不内置 UI。
- 价值:UI 与业务高度自由,适配设计系统更容易。
3.2 扩展即能力单元
- 内核几乎所有能力都通过 extension 注入(commands、keymap、input/paste rules、PM plugins、node/mark view)。
Editor初始化时会组装“核心扩展 + 用户扩展”,统一交给ExtensionManager。- 价值:能力组合、重写、禁用都走统一路径,符合“插件式平台”设计。
3.3 对 ProseMirror 的“薄封装 + 可扩展增强”
- 事务与状态更新仍遵循 ProseMirror 模式。
- Tiptap 额外提供:
- 统一命令 API(
commands/chain/can) - 扩展生命周期事件(
onCreate/onUpdate/...) - 框架桥接(React/Vue hooks & components)
- 高阶能力(协同、Markdown、Suggestion)
- 统一命令 API(
4. 启动路径(从构造到可编辑)
new Editor(options):合并选项,创建扩展管理器、命令管理器、schema。- 解析初始内容,先建立
EditorState(即使未 mount)。 mount(element)时创建EditorView。- 将
ExtensionManager.plugins重新配置到 state。 - 创建 nodeViews/markViews,注入 CSS,异步触发
create事件。
这个流程的关键是:状态可先于视图存在,所以即使未挂载,命令与状态访问仍可控(通过 view 代理兜底)。
5. 为什么要单独有 @tiptap/pm
常问“为什么不直接让用户装 ProseMirror 全家桶?”
- ProseMirror 包多且相互版本敏感,业务侧容易出现重复实例/版本漂移。
- Tiptap 用
@tiptap/pm统一出口,把“版本整合风险”收敛到框架内部。 - 对扩展作者也更友好:依赖路径稳定。
6. 架构优势与代价
优势:
- 高扩展性:新增能力基本不改内核,只增扩展。
- 高可移植性:同一套扩展可在 React/Vue 使用。
- 易于演进:单个扩展可独立修复和发布。
代价:
- 抽象层级高,调试链路比“直接用 ProseMirror”更长。
- 扩展顺序、优先级、组合关系是常见坑点。
- React/Vue 桥接下,生命周期与事务同步需要持续处理边界(SSR、StrictMode、unmount race)。