news 2026/9/6 20:24:15

Tiptap 编辑器深度解析:Headless 富文本框架的扩展架构、核心 API 与本地实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Tiptap 编辑器深度解析:Headless 富文本框架的扩展架构、核心 API 与本地实战

Tiptap 编辑器深度解析:Headless 富文本框架的扩展架构、核心 API 与本地实战

【免费下载链接】tiptapThe headless rich text editor framework for web artisans.项目地址: https://gitcode.com/GitHub_Trending/ti/tiptap

Tiptap 是一个无界面(headless)、框架无关的富文本编辑器框架,基于 ProseMirror 构建,通过扩展(Extension)机制实现从基础文本样式到复杂块级编辑能力的自由组合。本文以 Tiptap 仓库根目录 README.md 为主线,结合 packages/core 的源码实现与 demos 中的真实示例,完整梳理其设计哲学、包生态结构、EditorOptions配置体系与扩展开发机制,帮助你在本地搭建、运行并二次开发 Tiptap 编辑器。

一、Tiptap 是什么:Headless、框架无关、扩展驱动

根据仓库 README.md 的定义,Tiptap Editor 是一个 headless、framework-agnostic(框架无关)的富文本编辑器,核心特征有四点:

  1. Headless(无内置界面):Tiptap 不附带任何固定 UI,不需要类名覆盖或代码 hack 来改样式,设计自由度完全交给使用者;
  2. 框架无关:同一套核心可以在 Vue、React、Svelte 或纯 JavaScript 环境中集成,无兼容性问题;
  3. 基于扩展:从简单文本样式到拖拽块编辑,功能均由扩展提供。README 提到官方文档与社区提供了上百个扩展可供选择;
  4. UX 完全可控:编辑器允许开发者自定义扩展与节点(Node),把交互体验的定义权交给应用层。

