Tiptap 3 列表扩展整合迁移指南:ListKeymap 与 ListKit 的统一时代

发布时间:2026/9/10 14:11:27
Tiptap 3 列表扩展整合迁移指南:ListKeymap 与 ListKit 的统一时代 Tiptap 3 列表扩展整合迁移指南ListKeymap 与 ListKit 的统一时代【免费下载链接】tiptapThe headless rich text editor framework for web artisans.项目地址: https://gitcode.com/GitHub_Trending/ti/tiptapTiptap 在 3.x 大版本中把所有列表相关扩展统一收编进tiptap/extension-list并提供了ListKit一键组合入口。本指南基于packages-deprecated/extension-list-keymap的变更记录梳理这次 repackaging 的来龙去脉从卸载旧包、改 import、用ListKit集中配置到理解新版ListKeymap的键盘绑定原理帮助你一次性完成列表功能的无痛迁移。一次大打包ListKeymap 为何走入 extension-list-keymap 的历史在 Tiptap 2.x 时代列表功能被拆成一组独立的 npm 包tiptap/extension-ordered-list、tiptap/extension-bullet-list、tiptap/extension-list-keymap、tiptap/extension-list-item、tiptap/extension-task-list、tiptap/extension-task-item。这种细粒度拆分虽然灵活但也带来了依赖管理、版本同步上的成本。packages-deprecated/extension-list-keymap/CHANGELOG.md中3.0.1的Major Changes明确记录了这一次转折This adds all of the list packages to thetiptap/extension-listpackage.变更号2c911d2。也就是说从 3.0.0 起上面所有列表扩展的源码全部合并进统一的tiptap/extension-list包而原有的独立包被标记为 deprecated。从当前仓库结构可以直观印证这一点原包packages-deprecated/extension-list-keymap/已被移入packages-deprecated/目录其 src/index.ts 只剩下一层转发import { ListKeymap } from tiptap/extension-list export type { ListKeymapOptions } from tiptap/extension-list export { listHelpers, ListKeymap } from tiptap/extension-list export default ListKeymap新包packages/extension-list/下按目录拆分管理了 bullet-list、item、ordered-list、task-item、task-list、keymap 与 kit 模块。同时packages-deprecated/extension-list-keymap/package.json显示旧包已经不再依赖tiptap/core而是以tiptap/extension-listworkspace:*为唯一的 peer dependency——这从依赖层面再次确认了功能已整体移交的事实。核心新 API用 ListKit 一次注册全部列表扩展合并之后官方推荐的首选用法不再是逐个安装列表扩展而是引入ListKit。CHANGELOG 中给出的核心配置示例如下import { ListKit } from tiptap/extension-list; new Editor({ extensions: [ ListKit.configure({ bulletList: { HTMLAttributes: bullet-list, }, orderedList: { HTMLAttributes: ordered-list, }, listItem: { HTMLAttributes: list-item, }, taskList: { HTMLAttributes: task-list, }, taskItem: { HTMLAttributes: task-item, }, listKeymap: {}, }), ], });注意CHANGELOG 示例中HTMLAttributes使用了简写字符串按 Tiptap 约定该配置项实际接收一个 HTML 属性对象例如{ class: bullet-list }接入自己项目时请以类型提示为准。对应实现位于 packages/extension-list/src/kit/index.ts。ListKit本身是Extension.createListKitOptions通过addExtensions()把所有子扩展组合起来export interface ListKitOptions { bulletList: PartialBulletListOptions | false listItem: PartialListItemOptions | false listKeymap: PartialListKeymapOptions | false orderedList: PartialOrderedListOptions | false taskItem: PartialTaskItemOptions | false taskList: PartialTaskListOptions | false }从源码可以看出三个关键设计每个子扩展都是一个配置键bulletList、orderedList、listItem、taskList、taskItem、listKeymap一一对应。传入Partial…Options即代表注册该扩展并应用这段配置在 kit/index.ts 中会执行BulletList.configure(this.options.bulletList)等调用。传入false即代表不注册该扩展。例如你不需要任务列表可以直接写ListKit.configure({ taskList: false, taskItem: false })实现更精细的组合控制。想要分开使用六个扩展的独立导出依然保留CHANGELOG 在介绍完ListKit后专门强调Want to use the extensions separately? For more control, you can also use the extensions separately.每个扩展都从tiptap/extension-list命名导出。汇总如下表原独立包新包统一导出功能说明tiptap/extension-bullet-listBulletList无序列表tiptap/extension-ordered-listOrderedList有序列表tiptap/extension-list-itemListItem列表项tiptap/extension-task-listTaskList任务列表容器tiptap/extension-task-itemTaskItem任务项tiptap/extension-list-keymapListKeymap更完善的列表键盘绑定这些导出统一聚合在 packages/extension-list/src/index.ts并通过export * from ./keymap/index.js等把全部子模块转发出去。迁移操作步骤第一步卸载旧的独立列表包如果项目里安装过以下任何一个旧包先卸载CHANGELOG 原文命令npm uninstall tiptap/extension-ordered-list tiptap/extension-bullet-list tiptap/extension-list-keymap tiptap/extension-list-item tiptap/extension-task-list第二步安装整合后的新包npm install tiptap/extension-list第三步逐个修改 import 语句CHANGELOG 为每个扩展都提供了标准迁移 diff。以ListKeymap为例- import ListKeymap from tiptap/extension-list-keymap import { ListKeymap } from tiptap/extension-list其余扩展同理仅命名不同迁移规则完全一致- import BulletList from tiptap/extension-bullet-list import { BulletList } from tiptap/extension-list- import OrderedList from tiptap/extension-ordered-list import { OrderedList } from tiptap/extension-list- import ListItem from tiptap/extension-list-item import { ListItem } from tiptap/extension-list- import TaskList from tiptap/extension-task-list import { TaskList } from tiptap/extension-list- import TaskItem from tiptap/extension-task-item import { TaskItem } from tiptap/extension-list迁移后所有列表扩展共享同一个版本号如当前仓库锁定的3.30.3彻底避免了六个包、六个版本、六个发布节奏的同步问题。新 ListKeymap 做了什么源码级拆解迁移背后ListKeymap的实现也一并进入了新包。它解决了什么痛点packages/extension-list/src/keymap/list-keymap.ts 的注释说得很清楚ProseMirror 默认的键盘处理在按 Backspace / Delete 时总是倾向 lift提升或 sink下沉列表项导致两个列表项的段落被错误合并ListKeymap的职责是拦截这些按键改为把两个列表项中的段落合并进同一个列表项这一更符合编辑器直觉的行为。可配置项 listTypesListKeymapOptions只有一项配置listTypes它声明了哪些节点是列表项、各自包裹在哪些外层列表里export type ListKeymapOptions { listTypes: Array{ itemName: string wrapperNames: string[] } }默认值覆盖了内置的两组列表见 list-keymap.tslistTypes: [ { itemName: listItem, wrapperNames: [bulletList, orderedList] }, { itemName: taskItem, wrapperNames: [taskList] }, ],如果你在自定义列表节点可以通过ListKeymap.configure({ listTypes: [...] })把它接入同样的键盘行为。五个按键处理器通过addKeyboardShortcuts()list-keymap.tsListKeymap注册了以下快捷键快捷键处理器说明DeletehandleDelete删除键处理列表项衔接处的文本删除Mod-DeletehandleDelete按词删除Ctrl/Cmd DeleteBackspacehandleBackspace退格键优先拦截列表末尾紧跟普通段落的情况Mod-BackspacehandleBackspace按词退格Ctrl/Cmd BackspaceTabhandleTab把列表项之后的段落并入前一个列表项避免重复下沉代码中每个列表类型都会被遍历只有对应节点确实存在于 schemaeditor.state.schema.nodes[itemName] undefined则跳过时才尝试处理。值得注意的细节是Tab的处理与其他键不同它使用了for...of并在第一个成功处理处return true保证嵌套了任务列表等复合结构时一次 Tab 只会下沉一次。处理器与测试的印证handleTabhandleTab.ts只在光标位于空选区、位于块首、且前一个兄弟块是列表项时才触发随后通过一次事务deleteinsert把当前块搬进前一个列表项尾部并重新设置光标TextSelection.create。源码还特别注释gap cursor 会通过前置校验但解析位置不在 textblock 内需单独排除。handleBackspacehandleBackspace.ts处理顺序非常考究——先让undoInputRule有机会处理保留输入规则的撤销语义若当前光标不在列表项内但前面有列表则把当前段落cut进最后一个列表项并joinForward若光标已位于列表项首个子块的开头则退化为liftListItem(name)把项提升出去。这些边界行为都有对应测试守护例如 listKeymapTab.spec.ts 验证了gap cursor 处按 Tab 应不生效在列表项内再嵌套taskList的复合场景中Tab 将普通段落并入列表项后不会再次下沉进taskItem。工程与构建层面的注意事项除了功能合并CHANGELOG 的3.0.1与3.0.0-next.6变更记录还揭示了几个工程事实迁移时值得留意构建工具切换为 tsup不再产出 UMD变更号a92f4a6说明——We are now building packages with tsup which does not support UMD builds, please repackage if you require UMD builds.如果你依赖 CDN 直接引入的 UMD 产物需要自行重新打包。Monorepo 版本锁定改用 pnpm alias1b4c82b新版仓库通过 pnpm workspace alias 做精确版本固定避免依赖解析冲突。强制类型导入89bd9c7构建 dist 的index.js时会忽略纯类型导入进一步减小产物体积。3.22.4的补丁27ea931专门修复了包更新后产生 peer dependency 解析冲突的问题——这也是合并到单包后显著缓解的一类痛点。顺带一提如果你在自己的业务代码中仍然引用了tiptap/extension-list-keymap请切换到tiptap/extension-list仓库中该 deprecated 包的作用已退化为纯转发层不应作为新项目的直接依赖。小结一条清晰的升级路线梳理 CHANGELOG 中的版本脉络2.5.x时代依赖tiptap/core→3.0.0-next.x与 beta 系列引入 repackaging →3.0.1起稳定合并 →3.30.3当前基线可以总结出这套迁移心法用tiptap/extension-list一个包替代全部旧列表包首选ListKit组合注册需要精细控制时再用六个命名导出BulletList/OrderedList/ListItem/TaskList/TaskItem/ListKeymap每个子扩展既可作为ListKit.configure({ ... })的键也可传false显式关闭若需自定义列表键盘行为通过ListKeymap的listTypes配置向 Backspace / Delete / Tab 系列快捷键注册你的列表节点。对于正在从 Tiptap 2.x 升级或清理旧依赖的开发者而言这套统一包 ListKit 聚合 按需独立导出的结构既是迁移的目标形态也是后续扩展自定义列表行为的起点。【免费下载链接】tiptapThe headless rich text editor framework for web artisans.项目地址: https://gitcode.com/GitHub_Trending/ti/tiptap创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询