Quill 版本演进全解析:从 CHANGELOG 看 2.0 的 ESM 改造、滚动容器自动探测与剪贴板重构
本文基于 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.0、quill-delta ^5.1.0、eventemitter3。而 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.body或position: fixed的祖先为止(见 scrollRectIntoView.ts); - 对每一级祖先按 CSSOM View 规范中
element.scroll的nearest语义计算滚动距离(getScrollDistance),并读取scroll-padding-*计算样式参与边界计算; - 到达
document.body时使用window.visualViewport的尺寸作为视口边界,兼容移动端动态地址栏。
对外暴露方式见 packages/quill/src/core/quill.ts:scrollRectIntoView(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.ts 与 normalizers/msWord.ts 两个归一化器,packages/quill/src/modules/clipboard.ts 在将外部内容转换为 Delta 时调用它们。配套的测试位于 test/unit/modules/normalizeExternalHTML/normalizers/(googleDocs.spec.ts、msWord.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 其余重大改进
- 嵌套 Quill(#3590):允许在一个 Quill 实例内部再嵌入另一个实例,
Quill.find(node)静态方法结合 packages/quill/src/core/instances.ts 的实例注册表可以按 DOM 节点找到对应实例(见 quill.ts); - 改进 IME 与拼写检查器支持(#3807):合成态处理集中在 packages/quill/src/core/composition.ts 与 selection 的
composing标志; - TEXT_CHANGE 事件的语义清理(#3778):事件发射语义收敛在 packages/quill/src/core/emitter.ts 与各
modify调用路径中。
3.6 性能改进
CHANGELOG 强调 2.0 "包含许多性能优化,其中最重要的是大内容渲染速度的提升",并列出三项(#3815、#3538、#3539):
- 提升插入性能;
- 在可能时避免获取选区(avoid fetching selections);
- 容器为空时无需走
setContents。
最后一点在源码中容易印证:构造路径对空容器有专门处理,而 setContents 本身实现为"deleteText(0, length) + insertContents + 删除末尾多余换行"的三步合成,空容器场景省去这套全量删除再插入的往返正是优化所在。
3.7 代码现代化
- 迁移到 TypeScript,并提供官方类型声明——对应 packages/quill/src 全量
.ts源码,入口为 packages/quill/src/core.ts 与 packages/quill/src/quill.ts; - 单元测试迁移到 Vitest:packages/quill/package.json 的
test:unit脚本为vitest --config test/unit/vitest.config.ts,另有test:fuzz(test/fuzz/vitest.config.ts); - E2E 测试迁移到 Playwright:
test:e2e脚本为playwright test,配置在 packages/quill/playwright.config.ts,用例见test/e2e/(如 test/e2e/full.spec.ts); - 官网迁移:CHANGELOG 写作 "Migrated website to Gatsby",而当前仓库
packages/website已采用 Next.js 结构(存在next.config.mjs),可以推断官网在后来的维护中又经历了框架更换。
四、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.cjs 与
src/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.ts,Bounds接口即其导出类型之一);改进 esbuild 兼容性; - v2.0.0-rc.3(2024-03-16):修复
Quill#getSemanticHTML()对列表项的产出(该方法重载声明见 quill.ts);移除不必要的 Firefox 兼容处理;Clipboard 修复外部粘贴的冗余换行;新增formats配置项用于限定编辑器允许的格式。该配置的实现链路是:quill.ts 中QuillOptions.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类型;允许insertBefore的ref为null。
五、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 概念——
find、getIndex、getLeaf、getLine、getLines,并声明其不受语义化版本(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.9:
ui/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.x 升到 2.0:优先核对三件事——Clipboard 白名单(2.0 的
formats配置 + 2.0.2 对禁用 image 时粘贴的拦截)、History 行为(2.0 起撤销/重做会连带恢复选区,依赖旧行为的代码需调整)、滚动行为(scrollingContainer手动配置的容器若不再匹配,将走 2.0 的祖先链自动探测逻辑,见 scrollRectIntoView.ts); - 排查具体缺陷:CHANGELOG 每条记录都带有 PR/Issue 编号,可据此在仓库中反查对应提交与测试。例如 Safari 合成态 Enter/Backspace 副作用对应 2.0.2 条目,其防护逻辑可在 packages/quill/src/core/composition.ts 与 keyboard.ts 中验证;E2E 层有 test/e2e/fixtures/Composition.ts 与 test/e2e/replaceSelection.spec.ts 等用例覆盖;
- 版本语义: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/core、packages/quill/src/modules、packages/quill/src/themes)与 CHANGELOG 中各版本条目一一对应,是定位"某个能力从哪个版本引入、在何处实现"的可靠索引。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00