首页
/ Quill 版本演进全解析:从 CHANGELOG 看 2.0 的 ESM 改造、滚动容器自动探测与剪贴板重构

Quill 版本演进全解析:从 CHANGELOG 看 2.0 的 ESM 改造、滚动容器自动探测与剪贴板重构

2026-09-05 11:40:28作者:何将鹤

本文基于 Quill 仓库根目录下的 CHANGELOG.md,完整梳理 Quill 从 2016 年 1.0.0-beta 到 2024 年 2.0.2 的全部版本发布脉络。读完本文,你将掌握 Quill 2.0 各核心改进(ESM 包结构、嵌套编辑器、IME 合成修复、TEXT_CHANGE 语义清理、History 记录选区、滚动容器自动探测、Google Docs/Word 粘贴增强)在仓库源码中的对应实现位置,以及每个候选版(RC)与 1.x 系列补丁版实际修复的问题清单,从而在升级依赖或排查历史缺陷时能快速定位到对应版本。

一、版本总览:CHANGELOG 的时间线结构

仓库中的 CHANGELOG.md 按时间倒序记录了所有正式发布,覆盖四个阶段:

阶段 版本区间 时间跨度 特征
2.0 正式发布 v2.0.0 ~ v2.0.2 2024-04-17 ~ 2024-05-13 大版本重写后的稳定版
2.0 候选/公测 v2.0.0-beta.0 ~ rc.5 2023-12-08 ~ 2024-04-04 高频迭代,含多处破坏性调整
1.x 成熟维护 v1.0.0 ~ v1.3.7 2016-09-06 ~ 2019-09-09 长期稳定维护线
1.0 候选/公测 v1.0.0-beta.0 ~ rc.4 2016-05-04 ~ 2016-08-31 周更预览版,大量 Breaking Changes

需要注意一个细节:CHANGELOG 记录到的最新正式版本是 v2.0.2(2024-05-13),而 packages/quill/package.json 中的 version 字段已经是 2.0.3,说明当前工作区源码对应的是 2.0.2 之后的开发快照,CHANGELOG 尚未追加该版本的条目。此外,2.0.2 的条目注明"Release notes generated using configuration in .github/release.yml",即发布说明开始由发布配置自动生成,而 2.0.1 及更早版本仍为手工撰写。

二、v2.0.2 与 v2.0.1:稳定版的类型与事件修正

v2.0.2(2024-05-13)Bug Fixes

