ProseMirror
模块化、可扩展的富文本编辑器底层框架,TipTap 等众多编辑器的基石。
ProseMirror 是模块化富文本编辑器框架,采用函数式状态管理和不可变事务模型,通过 JSON Schema 系统定义文档结构,是 TipTap、Milkdown 等上层编辑器框架的基石,被誉为编辑器领域的"编译器"。
ProseMirror
模块化、可扩展的富文本编辑器底层框架,TipTap 等众多编辑器的基石。
技术简介说明
ProseMirror 是由 Marijn Haverbeke(也是 CodeMirror 和 Acorn 的作者)创建的一个模块化富文本编辑器框架。它不是一个开箱即用的编辑器,而是一组精心设计的底层模块,提供了构建任何类型富文本编辑器所需的全部基础设施。
ProseMirror 的核心创新在于其函数式状态管理模型——编辑器状态是不可变的,所有修改通过事务(Transaction)产生新的状态。这种设计使得撤销/重做、协作编辑等功能天然具备可靠的基础。其文档模型基于 JSON 的 Schema 系统,确保文档结构始终合法。
作为编辑器领域的"编译器",ProseMirror 支撑了包括 TipTap、Milkdown、Tinode 等多个上层编辑器框架。它的设计哲学是提供强大的原语和组合能力,而非预设的 UI 或功能。
基本信息
- 官网:https://prosemirror.net/
- GitHub:https://github.com/ProseMirror/prosemirror(主仓库,多包 Monorepo)
- License:MIT
- 最新版本:
- prosemirror-model: 1.25.10
- prosemirror-view: 1.42.0
- prosemirror-state: 1.4.3
- prosemirror-transform: 1.10.4
- prosemirror-markdown: 1.13.5
- 主要维护者:Marijn Haverbeke(个人项目)
- GitHub Stars:~7,000+(主仓库)
- npm 周下载量:prosemirror-view ~10.5M(作为底层依赖)
快速上手
安装
# 核心包
npm install prosemirror-model prosemirror-state prosemirror-view prosemirror-transform
# 常用辅助包
npm install prosemirror-commands prosemirror-keymap prosemirror-inputrules
npm install prosemirror-schema-basic prosemirror-schema-list
npm install prosemirror-history prosemirror-markdown
# 基础示例需要的所有包
npm install prosemirror-model prosemirror-state prosemirror-view prosemirror-commands prosemirror-keymap prosemirror-inputrules prosemirror-schema-basic基础配置
import { EditorState } from 'prosemirror-state'
import { EditorView } from 'prosemirror-view'
import { schema } from 'prosemirror-schema-basic'
import { keymap } from 'prosemirror-keymap'
import { baseKeymap } from 'prosemirror-commands'
import { inputRules, wrappingInputRule } from 'prosemirror-inputrules'
import { history, undo, redo } from 'prosemirror-history'
// 定义 Schema(或使用预定义的 schema)
const mySchema = schema // 使用基础 schema
// 创建编辑器状态
const state = EditorState.create({
schema: mySchema,
plugins: [
history(),
keymap({ 'Mod-z': undo, 'Mod-y': redo }),
keymap(baseKeymap),
],
})
// 挂载编辑器视图
const view = new EditorView(document.querySelector('#editor'), {
state,
})最小示例
<!DOCTYPE html>
<html>
<head>
<style>
.ProseMirror {
min-height: 200px;
padding: 10px;
border: 1px solid #ccc;
outline: none;
}
.ProseMirror p { margin: 0.5em 0; }
.ProseMirror h1 { font-size: 2em; }
</style>
</head>
<body>
<div id="editor"></div>
<script type="module">
import { EditorState } from 'prosemirror-state'
import { EditorView } from 'prosemirror-view'
import { schema } from 'prosemirror-schema-basic'
import { keymap } from 'prosemirror-keymap'
import { baseKeymap } from 'prosemirror-commands'
import { history, undo, redo } from 'prosemirror-history'
const state = EditorState.create({
schema,
plugins: [
history(),
keymap({ 'Mod-z': undo, 'Mod-y': redo }),
keymap(baseKeymap),
],
})
const view = new EditorView(document.querySelector('#editor'), { state })
</script>
</body>
</html>核心概念与架构
架构设计
ProseMirror 采用模块化架构,核心由以下独立模块组成:
┌─────────────────────────────────────────────┐
│ EditorView │ ← 渲染层
├─────────────────────────────────────────────┤
│ EditorState │ ← 状态层
│ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ Schema │ │ Doc │ │ Plugins │ │
│ │ (Model) │ │ (Model) │ │ │ │
│ └──────────┘ └──────────┘ └──────────────┘ │
├─────────────────────────────────────────────┤
│ Transactions │ ← 变更层
│ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ Transform│ │ Steps │ │ Mapping │ │
│ └──────────┘ └──────────┘ └──────────────┘ │
└─────────────────────────────────────────────┘
核心概念
- Schema(模式):定义文档的合法结构,包括节点类型(Node Spec)和标记类型(Mark Spec)
- Document(文档):基于 Schema 的 JSON 文档树,由 Node 和 Text 组成
- State(状态):不可变的编辑器状态,包含文档和插件状态
- Transaction(事务):描述状态变更的操作序列,产生新状态
- Step(步骤):事务的原子操作单元,包括 ReplaceStep、AddMarkStep 等
- Plugin(插件):扩展编辑器行为的机制,可监听事件、修改输入、添加装饰
- Mapping(映射):跟踪文档位置在不同版本间的对应关系
- Decoration(装饰):在文档之上叠加的视觉层,不影响文档内容
工作原理
- 用户输入产生 DOM 事件
- EditorView 将 DOM 事件解析为 ProseMirror 操作
- 操作创建 Transaction(包含 Steps)
- Transaction 应用到 State 产生新 State
- 新 State 通过 diff 更新 DOM
核心特性
- 函数式状态管理:不可变状态 + 事务模型,确保状态可预测和可回溯
- Schema 系统:声明式文档结构定义,保证文档始终合法
- 模块化设计:每个模块职责单一,按需组合
- Plugin 系统:强大的扩展机制,支持输入规则、键盘绑定、事件监听
- 协作编辑基础:通过 Transform 和 Step 的精确追踪,天然支持 CRDT 协作
- 增量解析:高效处理大文档的更新和渲染
- Markdown 互转:prosemirror-markdown 提供与 Markdown 的双向转换
- Clipboard 管理:统一的剪贴板序列化/反序列化
- Decoration API:纯装饰(如协作光标)不修改文档内容
- 跨框架:纯 JavaScript 实现,不绑定任何 UI 框架
生态图
核心包生态
| 包名 | 说明 |
|---|---|
prosemirror-model | 文档模型、Schema 定义 |
prosemirror-state | 编辑器状态管理、Transaction |
prosemirror-view | DOM 渲染和事件处理 |
prosemirror-transform | 文档变换(Steps、Mapping) |
prosemirror-commands | 内置编辑命令 |
prosemirror-keymap | 键盘绑定 |
prosemirror-inputrules | 输入规则(如 # → H1) |
prosemirror-history | 撤销/重做 |
prosemirror-schema-basic | 基础 Schema |
prosemirror-schema-list | 列表 Schema 扩展 |
prosemirror-markdown | Markdown 序列化/反序列化 |
prosemirror-changeset | 变更追踪(tracked changes) |
prosemirror-collab | 协作编辑基础 |
prosemirror-dropcursor | 拖放光标 |
prosemirror-gapcursor | 不可编辑元素旁的间隙光标 |
prosemirror-tables | 表格支持 |
上层框架生态
- TipTap:基于 ProseMirror 的最流行的无头编辑器框架
- Milkdown:基于 ProseMirror 的 Markdown 编辑器
- remirror:React 封装层
- prosemirror-extensions:社区扩展集合
协作编辑
- y-prosemirror:Yjs 与 ProseMirror 的桥接
- Hocuspocus:TipTap 的协作后端
- Liveblocks:提供 ProseMirror 协作集成
适用场景
- 构建自定义编辑器框架:如需从零构建一个编辑器产品,ProseMirror 是最坚实的底层选择
- 编辑器框架开发:TipTap、Milkdown 等上层框架的基础
- 复杂文档编辑:需要严格的文档结构约束(如法律文档、学术出版)
- 协作编辑引擎:利用 Step/Transform 模型实现实时协作
- Markdown 编辑器:通过 prosemirror-markdown 实现所见即所得的 Markdown 编辑
- 表格编辑器:prosemirror-tables 提供完整的表格编辑能力
- 内容迁移工具:利用文档模型的 JSON 表示实现跨系统内容迁移
开发与工程化
开发流程
# 克隆仓库
git clone https://github.com/ProseMirror/prosemirror.git
cd prosemirror
# 安装依赖
npm install
# 构建
npm run build
# 测试
npm test
# 开发单个模块
cd packages/prosemirror-view
npm run dev构建配置
ProseMirror 各模块使用 Rollup 构建,支持 ESM 和 CJS 输出:
// rollup.config.js 示例
import { nodeResolve } from '@rollup/plugin-node-resolve'
export default {
input: 'src/index.js',
output: [
{ file: 'dist/index.cjs', format: 'cjs' },
{ file: 'dist/index.js', format: 'es' },
],
plugins: [nodeResolve()],
}调试技巧
// 使用 prosemirror-dev-tools
import { applyDevTools } from 'prosemirror-dev-tools'
const view = new EditorView(/* ... */)
applyDevTools(view) // 在浏览器中提供编辑器状态检查器性能与安全
性能特点
- 增量渲染:仅更新变化的 DOM 节点,避免全量重渲染
- 增量解析:输入规则和大文档操作使用增量解析策略
- 高效 Diff:Transaction 的 Step 序列确保最小化 DOM 更新
- 大文档支持:文档模型本身可处理大型文档,瓶颈通常在渲染层
性能优化
- 使用 Decoration 而非修改文档来展示临时视觉效果
- 合理设计 Schema,避免过度嵌套
- 对大文档考虑虚拟滚动方案
- 在 Plugin 的
filterTransaction中拦截无效事务
安全注意
- CVE-2025-64501:2025 年 11 月修复的安全漏洞,涉及 HTML 输入解析
- 始终对粘贴和拖放的 HTML 内容进行消毒
- Schema 的
parseDOM规则需要审慎设计,防止 XSS 注入 - 服务端处理编辑器内容时使用 DOMPurify 等工具
技术对比
| 特性 | ProseMirror | TipTap | Slate | Lexical | Quill |
|---|---|---|---|---|---|
| 定位 | 底层框架 | 上层框架 | 上层框架 | 上层框架 | 开箱即用 |
| 开箱即用 | ❌ 需要大量代码 | ✅ 中等 | ⚠️ 需要较多代码 | ⚠️ 需要较多代码 | ✅ 最低门槛 |
| 状态管理 | 函数式不可变 | 继承 ProseMirror | 不可变 | 不可变 | Delta 操作 |
| Schema | ✅ 强约束 | ✅ 通过扩展 | ⚠️ 弱约束 | ✅ 强约束 | ✅ Blot 系统 |
| 框架绑定 | 无 | React/Vue/Svelte | React | React/通用 | 无 |
| 协作编辑 | 基础模块 | 集成 Yjs | 需自建 | 内置(有限) | 需自建 |
| 学习曲线 | 陡峭 | 中等 | 较陡 | 较陡 | 低 |
| 文档质量 | 优秀 | 优秀 | 中等 | 良好 | 良好 |
ProseMirror 是"造编辑器的编辑器框架",而 TipTap/Slate/Lexical 是"造产品的编辑器框架"。选择 ProseMirror 意味着你打算构建自己的编辑器框架而非直接构建产品。
最佳实践
- 从 Schema 开始:先仔细设计文档 Schema,再实现编辑逻辑
- 使用 Plugin 封装关注点:每个 Plugin 只负责一个功能领域
- 利用 Transaction 的 filter:使用
filterTransaction在应用前校验变更 - 谨慎处理 DOM 解析:
parseDOM规则要覆盖所有可能的 HTML 输入 - 合理使用 Decoration:临时视觉效果用 Decoration 而非修改文档
- 测试 Step 操作:Step 的
apply和invert方法是协作编辑的基础,需要充分测试 - 使用 prosemirror-dev-tools:开发阶段使用调试工具检查编辑器状态
技术局限与边界
- 学习曲线陡峭:概念多(Schema、Transaction、Step、Mapping、Plugin),上手困难
- 需要大量样板代码:从零构建一个可用的编辑器需要编写大量代码
- 无内置 UI:所有 UI 元素(工具栏、气泡菜单等)需要自行实现
- 无内置样式:不附带任何 CSS,样式完全自定义
- 社区规模有限:相比 TipTap 等上层框架,直接使用 ProseMirror 的社区较小
- 单人维护风险:核心由 Marijn Haverbeke 一人维护
- 协作编辑需要额外工作:prosemirror-collab 提供基础,但完整的协作方案需要配合 Yjs 等
学习资源
- 官方文档:https://prosemirror.net/docs/
- 参考指南:https://prosemirror.net/docs/ref/
- 示例:https://prosemirror.net/examples/
- 教程:https://prosemirror.net/docs/guide/
- 社区论坛:https://discuss.prosemirror.net/
- GitHub 仓库:https://github.com/ProseMirror/prosemirror
- Changelog:https://prosemirror.net/docs/changelog/
- Marijn 的博客:https://marijnhaverbeke.nl/blog/(涉及 ProseMirror 设计理念)
2026 年现状
最新版本
- prosemirror-model: 1.25.10(2026 年 6 月更新)
- prosemirror-view: 1.42.0
- prosemirror-changeset: 2.4.0(2026 年 2 月)
发展趋势
- 持续稳定维护:以 bug 修复和小幅改进为主,保持 API 稳定
- 社区创新:基于 ProseMirror 的 Canvas 编辑器、Web Component 等实验性项目
- 上层框架驱动:TipTap 3.0 的成功为 ProseMirror 生态带来更多关注
- 安全修复积极:2025 年修复了 CVE-2025-64501 等安全漏洞
社区活跃度
- 论坛活跃:discuss.prosemirror.net 持续有新讨论
- GitHub Stars:~7,000+
- npm 生态下载量:底层依赖,prosemirror-view 周下载 ~10.5M
- 被 TipTap 等上层框架间接驱动发展
定位总结
ProseMirror 在 2026 年依然是富文本编辑器领域最强大的底层框架。对于大多数项目,建议选择基于 ProseMirror 的上层框架(如 TipTap),而非直接使用 ProseMirror。只有当你需要完全控制编辑器架构的每一个层面时,才考虑直接使用 ProseMirror。