在源码层面,这一理念对应 packages/core 包——它被描述为headless rich text editor(见 packages/core/package.json),当前版本为 3.30.3。Tiptap 的底层构建在 ProseMirror 之上:仓库通过 packages/pm 这一 workspace 包对 ProseMirror 各子模块(model、state、view、schema-list、tables 等)做统一再导出,所有@tiptap/*包都依赖@tiptap/pm而非直接引用上游包,从包管理角度屏蔽了 ProseMirror 的模块拆分细节。

此外,README 指出 Tiptap 与开源协作后端 Hocuspocus 共同构成 Tiptap Suite 的基础,后者围绕 Yjs 的 CRDT 能力构建。本仓库中对应的是 packages/extension-collaboration 等协作相关扩展包。

二、仓库结构:一个多包(monorepo)生态

从仓库目录结构看,Tiptap 是一个典型的 pnpm workspace monorepo,分为四大板块:

2.1packages/:核心与官方扩展

这是最重要的部分,包含:

  • 核心:packages/core(编辑器引擎、扩展基类、命令系统)、packages/extensions(扩展集合)、packages/starter-kit(开箱即用的扩展套件);
  • 框架适配层:packages/react、packages/vue-2、packages/vue-3;
  • 序列化/静态渲染:packages/markdown、packages/html、packages/static-renderer、packages/ai-toolkit(含流式输出 reveal 等 AI 场景工具);
  • 具体功能扩展:按extension-*命名组织,如 packages/extension-bold、packages/extension-heading、packages/extension-table、packages/extension-link、packages/extension-list、packages/extension-collaboration、packages/extension-collaboration-caret、packages/extension-drag-handle、packages/extension-mention、packages/extension-emoji、packages/extension-youtube 等数十个。

2.2packages-deprecated/:废弃包的兼容层

packages-deprecated 下保留了extension-character-countextension-historyextension-placeholderextension-task-item等旧包。例如历史上独立的 ListItem / TableCell / TaskList 等,如今已合并进 packages/extension-list 与 packages/extension-table 这类聚合包中——废弃包的存在说明 Tiptap 在扩展粒度上做过重组,但仍维持向后兼容。

2.3demos/:可运行的官方示例应用

demos 是一个 Vite + 多框架的示例站点,目录按功能域划分:Examples/(默认、协作、无障碍等)、Extensions/(DragHandle、FindAndReplace、TableOfContents 等)、Marks/(Bold、Link、Underline…)、Nodes/(Heading、CodeBlock、Youtube…)、Tutorials/(从 textarea 到 Tiptap 再到 Yjs 协作的渐进式教程)、Experiments/等。每个示例通常包含 React(.jsx/.tsx)与 Vue(.vue)两套实现,这正是 README 所宣称的"框架无关"的直观体现。

2.4scripts/与工程配置

根目录 package.json 定义了整套工程脚本:pnpm dev(启动 demos)、pnpm buildpnpm test:unit(基于vp test)、pnpm test:e2e(Playwright)、pnpm lint/pnpm format(oxlint / oxfmt)等。环境要求为Node >= 24,包管理器固定为pnpm@11.2.2packageManager字段声明)。

三、核心引擎:@tiptap/core的 Editor 与 EditorOptions

3.1 Editor 类

编辑器入口是 packages/core/src/Editor.ts 中的Editor类(自 L59 起)。关键实现事实:

  • Editor继承自EventEmitter(编辑器事件系统),内部持有CommandManager(命令系统)、ExtensionManager(扩展管理器)、ProseMirror 的SchemaEditorViewEditorState
  • 默认选项在 L92-L120 定义,例如content: ''extensions: []autofocus: falseeditable: trueenableInputRules: trueenablePasteRules: true等;
  • 实例具备instanceId(随机生成)、isInitialized标志与extensionStorage(各扩展的持久化存储);
  • 内置核心扩展在构造时自动注入,包括ClipboardTextSerializerCommandsDeleteDropEditableFocusEventsKeymapPasteTabindexTextDirection(见 Editor.ts L11-L22 的导入),它们分别对应键盘快捷键、焦点/失焦事件、粘贴处理等基础行为。

3.2 EditorOptions 完整配置项

完整的选项类型定义在 packages/core/src/types.ts 的EditorOptions接口中,逐项说明如下:

选项类型 / 取值说明
elementElement \| { mount: HTMLElement } \| ((editor) => void) \| null编辑器挂载目标:传Element则追加到该元素;传null则不自动挂载;传函数则由其自行放置编辑器 DOM
contentContent初始内容,支持 HTML 字符串、JSON 对象或 JSON 数组
extensionsExtensions使用的扩展列表
injectCSSboolean是否注入基础 CSS
injectNoncestring \| undefined注入样式时使用的 CSP nonce
autofocusFocusPosition初始聚焦位置
editableboolean是否可编辑(只读模式设为false
textDirection'ltr' \| 'rtl' \| 'auto' \| undefined全文本方向策略:auto会按内容检测设置dir属性
editorPropsEditorProps透传给 ProseMirrorEditorView的 props
parseOptionsParseOptions内容解析选项
coreExtensionOptions对象核心扩展细粒度配置:clipboardTextSerializer.blockSeparatortabindex.valuedelete.async/delete.filterTransaction
enableInputRulesEnableRules是否启用输入规则(如 Markdown 快捷输入)
enablePasteRulesEnableRules是否启用粘贴规则
enableCoreExtensionsboolean \| Partial<Record<...>>布尔值全量开关;也可传对象按名称关闭单个核心扩展,如{ keymap: false }
enableContentCheckboolean,默认false初始化时检查内容合法性,非法时触发contentError事件
emitContentErrorboolean,默认false不做阻断性检查,但保留内容并触发contentError警告
onBeforeCreate/onCreate/onMount/onUnmount回调生命周期钩子
onUpdate/onSelectionUpdate/onTransaction回调内容、选区、事务变化回调
onFocus/onBlur回调焦点事件回调
onDestroy回调销毁回调
onPaste/onDrop/onDelete回调粘贴、拖入、删除的内容拦截回调
enableExtensionDispatchTransactionboolean,默认true是否允许扩展自定义dispatchTransaction钩子

Editor.tsL119-L120 还展示了onContentError的默认行为是直接抛出 errorthrow error),意味着开启enableContentCheck后若不加自定义处理,非法内容会直接中断初始化——这是使用时的一个重要注意点。

3.3 core 包的公开 API

从 packages/core/src/index.ts 可以看出@tiptap/core的完整导出面:EditorExtensionNodeMarkNodeViewMarkViewInputRulePasteRuleCommandManagerTracker,以及内置的commands命名空间、jsx-runtimecreateElement/Fragment,用于在 JS 环境中以 JSX 描述文档节点)等。扩展作者几乎只需要依赖这些导出即可编写新扩展。

四、扩展机制:Extension 的 create / configure / extend 三件套

README 强调 Tiptap "通过扩展定制与扩展能力",其机制实现于 packages/core/src/Extension.ts(L16-L59):

  • Extension.create(config)(L27-L33):静态工厂方法,接受配置对象或返回配置对象的函数,返回Extension实例。这是所有自定义扩展的入口;
  • configure(options)(L35-L37):用新选项创建同一扩展的配置化副本,常用于"给扩展传参"而不改变其行为;
  • extend(extendedConfig)(L39-L58):基于现有扩展派生新扩展,可在派生时覆盖addCommandsaddKeyboardShortcutsaddAttributes等任意配置段,同样支持函数式配置。

Extension继承自Extendable(packages/core/src/Extendable.ts),后者统一处理 name / option / storage 合并逻辑;NodeMark类(packages/core/src/Node.ts、packages/core/src/Mark.ts)分别继承该体系,形成"扩展—节点—标记"三层结构。

以仓库内一个最小扩展为例,packages/extension-strike/src 展示了如何定义一个 Mark 类扩展并注册strike命令与 HTML 序列化规则;而 packages/extension-heading/src 则展示了 Node 扩展如何声明level属性。两者都可配合__tests__目录下的用例(如 packages/extension-strike/tests的测试文件)验证行为。

五、快速上手:StarterKit 与仓库内真实示例

5.1 StarterKit 包含什么

packages/starter-kit/package.json 的依赖列表就是它的完整内容:extension-documentextension-paragraphextension-text(文档结构三件套)、extension-headingextension-blockquoteextension-bullet-list/extension-ordered-list/extension-list/extension-list-item(标题、引用与列表)、extension-bold/extension-italic/extension-strike/extension-underline/extension-code(行内标记)、extension-code-blockextension-horizontal-ruleextension-hard-breakextension-link,以及extension-dropcursor/extension-gapcursor(拖放与空位光标)等。也就是说,一个"基础编辑器"≈ 一个StarterKit

5.2 官方默认示例(React 版)

demos/src/Examples/Default/React/index.tsx 展示了标准用法:

import { EditorContent, useEditor } from '@tiptap/react' import StarterKit from '@tiptap/starter-kit' import { TextStyleKit } from '@tiptap/extension-text-style' const extensions = [TextStyleKit, StarterKit] export default () => { const editor = useEditor({ extensions, content: `<h2>Hi there,</h2><p>this is a <em>basic</em> example…</p>`, }) return ( <> <MenuBar editor={editor} /> <EditorContent editor={editor} /> </> ) }

要点:内容可以是 HTML 字符串;MenuBar是演示用的自绘工具栏(headless 的体现);同一示例在 demos/src/Examples/Default/Vue 中有 Vue 实现,在 demos/src/Examples/Default/Svelte 中有 Svelte 实现,可对比三种框架适配层的 API 差异(useEditor响应式 ref 等)。

纯 JS / 无框架场景下,直接使用@tiptap/corenew Editor({ element, extensions, content })element参数语义见前文EditorOptions表。

六、在本地运行 Tiptap 仓库

以下命令均基于根目录 package.json 的scripts定义(要求 Node >= 24、pnpm 11.2.2):

pnpm install # 安装 workspace 依赖(prepare 阶段会自动运行 vp config) pnpm dev # 启动 demos 应用(vp run start) pnpm build # 递归构建所有 packages(vp run -r build) pnpm test:unit # 运行单元测试(vp test) pnpm test:e2e # Playwright 端到端测试(chromium) pnpm lint # oxlint 静态检查

几个值得关注的工程化细节:

  • 新增 demo 脚手架:scripts/make-demo.sh 通过pnpm run make:demo运行,交互式询问 demo 名称与分类(Dev/Examples/Extensions/Experiments/Marks/Nodes),并从 demos/src/Examples/Default 模板复制目录(见 CONTRIBUTING.md "Create a new demo" 一节);
  • 发布流程:使用 Changesets 管理版本,pnpm run publish会先vp run build再执行changeset publish;CONTRIBUTING.md 中说明新包需要手动首发并配置 NPM trusted publishing(provenance)后才能被 CI 自动发布;
  • 测试分层packages/*/__tests__下是大量按功能命名的单测(如 packages/core/tests/setContent.spec.ts、packages/core/tests/insertContent.spec.ts、packages/core/tests/isActive.spec.ts),配合demos下的 Playwright e2e(配置见 playwright.config.ts)构成双保险。

