Tiptap 编辑器扩展集成:3 步接入官方扩展,10 行代码写出自己的 Mark
【免费下载链接】tiptapThe headless rich text editor framework for web artisans.项目地址: https://gitcode.com/GitHub_Trending/ti/tiptap
当你想给页面加上加粗、标题和表格,却发现现成编辑器自带的 UI 样式根本改不动——Tiptap 就是为解决这个问题而生:一个 headless 富文本编辑器,它自己没有任何界面,所有能力都以扩展的形式独立注册,由你自己拼装。
Tiptap 扩展机制解决了什么问题
Tiptap 构建在 ProseMirror 之上,但它的核心(packages/core/)只负责管理文档状态和分发命令,加粗、标题、列表这些能力全部拆成packages/下的独立包,运行时由你注册。你可以把编辑器理解为一部空手机:核心只是手机本身,每个扩展都是一款单独安装的应用,装哪些、怎么用,完全由你决定。
最小可用示例:3 步跑通 Tiptap 编辑器
先在你自己的项目里安装两个包:@tiptap/core提供编辑器核心,@tiptap/starter-kit是官方扩展包,一次性带进加粗、斜体、标题、列表、撤销重做等 20 个最常用的扩展。
npm install @tiptap/core @tiptap/starter-kit接下来在入口脚本里初始化编辑器。下面这段代码的全部作用,就是把 StarterKit 注册进编辑器,并写入一行初始内容。
import { Editor } from '@tiptap/core' import StarterKit from '@tiptap/starter-kit' const editor = new Editor({ element: document.querySelector('#editor'), extensions: [StarterKit], content: '<p>开始写作</p>', })跑通后,页面上#editor对应的元素变成可编辑区域:选中文字按 Ctrl/Cmd+B 变粗,行尾敲**文字**也会自动转成加粗——这些行为全部来自刚注册的扩展,而不是编辑器内置的。
Tiptap 扩展机制拆解:读 3 处源码
注册链路:new Editor之后发生了什么
你在代码里写new Editor({ extensions: [StarterKit] }),实际触发的是packages/core/里的 ExtensionManager:它遍历每个扩展,依次收集addCommands、addKeyboardShortcuts、addProseMirrorPlugins等钩子的返回值,汇总生成 ProseMirror 的 schema、输入规则和键位表,最后挂载到编辑器上。所以"加功能"和"改配置"本质上是同一件事——注册一个带配置的对象。
扩展源码解剖:bold 的 5 个钩子
打开 packages/extension-bold/src/bold.tsx,你会发现一个 Mark 扩展由 5 处组成:parseHTML声明哪些 HTML(<strong>、<b>)解析为 bold;renderHTML负责反向输出;addCommands提供toggleBold命令;addKeyboardShortcuts绑定快捷键;addInputRules用正则匹配**文字**并转换成 bold mark。
addKeyboardShortcuts() { return { 'Mod-b': () => this.editor.commands.toggleBold(), } }这段就是你按 Ctrl+B 能加粗的直接原因——快捷键不是编辑器行为,而是扩展自己注册的。
按需裁剪:用 configure 关掉不想要的 StarterKit 功能
StarterKit 的addExtensions()逐个检查配置项:值为false就不注册对应扩展。想去掉链接,写一行StarterKit.configure({ link: false });想限制标题只留 1-3 级,写heading: { levels: [1, 2, 3] }。不需要手动拆包,也不用重写整个扩展列表。
动手做:4 步写出 Tiptap 高亮扩展
目标:官方扩展里没有文本高亮,自己做一个——选中文字点按钮变黄色,导出 HTML 时保留<mark>标签。
第 1 步,在项目里新建highlight.ts,用Mark.create声明扩展,注册对mark标签的解析和渲染规则。第 2 步,在addCommands里加一个setHighlight命令,供按钮调用。第 3 步,把扩展和 StarterKit 一起注册进编辑器,并补一条mark { background: #ffeb3b }的 CSS。第 4 步,按钮的点击事件里调用editor.commands.setHighlight()。
import { Mark } from '@tiptap/core' // 步骤 1:定义高亮 Mark,解析并渲染 mark 标签 export const Highlight = Mark.create({ name: 'highlight', parseHTML: () => [{ tag: 'mark' }], renderHTML: ({ HTMLAttributes }) => ['mark', HTMLAttributes, 0], // 步骤 2:暴露命令供工具栏按钮调用 addCommands() { return { setHighlight: () => ({ commands }) => commands.setMark(this.name), } }, }) // 步骤 3:与 StarterKit 一起注册,并加上高亮样式 const editor = new Editor({ element: document.querySelector('#editor'), extensions: [StarterKit, Highlight], content: '<p>选中我试试高亮</p>', }) // 步骤 4:按钮触发命令 document.querySelector('#hl').onclick = () => editor.commands.setHighlight()跑起来后选中几个字点按钮,文字变黄;再调editor.getHTML(),输出里能拿到<mark>选中我</mark>,说明解析和渲染两个方向都通了。
Tiptap 扩展高频报错快速定位
现象:Color 扩展设置了颜色,DOM 里却没有任何样式变化。原因:Color 只是往 TextStyle mark 上写 color 属性,没注册 TextStyle 时 mark 无处挂载。解决:在
extensions里补上 TextStyle,完整写法见 demos/src/Extensions/Color/。现象:Mod+B 不触发加粗,但直接调
editor.commands.toggleBold()有效。原因:快捷键由各扩展的addKeyboardShortcuts注册,你手动拼 Document/Paragraph/Text 时漏了 Bold。解决:把 Bold 加进 extensions,或在自己的键位映射里手动绑定 toggleBold。现象:clone 官方仓库后
pnpm dev报 engine 版本错误。原因:根package.json声明了node >=24,你本机 Node 版本偏低。解决:升级到 Node 24 再启动,例如nvm install 24 && nvm use 24。
读完之后做什么
- 逐个浏览 demos/src/Extensions/:每个目录都是官方扩展的可运行演示,从
Color和TableOfContents看起,对照源码理解每个钩子。 - 精读 packages/core/src/Extension.ts 和
Mark.ts,再回头重读 bold 扩展,把"5 个钩子"从记忆变成条件反射。 - 打开
packages/extension-bold/__tests__/里的单测,参考它的断言方式,给你自己刚写的高亮扩展补上测试。
如果你写出的扩展对别人也有用,欢迎带到官方社区讨论。
【免费下载链接】tiptapThe headless rich text editor framework for web artisans.项目地址: https://gitcode.com/GitHub_Trending/ti/tiptap
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考