CHANGELOG 列出四项修复(对应 PR #4127、#4200、#4201、#4202):

  • 修复 Quill.register 的类型定义错误;
  • 修复通过快捷键删除链接时事件 source 不正确的问题;
  • 避免 Safari 中处于输入法合成(composing)状态时 Enter/Backspace 产生副作用;
  • 当 image 格式被禁用时,忽略粘贴进来的图片。

最后一条与 2.0 新引入的 formats 配置项直接相关:在 packages/quill/src/core/quill.ts 中,QuillOptions.formats 的文档注释明确"null means all formats are allowed",即默认允许所有格式;一旦传入受限列表,剪贴板路径也会遵循该白名单——这正是 v2.0.2 "Ignore pasting images when image format is disallowed" 所补上的边界。

v2.0.1(2024-05-01)

  • 防止主题默认工具栏配置被意外覆盖(#4120);
  • 改进返回 Delta 的方法的类型定义(#4136);
  • 修复工具栏中 h3-h6 的图标(#4131)。

三、v2.0.0(2024-04-17):2.0 正式版的四大主题

CHANGELOG 将 2.0.0 的变更归纳为 Major Improvements、Performance Improvements、Code Modernization 三类,下面逐一展开,并给出仓库中的源码佐证。

3.1 ESM:Quill 成为合法的 ESM 包

2.0 的首要变化是"Quill is now a valid ESM package for better ecosystem (e.g. bundlers) and tree-shaking support"。在 packages/quill/package.json 中可以看到配套事实:包声明了 "type": "module",入口 main 指向 quill.js;依赖中同时存在 lodash-es(ESM 版 lodash)与 parchment ^3.0.0quill-delta ^5.1.0eventemitter3。而 v2.0.0-rc.2 条目中专门记录了 "Improve compatibility with esbuild",说明 ESM 化过程中对主流打包器(webpack、esbuild 等)的兼容是持续打磨的重点。

3.2 自动探测滚动容器

"Auto detect scrolling container"(#3840)解决了此前必须手动指定 scrollingContainer 的痛点。仓库中对应实现是 packages/quill/src/core/utils/scrollRectIntoView.ts

  • 该函数从编辑器根节点 root 出发,沿 parentElement(以及 Shadow DOM 的 getRootNode().host)逐级向上遍历,直到 document.bodyposition: fixed 的祖先为止(见 scrollRectIntoView.ts);
  • 对每一级祖先按 CSSOM View 规范中 element.scrollnearest 语义计算滚动距离(getScrollDistance),并读取 scroll-padding-* 计算样式参与边界计算;
  • 到达 document.body 时使用 window.visualViewport 的尺寸作为视口边界,兼容移动端动态地址栏。

对外暴露方式见 packages/quill/src/core/quill.tsscrollRectIntoView(rect, options) 是底层方法,scrollSelectionIntoView(options) 在其上封装为"把当前选区滚入可见区域";旧 API scrollIntoView() 被标记为 @deprecated 并会打印警告。调用侧如 setSelection 在非 SILENT 来源时会自动触发 scrollSelectionIntoView()quill.ts)。

3.3 History 模块记录选区

"Record selection in history module"(#3823)意味着撤销/重做不再只还原文本与格式,还恢复光标位置。源码佐证:packages/quill/src/modules/history.ts 直接 import type { Range } from '../core/selection.js',其中 Range 类(index + length)定义在 packages/quill/src/core/selection.ts,并在 v2.0.0-rc.5 中被作为公开类型暴露("Expose Range type")。

3.4 Clipboard:对 Google Docs 与 Word 的粘贴增强

2.0.0 条目中"Clipboard: Improve support for pasting from Google Docs and Microsoft Word"在仓库中有独立目录佐证:packages/quill/src/modules/normalizeExternalHTML/ 下按来源拆分为 normalizers/googleDocs.tsnormalizers/msWord.ts 两个归一化器,packages/quill/src/modules/clipboard.ts 在将外部内容转换为 Delta 时调用它们。配套的测试位于 test/unit/modules/normalizeExternalHTML/normalizers/googleDocs.spec.tsmsWord.spec.ts)。这条线在 RC 阶段已有铺垫:v2.0.0-rc.0 记录了 "Improve support for pasting from Google Docs and Microsoft Word"、"Fix redundant newlines when pasting from external sources"、"Convert newlines between inline elements to a space" 等连续改进。

3.5 其余重大改进

3.6 性能改进

CHANGELOG 强调 2.0 "包含许多性能优化,其中最重要的是大内容渲染速度的提升",并列出三项(#3815、#3538、#3539):

  • 提升插入性能;
  • 在可能时避免获取选区(avoid fetching selections);
  • 容器为空时无需走 setContents

最后一点在源码中容易印证:构造路径对空容器有专门处理,而 setContents 本身实现为"deleteText(0, length) + insertContents + 删除末尾多余换行"的三步合成,空容器场景省去这套全量删除再插入的往返正是优化所在。

3.7 代码现代化

四、2.0 候选版时间线:从 beta.0 到 rc.5

2.0 的预览阶段从 2023-12-08 的 beta.0 持续到 2024-04-04 的 rc.5,每个版本都带有明确的修复清单,升级 2.0 前值得逐条对照:

  • v2.0.0-beta.0(2023-12-08):首个 2.0 预览版。CHANGELOG 原文称"Quill has been significantly modernized. Leveraging the latest browser-supported APIs",并列出了与正式版相同的核心清单(嵌套 Quill、IME、TEXT_CHANGE 语义清理、History 记录选区、自动探测滚动容器)以及三项性能优化和代码现代化五项内容;
  • v2.0.0-beta.1(2024-01-21):修复 syntax 模块语言标签 "Javascript" → "JavaScript";修复 emitter 类型错误;内联 SVG 图标以简化打包器配置(对应仓库中 packages/quill/scripts/babel-svg-inline-import.cjssrc/assets/icons/ 下 60 余个 SVG 图标);改进 Registry 类型;
  • v2.0.0-beta.2(2024-01-30):修复 Safari 中 IME 不工作;Clipboard 支持以纯文本粘贴;修复 Quill.getText() 不尊重 length 参数(该方法实现见 packages/quill/src/core/editor.ts);修复 Linux/Windows 上 redo 快捷键无效
  • v2.0.0-rc.0(2024-02-03):Clipboard 四项改进(行内元素间换行转空格、粘贴时避免生成不支持的格式、外部来源冗余换行、空段落间空白忽略);Syntax 模块同时支持 highlight.js v10 与 v11(对照 packages/quill/src/modules/syntax.ts);
  • v2.0.0-rc.1(2024-02-12):移除不必要的 lodash 用法;
  • v2.0.0-rc.2(2024-02-15):修复工具栏按钮状态在某些场景下不更新;收窄 BubbleTheme.tooltip 类型;修复 Selection#getBounds() 在范围起点位于文本节点末尾时的行为(getBounds 实现于 packages/quill/src/core/selection.tsBounds 接口即其导出类型之一);改进 esbuild 兼容性;
  • v2.0.0-rc.3(2024-03-16):修复 Quill#getSemanticHTML() 对列表项的产出(该方法重载声明见 quill.ts);移除不必要的 Firefox 兼容处理;Clipboard 修复外部粘贴的冗余换行;新增 formats 配置项用于限定编辑器允许的格式。该配置的实现链路是:quill.tsQuillOptions.formats 定义 → 构造时经 createRegistryWithFormats 生成受限注册表 → packages/quill/src/core/utils/createRegistryWithFormats.ts 中先注册 block/break/cursor/inline/scroll/text 六个核心 blot,再按格式名递归注册其 requiredContainer 链(上限 100 次迭代防环),未注册的格式名会打印 Cannot register ... specified in "formats" config 错误;
  • v2.0.0-rc.4(2024-03-24):为 Parchment 附带 source maps;Clipboard 支持粘贴 iOS 分享面板复制的链接;修复配置解析中 undefined 值被保留的问题;暴露 Quill options 类型;移除打包器生成的空 .css.js 文件;
  • v2.0.0-rc.5(2024-04-04):Clipboard 增加对 Quill v1 列表属性的支持(利于从 1.x 迁移内容);修复 quill.formatText() 等方法的函数重载声明;为 getBounds() 暴露 Bounds 类型、公开 Range 类型;允许 insertBeforerefnull

五、1.x 成熟维护线(v1.0.0 ~ v1.3.7)

1.x 是 Quill 使用最广泛的版本线,CHANGELOG 中保留了完整记录。按时间倒序梳理关键版本:

  • v1.3.7(2019-09-09):安全相关修复,涉及 extend 依赖漏洞与 npm 公告 1039(原型污染类问题);这是 1.x 的终点版本;
  • v1.3.6(2018-03-12):Picker 可访问性改进;修复 Chrome 65 中日语合成问题;
  • v1.3.5(2018-01-22):修复勾选复选清单项的缩进保持;修复粘贴 text-align 样式;修复 dangerouslyPasteHTML 后光标位置;修复 text-change 回调中 history 栈值错误;增加 Webkit 图像导航死锁的 workaround;
  • v1.3.4 / v1.3.3:放宽依赖与列表自动填充约束;修复无参数 getFormat;移除跨 embed 的自动高亮;移动端勾选 checklist;KaTeX 渲染错误可视化;
  • v1.3.0(2017-07-17):Clipboard 新增 matchVisual 配置;修复 select 元素选中项判定、RTL 列表布局、预格式化中文合成等十余项问题;
  • v1.2.6 ~ v1.2.1:默认禁用 Grammarly 集成;移动端 YouTube 链接;Korean 合成修复(Safari);Windows/Ubuntu 下 Backspace/Delete 修复;
  • v1.2.0(2017-01-21):引入 experimental API 概念——findgetIndexgetLeafgetLinegetLines,并声明其不受语义化版本(SemVer)保护;
  • v1.1.6(2016-12-06):API 层加入 Checklist 支持(UI 随后补全);修复 readOnly 模式下仍可编辑的漏洞;修复大段粘贴导致的最大调用栈溢出;
  • v1.1.1(2016-10-21):TEXT_CHANGE 事件改用光标位置报告变更点;
  • v1.1.0(2016-10-17):引入 strict 配置项(默认 true)。CHANGELOG 用整段文字解释了背景:API 调用一直带有 source 参数表示来源,"user" 来源在 readOnly 编辑器中此前并不被拦截(#909),若直接修复按 SemVer 属于破坏性变更,因此以非破坏性的 strict 开关交付新行为;
  • v1.0.6 ~ v1.0.2:文档澄清与构建修复;
  • v1.0.0(2016-09-06):1.0 正式版发布。

六、1.0 候选/公测期(2016-05 ~ 2016-08):值得留档的破坏性变更

1.0 预览期采用周更节奏,CHANGELOG 为每个 beta 单独列出 Breaking Changes。这些变更定义了 Quill 1.x 的诸多 API 形态,升级自 0.x 时需特别注意:

  • beta.0:指向 "Upgrading to 1.0" 指南,对应仓库文档 packages/website/content/docs/upgrading-to-2-0.mdx 的前身(1.0 升级指南);
  • beta.2:code highlighter 模块更名为 syntax;Clipboard matcher 配置改为追加而非替换默认 matcher;视频嵌入由 <video> 改为 <iframe> 以支持 YouTube/Vimeo 链接;键盘绑定引入上下文监听;
  • beta.3:键盘模块修正 metaKey 语义并新增跨平台修饰键 shortKey(Mac 为 metaKey,Windows/Linux 为 ctrlKey);Formula 因依赖 KaTeX 改为独立模块;
  • beta.4:Header 不再生成 id 属性;Windows 增加 Ctrl+Y 重做;BlockEmbed 改为长度 1,在 Delta 中与行内 embed 一致表示(value() 不再附带换行符,格式属性挂到对象本身而非换行符);
  • beta.5 ~ beta.6:新增 blur();修复公式编辑、跨列表删除、placeholder、格式丢失等;
  • beta.8:图片插入交互重构——移除 image-tooltip,改为点击工具栏图标直接打开系统文件选择器并转 base64,为远程上传预留钩子(这一交互在 2.0 中进一步由 packages/quill/src/modules/uploader.ts 承接);code block 由每行一个 <pre> 合并为单个 <pre>
  • beta.9ui/link-tooltip 不再通过 import 暴露(Snow 专属实现);ui/tooltip 大幅重构;Syntax 模块改为自动检测语言而非默认 JavaScript;Formula 与视频插入 UI 进入 Snow/Bubble 主题;
  • beta.10:Keyboard 绑定的初始配置格式变更(addBinding 重载保持向后兼容);
  • rc.0 ~ rc.4:最小样式表更名 quill.core.css;undo/redo 一致性修复(#889);列表方向交互修复等。

七、从 CHANGELOG 提炼的升级检查清单

结合以上记录,给需要维护或升级 Quill 的开发者三条可操作的结论:

  1. 从 1.x 升到 2.0:优先核对三件事——Clipboard 白名单(2.0 的 formats 配置 + 2.0.2 对禁用 image 时粘贴的拦截)、History 行为(2.0 起撤销/重做会连带恢复选区,依赖旧行为的代码需调整)、滚动行为(scrollingContainer 手动配置的容器若不再匹配,将走 2.0 的祖先链自动探测逻辑,见 scrollRectIntoView.ts);
  2. 排查具体缺陷:CHANGELOG 每条记录都带有 PR/Issue 编号,可据此在仓库中反查对应提交与测试。例如 Safari 合成态 Enter/Backspace 副作用对应 2.0.2 条目,其防护逻辑可在 packages/quill/src/core/composition.tskeyboard.ts 中验证;E2E 层有 test/e2e/fixtures/Composition.tstest/e2e/replaceSelection.spec.ts 等用例覆盖;
  3. 版本语义:1.2.0 起 Quill 明确区分实验 API(不受 SemVer 保护)与稳定 API,1.1.0 的 strict 案例则展示了项目"宁可加开关也不悄悄改默认行为"的兼容策略——升级时遇到行为差异,先查 CHANGELOG 中对应版本的说明,多数差异都有明确的来源标记。

八、结语

CHANGELOG.md 记录了 Quill 约八年的发布史:1.0 预览期的激进重构、1.x 长期维护期的精细修复,到 2.0 以 TypeScript 全面重写并补齐 ESM、嵌套编辑器与外部粘贴归一化。仓库当前的源码结构(packages/quill/src/corepackages/quill/src/modulespackages/quill/src/themes)与 CHANGELOG 中各版本条目一一对应,是定位"某个能力从哪个版本引入、在何处实现"的可靠索引。

登录后查看全文
热门项目推荐
相关项目推荐