七、协作编辑与 Tiptap Suite

README 专设 "Make your editor collaborative" 一节:协作能力由开源后端 Hocuspocus 提供,其核心是 Yjs CRDT;编辑器与 Hocuspocus 共同构成 Tiptap Suite 的基础。

在仓库中对应的实现有:

  • packages/extension-collaboration:把 Yjs 的Y.Doc与 ProseMirror 状态桥接(含 5 个源文件与 2 个测试文件);
  • packages/extension-collaboration-caret:远程用户光标渲染;
  • packages/extension-unique-id:协作场景下为节点补充唯一 ID(其__tests__中含 YDoc 相关用例,对应 demos/src/Extensions/UniqueIDWithYdoc 示例)。

README 同时提到Pro Extensions(商用订阅扩展),覆盖协作编辑、评论、版本管理、文档转换与 AI 相关功能;仓库中 packages/ai-toolkit 则代表了开源侧的 AI 工具能力(如streaming-reveal流式输出渐显,见 packages/ai-toolkit/src/streaming-reveal.ts 及其测试 packages/ai-toolkit/tests/streaming-reveal.spec.ts)。

八、社区、贡献规范与许可

  • 贡献指南:CONTRIBUTING.md 要求提交前运行测试与 linter、为包变更附带 Changeset、PR 关联已指派的 issue、AI 辅助生成内容须显式披露、30 天无响应会关闭 PR 等;
  • 安全:漏洞报告遵循 SECURITY.md;
  • 许可:项目采用 MIT 许可证,详见 LICENSE.md;
  • 社区:README 引导使用者通过 GitHub Discussions 进行讨论(具体入口以仓库页面的 Discussions 区为准)。

九、小结

Tiptap 的技术定位可以概括为:"ProseMirror 之上的声明式扩展层"。packages/core 提供Editor+Extension双核心与完整的事件/命令体系;packages/pm 屏蔽 ProseMirror 模块细节;extension-*包把每个功能单元化;demos 则证明同一 API 可以在 React、Vue 2/3、Svelte 与纯 JS 中互换运行。理解EditorOptions(packages/core/src/types.ts)与Extension.create / configure / extend(packages/core/src/Extension.ts)这两块,就掌握了在 Tiptap 生态中搭建、定制乃至贡献新扩展所需的全部核心知识。

【免费下载链接】tiptapThe headless rich text editor framework for web artisans.项目地址: https://gitcode.com/GitHub_Trending/ti/tiptap

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/6 20:21:09

基于PLC的工厂温湿度控制系统设计与调试全流程解析

简介&#xff1a;面向自动化、电气工程及相关专业学生与工程师&#xff0c;这份论文类资源围绕工厂环境温湿度控制场景&#xff0c;完整呈现了基于PLC的控制系统设计路径&#xff1a;从总体方案、组成与功能分析&#xff0c;到硬件选型与接线设计&#xff0c;再到PID算法参数整…

作者头像 李华
网站建设 2026/9/6 20:19:47

MATLAB实现GNN-LSTM混合模型:融合图卷积与灰色系统的时间序列预测

简介&#xff1a;面向具备MATLAB和深度学习基础的科研人员、工程师与数据科学家&#xff0c;这份GNN-LSTM时间序列预测项目文档将灰色系统理论与LSTM网络深度结合&#xff0c;聚焦金融、工业、能源、环境、交通、医疗等场景中小样本、不完整数据及复杂非线性预测难题&#xff0…

作者头像 李华
网站建设 2026/9/6 20:19:40

基于GNN-LSTM的MATLAB时间序列预测组合模型实战

简介&#xff1a;面向时间序列预测研究人员与MATLAB开发者&#xff0c;提供基于GNN-LSTM&#xff08;灰色神经网络结合长短期记忆网络&#xff09;融合模型的项目实现&#xff0c;旨在解决金融、工业、能源、交通等领域中小样本、不完整数据的复杂非线性预测问题。压缩包内含1个…

作者头像 李华
网站建设 2026/9/6 20:13:52

BIQS2.0进阶版教材V4.0:从符合性到有效性的质量体系升级指南

简介&#xff1a;面向汽车行业供应商质量管理的BIQS2.0进阶版教材V4.0&#xff08;上册&#xff09;&#xff0c;自上汽通用采购部供应商质量与开发团队编写&#xff0c;系统阐述质量模块推进目的与落地方法。相比旧版&#xff0c;其核心变化是引导供应商“知其然并知其所以然”…

作者头像 李华