Doramagic 项目包 · 项目说明书
ckeditor5 项目
功能强大的富文本编辑器框架,采用模块化架构,支持现代集成,并提供协作编辑等特性。
Project Overview and Getting Started
CKEditor 5 是一个现代化的 JavaScript 富文本编辑器,采用 MVC 架构、自定义数据模型和虚拟 DOM,从零开始使用 TypeScript 编写,对现代打包工具(如 Vite、Webpack)具有出色的支持。它提供了从类似 Google Docs / Medium 的协作文档编辑,到 Slack / Twitter 这类消息式应用所需要的全部 WYSIW...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
项目概述
CKEditor 5 是一个现代化的 JavaScript 富文本编辑器,采用 MVC 架构、自定义数据模型和虚拟 DOM,从零开始使用 TypeScript 编写,对现代打包工具(如 Vite、Webpack)具有出色的支持。它提供了从类似 Google Docs / Medium 的协作文档编辑,到 Slack / Twitter 这类消息式应用所需要的全部 WYSIWYG 编辑能力。
CKEditor 5 is a modern JavaScript rich-text editor with MVC architecture, custom data model, and virtual DOM, written from scratch in TypeScript with excellent support for modern bundlers.
资料来源:README.md
仓库本身以 monorepo 形式组织,多个包协同构建出编辑框架,再由各个特性包基于此框架实现具体功能。截至当前版本 48.2.0,整体项目仍处于积极迭代状态,并提供官方 LTS 通道:
| 项目元数据 | 取值 | 来源 |
|---|---|---|
| 当前版本 | 48.2.0 | package.json / packages/ckeditor5/package.json |
| 主包名(聚合发布) | ckeditor5 | packages/ckeditor5/package.json |
| 功能包命名空间 | @ckeditor/ckeditor5-* | packages/ckeditor5-markdown-gfm/package.json 等 |
| 模块系统 | ES Modules ("type": "module") | packages/ckeditor5/package.json |
| 开发运行时 | Node >=24.11.0,pnpm >=10.28.0 | 根 package.json |
资料来源:package.json、packages/ckeditor5/package.json、packages/ckeditor5-markdown-gfm/package.json
仓库结构与架构
CKEditor 5 的核心由“编辑框架 + 特性包”两层组成。packages/ 目录下的每一个子目录通常对应一个独立发布的 npm 包,例如 @ckeditor/ckeditor5-engine(编辑引擎)、@ckeditor/ckeditor5-ui(UI 层)、@ckeditor/ckeditor5-page-break(分页符特性)等。顶层 ckeditor5 包(聚合包)则把这些特性重新导出,方便上层业务方一次性引入。
核心层次结构
graph TD
A["应用层<br/>(Angular / React / Vue / Next.js)"] --> B["聚合包 ckeditor5"]
B --> C["@ckeditor/ckeditor5-engine<br/>(数据模型 + 视图 + 控制器)"]
B --> D["@ckeditor/ckeditor5-ui<br/>(工具栏、组件、视图)"]
B --> E["@ckeditor/ckeditor5-utils<br/>(mixin、全局对象等工具)"]
B --> F["@ckeditor/ckeditor5-* 特性包<br/>(bookmark, page-break, markdown-gfm, ...)"]
C --> E
D --> E
F --> C
F --> D关键设计点
资料来源:packages/ckeditor5-utils/src/mix.ts
资料来源:packages/ckeditor5-utils/src/dom/global.ts
资料来源:packages/ckeditor5-engine/README.md
- 基于类的插件模型:所有特性都以
Plugin类形式注入到Editor实例中,编辑器通过editor.plugins访问它们。 - Mixin 工具:
@ckeditor/ckeditor5-utils提供Constructor与Mixed<Base, Mixin>等类型工具,用于以类型安全的方式组合多个 mixin,例如把额外行为注入Plugin基类。 - DOM 抽象层:通过
global.window/global.document暴露全局对象,便于测试时通过sinon.stub替换浏览器原生 API。 - 引擎层说明:
@ckeditor/ckeditor5-engine包自身的 README 描述了编辑引擎的职责,包括数据模型、Schema、命令、选择等核心概念。
快速开始
README 中提供了多种安装路径,业务方可以根据自身需求选择最合适的方案:
资料来源:README.md
资料来源:README.md
资料来源:README.md
- 使用 CKEditor 5 Builder:通过在线 Builder 选择编辑器类型与需要的插件,下载一个预配置好的开箱即用包。这是 README 推荐的最简方式。
- 按框架集成:对于需要把 CKEditor 5 集成到现有 SPA 框架中的项目,官方提供 Angular、React、Vue 等集成文档。
- 使用 CKEditor 5 Framework(高级安装):直接基于
@ckeditor/ckeditor5-*包进行自定义构建,适合需要深度定制的团队。
社区提示:截至 issue #7376,从 v42.0.0 起官方提供的新安装方法可以无缝对接 Next.js 等现代框架。
资料来源:Issue #7376 - Next.js integration
TypeScript 支持
CKEditor 5 是一个 TypeScript 项目。从 v37.0.0 起,官方包直接提供原生类型定义(index.d.ts),无需再额外安装 @types/* 或自行生成。
CKEditor 5 is a TypeScript project. Starting from v37.0.0, official packages provide native type definitions.
资料来源:README.md
packages/ckeditor5/package.json 的 publishConfig 也明确指出:"types": "./dist/index.d.ts" —— 即发布到 npm 时会携带官方声明文件,这与 issue #504 中长期被呼吁的 TypeScript 类型需求一致。
// 典型用法:直接 import 类型
import { Editor, Plugin } from 'ckeditor5';
class MyPlugin extends Plugin {
static get pluginName() { return 'MyPlugin' as const; }
}
资料来源:packages/ckeditor5/package.json、Issue #504 - Typings for TypeScript
特性生态与社区关注的痛点
CKEditor 5 仓库中除了核心框架外,还提供了大量开箱即用的特性包。例如:
资料来源:packages/ckeditor5-bookmark/README.md
资料来源:packages/ckeditor5-source-editing/README.md
资料来源:packages/ckeditor5-markdown-gfm/package.json
资料来源:packages/ckeditor5-page-break/package.json
@ckeditor/ckeditor5-bookmark:书签功能,详见其 README 中的演示链接。@ckeditor/ckeditor5-source-editing:源码编辑模式,适合需要直接编辑 HTML 的用户。@ckeditor/ckeditor5-markdown-gfm:GitHub Flavored Markdown 数据处理器,可在 Markdown 与编辑器模型之间互相转换。@ckeditor/ckeditor5-page-break:分页符功能,便于处理打印或 PDF 导出场景。
社区中呼声较高的几个问题与编辑器的“内容表达/交互”能力直接相关,下游用户在选型时应当留意:
| 社区议题 | 影响 | 来源 |
|---|---|---|
editor.getData() 是否可输出内联样式(如 <table style="...">) | 与 data pipeline / HTML 数据处理器配置相关 | #1627 |
| 内容拖拽(drag & drop)支持现状 | 当前仅支持复制粘贴与文件拖拽,内容拖拽体验有限 | #2664 |
| 媒体嵌入(Media embed)调整大小 | v48.2.0 起已支持通过拖拽手柄调整大小 | #6593 |
| Next.js 集成文档 | v42.0.0 后新安装方法可与 Next.js 无缝协作 | #7376 |
贡献与版本节奏
CKEditor 5 仓库同时承担“代码托管 + 集中式开发工具链”的角色:根级 package.json 通过 @ckeditor/ckeditor5-dev-* 系列工具统一管理构建、文档、许可证检查、CI、发布等流程。
资料来源:package.json
资料来源:README.md
资料来源:README.md
- Node 与包管理器要求:仓库要求
node >=24.11.0、pnpm >=10.28.0,并在engines字段中明确提示“我们现在使用 pnpm”。 - 许可协议:项目采用 GPL-2.0-or-later 与 CKSource 商业许可证双许可模式。
- 贡献流程:贡献者应阅读官方 contributors 指南,并在该仓库的 Issues 区提交反馈与功能请求。
常见失败模式
基于仓库结构与社区反馈,新用户最常遇到的“踩坑点”包括:
资料来源:package.json
资料来源:packages/ckeditor5/package.json
资料来源:Issue #1627
- 使用 npm / yarn 而非 pnpm:根
package.json中明确以横幅提示项目已迁移至 pnpm,使用其他包管理器可能无法正确解析workspace:*依赖。 - 运行旧版本 Node:低于
24.11.0的 Node 可能在engines检查阶段被工具链拒绝。 - 混淆“特性包”与“聚合包”:直接
@ckeditor/ckeditor5-engine等只暴露底层 API,而ckeditor5聚合包才汇总了常用特性;从packages/ckeditor5/package.json的exports与dependencies可以看出两者关系。 - 数据格式假设错误:若业务期望
editor.getData()直接返回带内联样式的 HTML,需要通过数据处理器或自定义转换逻辑实现,而非默认输出。
See Also
资料来源:package.json、packages/ckeditor5/package.json、packages/ckeditor5-markdown-gfm/package.json
Core Architecture: Engine, Model, View, and Plugins
CKEditor 5 是一个现代化的 JavaScript 富文本编辑器,采用 MVC 架构、自定义数据模型、虚拟 DOM,完全使用 TypeScript 编写,并对现代打包工具(如 Vite、Webpack、Next.js 等)提供良好支持。资料来源:[README.md]()。
继续阅读本节完整说明和来源证据。
核心架构:Engine、Model、View 与 Plugins
概述与设计目标
CKEditor 5 是一个现代化的 JavaScript 富文本编辑器,采用 MVC 架构、自定义数据模型、虚拟 DOM,完全使用 TypeScript 编写,并对现代打包工具(如 Vite、Webpack、Next.js 等)提供良好支持。资料来源:README.md。
其核心目标是解决传统 contentEditable 的浏览器兼容性问题,并为富文本编辑提供"可扩展、可测试、可协作"的工程基座。资料来源:packages/ckeditor5-engine/README.md。
仓库本身是一个模块化的多包 monorepo(基于 pnpm 工作区),统一发布版本号为 48.2.0,多个独立功能包通过 ckeditor5 这一聚合包对外暴露 API。资料来源:packages/ckeditor5/package.json 与 package.json。
整体架构层次
CKEditor 5 自底向上大致可分为四层,各层由独立 npm 包实现,职责清晰、低耦合:
| 层级 | 主要包 | 职责 |
|---|---|---|
| 工具层 | ckeditor5-utils | 提供 mixin、全局对象、DOM 抽象等基础设施 |
| 核心层 | ckeditor5-core | 插件、命令、编辑器生命周期、配置归一化 |
| 引擎层 | ckeditor5-engine | 数据模型、视图树、Schema、转换器、协同 OT |
| 特性层 | ckeditor5-image、ckeditor5-heading 等 | 标题、图片、表格、源码编辑等具体功能 |
各特性包通过声明对核心/引擎包(例如 @ckeditor/ckeditor5-engine、@ckeditor/ckeditor5-core)的 workspace:* 依赖完成装配。资料来源:packages/ckeditor5-core/package.json 与 packages/ckeditor5-markdown-gfm/package.json。
flowchart TD
A[Application / Builder] --> B[ckeditor5 聚合包]
B --> C[ckeditor5-core<br/>Plugin · Command · Editor]
C --> D[ckeditor5-engine<br/>Model · View · Schema]
C --> E[ckeditor5-ui<br/>Toolbar · Balloon · Dropdown]
D --> F[ckeditor5-utils<br/>mix · global · DOM]
E --> F
C --> G[特性包<br/>image · heading · typing · ...]
G --> D引擎层:Model、View 与 Schema
ckeditor5-engine 是整个编辑器的"心脏"。其设计遵循几条核心原则:
- 自定义树形数据模型。所有内容(段落、图片、表格等)以结构化节点表示,而不是直接操作 DOM,从而避免浏览器差异并天然支持撤销/重做与协同编辑。
- 编辑专用虚拟 DOM。引擎维护一个 View 树,负责屏蔽原生
contentEditable行为,负责渲染与光标管理。 - Schema-less 核心。引擎只提供最少的模型假设,具体允许哪些节点和属性,由各插件通过
schema注册。 - 可扩展的转换器(Converter)。
model ⇄ view之间的双向转换通过可注册的自定义函数实现,支持自定义属性(如alt、src、srcset)。 - 可测试性。官方宣称测试数量是 React 的 3 倍,各包均维持 100% 代码覆盖率。资料来源:packages/ckeditor5-engine/README.md。
以图片块编辑为例,ImageBlockEditing 在 init() 中通过 editor.model.schema.register('imageBlock', { inheritAllFrom: '$blockObject', allowAttributes: ['alt','src','srcset'] }) 注册模型元素,再调用 _setupConversion() 完成到 View 层的输出与编辑管道映射。资料来源:packages/ckeditor5-image/src/image/imageblockediting.ts。
核心层:Editor、Plugin 与 Command
ckeditor5-core 提供了编辑器的"骨架"。
- Editor 是生命周期与事件总线的中心,负责挂载 UI、加载插件集合、维护配置(
editor.config)与数据根。 - Plugin 是所有功能扩展的基本单元,每个插件可以声明
static requires(所依赖的其他插件)、static pluginName,并在init()中注册命令、监听事件、修改 Schema。ImageBlockEditing即继承自Plugin,通过static get requires()声明对ImageEditing、ImageSizeAttributes、ImageUtils、ImagePlaceholder、ClipboardPipeline等的依赖,static get pluginName()返回唯一标识'ImageBlockEditing'。资料来源:packages/ckeditor5-image/src/image/imageblockediting.ts。 - Command 封装可执行的"动作",例如加粗、插入图片;插件可以将命令注册到
editor.commands后,UI 层(工具栏按钮、菜单项)即可绑定并调用。 - mixin 机制 来自
ckeditor5-utils,允许把多个接口"混入"到一个基类,所有插件和编辑器内部类均基于此组合行为。资料来源:packages/ckeditor5-utils/src/mix.ts。
需要特别注意的是,utils/dom/global 模块统一封装了 window 与 document 访问,从而让测试可以通过 stub 模拟各种浏览器环境,而无需真正修改全局对象。资料来源:packages/ckeditor5-utils/src/dom/global.ts。
UI 层与典型特性包
ckeditor5-ui 提供了与引擎解耦的 UI 框架,包含工具栏、块工具栏、气泡栏、下拉菜单、对话框等组件,这些组件通过订阅 editor.commands 与 editor.editing.view 变化来自我更新。资料来源:packages/ckeditor5-ui/README.md。
在 v48.2.0 中,Media embed 借助与 Image 相同的"widget resizer"机制实现了通过拖拽手柄调整大小,体现了特性包之间复用同一架构组件的模式——这也是用户社区长期关注的"媒体嵌入缩放"诉求(对应 issue #6593)的实现路径。
此外,TypeScript 类型支持自 v42.0.0 起通过新的安装方式开箱即用,解决了 issue #504 中长期讨论的类型定义需求;Next.js 集成(issue #7376)在 v42.0.0 后通过新的安装方式与 SSR 友好入口顺畅工作,得益于模块入口使用 "type": "module" 并直接指向 ./src/index.ts。资料来源:packages/ckeditor5/package.json。
常见实践与失败模式
- 直接在 View 层改 DOM:应改 Model 并通过 Converter 输出,否则会被引擎在下一轮渲染时覆盖。
- 遗漏 Schema 注册:新元素若未在插件
init()中通过editor.model.schema.register(...)注册,粘贴或转换时会丢失。 - 跨插件耦合:应通过事件(
editor.fire)或共享命令通信,而非直接持有其他插件实例引用。 - 测试中未使用
global抽象:在 Node/JSDOM 下访问window会失败,应通过import { global } from 'ckeditor5'统一访问。资料来源:packages/ckeditor5-utils/src/dom/global.ts。
See Also
- 编辑引擎架构(Editing engine architecture)
- 核心编辑器架构(Core editor architecture)
- 插件与命令开发指南
- 协作编辑(Real-time collaboration / OT)
来源:https://github.com/ckeditor/ckeditor5 / 项目说明书
Feature Plugins: Image, Table, Media Embed, Clipboard, and Drag & Drop
CKEditor 5 是一个模块化、TypeScript 编写的 WYSIWYG 编辑框架,由编辑引擎 (@ckeditor/ckeditor5-engine)、核心层 (@ckeditor/ckeditor5-core)、UI 库 (@ckeditor/ckeditor5-ui) 以及若干功能包组成。本页聚焦于图像 (ckeditor5-image)、表格、媒体嵌入、剪贴...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
CKEditor 5 是一个模块化、TypeScript 编写的 WYSIWYG 编辑框架,由编辑引擎 (@ckeditor/ckeditor5-engine)、核心层 (@ckeditor/ckeditor5-core)、UI 库 (@ckeditor/ckeditor5-ui) 以及若干功能包组成。本页聚焦于图像 (ckeditor5-image)、表格、媒体嵌入、剪贴板 (Clipboard) 与拖放 (Drag & Drop) 这几类最常用的特性插件,梳理它们的依赖关系、模型-视图-转换管线以及常见扩展点。资料来源:README.md:1-50 packages/ckeditor5-engine/README.md:1-50
顶层包 ckeditor5 通过 "type": "module" 与 ESM 入口 ./src/index.ts 将所有官方特性聚合发布;在 publishConfig 中又同时暴露 UMD 产物 ./dist/ckeditor5.js 与类型声明 ./dist/index.d.ts,从而满足现代打包器与 SSR 框架(如 Next.js,参见社区议题 #7376)的集成需求。资料来源:packages/ckeditor5/package.json:18-50
Image 图像插件
块级图像:`ImageBlockEditing`
ImageBlockEditing 是图像块级编辑的核心插件。它在 init() 中调用 editor.model.schema.register('imageBlock', …),以 inheritAllFrom: '$blockObject' 继承块级对象语义,并显式允许 alt、src、srcset 三个属性。资料来源:packages/ckeditor5-image/src/image/imageblockediting.ts:38-55
插件通过 static get requires 声明强依赖:ImageEditing、ImageSizeAttributes、ImageUtils、ImagePlaceholder 与 ClipboardPipeline,体现"图像-尺寸-工具-占位-剪贴板"的标准组合。资料来源:packages/ckeditor5-image/src/image/imageblockediting.ts:19-33
当检测到已安装 ImageInlineEditing 时,ImageBlockEditing 会注册 imageTypeBlock 命令 (ImageTypeCommand),用于在行内与块级图像之间互转,并启用 _setupClipboardIntegration() 让粘贴行为同时理解两种图像模型。资料来源:packages/ckeditor5-image/src/image/imageblockediting.ts:48-55
`<picture>` 上转换
converters.ts 中的 upcastPicture() 负责将 HTML <picture><source/><img/></picture> 转为统一的 sources 模型属性。函数先以 conversionApi.consumable.test() 防御重复消费,再遍历子 <source> 收集 srcset、media、type、sizes 等键值,存入 Map<ViewElement, Record<string, string|undefined>>。资料来源:packages/ckeditor5-image/src/image/converters.ts:1-50
Clipboard、拖放与社区关注点
ClipboardPipeline 出现在 ImageBlockEditing 的 requires 中,说明图像与剪贴板管线是紧耦合设计:所有来自外部 HTML、纯文本或文件的输入都先经过统一的剪贴板管线再进入模型。资料来源:packages/ckeditor5-image/src/image/imageblockediting.ts:19-33 这一点对表格 (editor.getData() 输出 <figure class="table"> 包裹形式,社区议题 #1627) 与媒体嵌入 (resize 支持,社区议题 #6593) 的扩展同样适用——其行为都受制于同一套 schema 与 converter 机制。
社区长期跟踪的"内容拖放"功能(议题 #2664)受限于编辑器在虚拟 DOM 上接管事件系统的设计:CKEditor 5 在引擎层屏蔽了原生 contentEditable 的差异,因此对跨区块、跨编辑器的拖放需要通过专门的 DragDrop 集成。资料来源:packages/ckeditor5-engine/README.md:1-50
工具与基础设施
utils/dom/global 提供 GlobalType 接口,包含只读的 window 与 document 字段;通过 try/catch 包裹的赋值使其在 Node.js 等无 DOM 环境中仍能加载编辑器。文档示例还演示了如何在测试中用 testUtils.sinon.stub(global, 'window', …) 安全地替换 window 引用。资料来源:packages/ckeditor5-utils/src/dom/global.ts:25-50
utils/mix 模块暴露 Constructor<Instance> 与 Mixed<Base, Mixin> 等类型工具,便于在 TypeScript 中以 mixin 方式组合功能。资料来源:packages/ckeditor5-utils/src/mix.ts:18-50
page-break 与 markdown-gfm 等独立包均以 "type": "module" 形式发布,统一依赖 ckeditor5-core、ckeditor5-engine、ckeditor5-ui、ckeditor5-utils、ckeditor5-widget,印证了特性插件与基础设施之间的标准化边界。资料来源:packages/ckeditor5-page-break/package.json:30-50 packages/ckeditor5-markdown-gfm/package.json:25-50
插件依赖架构
graph TB Editor[Editor] Editor --> IBE[ImageBlockEditing] IBE --> IE[ImageEditing] IBE --> ISA[ImageSizeAttributes] IBE --> IU[ImageUtils] IBE --> IP[ImagePlaceholder] IBE --> CP[ClipboardPipeline] IBE --> IIE[ImageInlineEditing] IBE --> ITC[imageTypeBlock Command] UP[upcastPicture Converter] --> IBE CP --> Pipeline[Clipboard / Drag-Drop Pipeline] Pipeline --> Model[Editor Model + Schema]
该图概括了 ImageBlockEditing 的依赖链与剪贴板/拖放管线的关系:当用户拖入或粘贴内容时,ClipboardPipeline 接收原始数据,upcastPicture 等转换器把 HTML 转为模型节点,模型再通过 schema 约束(alt、src、srcset)保证一致性。资料来源:packages/ckeditor5-image/src/image/imageblockediting.ts:19-55 packages/ckeditor5-image/src/image/converters.ts:1-50
See Also
来源:https://github.com/ckeditor/ckeditor5 / 项目说明书
Framework Integration and Extensibility
CKEditor 5 是一个现代化的 JavaScript 富文本编辑器,采用 MVC 架构、自定义数据模型和虚拟 DOM,从零开始使用 TypeScript 编写 资料来源:[README.md:30-32]()。该项目被定位为"用于构建富文本编辑器的框架",强调可扩展性、事件驱动和高度解耦的设计原则 资料来源:[packages/ckeditor5-engine/REA...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
Framework Integration and Extensibility(框架集成与可扩展性)
概述与设计目标
CKEditor 5 是一个现代化的 JavaScript 富文本编辑器,采用 MVC 架构、自定义数据模型和虚拟 DOM,从零开始使用 TypeScript 编写 资料来源:README.md:30-32。该项目被定位为"用于构建富文本编辑器的框架",强调可扩展性、事件驱动和高度解耦的设计原则 资料来源:packages/ckeditor5-engine/README.md:14-22。
编辑器架构围绕三个核心特性构建:
- 可扩展性:代码基于事件并高度解耦,允许插入或替换选定的组件;特性之间不直接相互依赖,而是通过标准化方式通信 资料来源:packages/ckeditor5-engine/README.md:18-19。
- 模式无关的核心:核心层只做最少假设,可通过 schema 控制,将决策权留给插件与开发者 资料来源:packages/ckeditor5-engine/README.md:21-23。
- 模块化架构:核心模块与特性都可被重用和重新组合,甚至可在 Node.js 中以无头模式运行 资料来源:packages/ckeditor5-engine/README.md:24-25。
单仓库结构与包组织
CKEditor 5 是一个模块化、多包的单仓库(monorepo)项目,由多个协同的包组成编辑框架 资料来源:README.md:65-67。根目录的 package.json 中通过 workspace:* 引用内部依赖,并使用 pnpm 作为包管理器(pnpm: ">=10.28.0") 资料来源:package.json:15-21。
核心包概览
| 包名称 | 角色 | 关键依赖 | 说明 |
|---|---|---|---|
ckeditor5 | 编辑器入口 | @ckeditor/... 工作区依赖 | 当前版本 48.2.0,对外发布统一 API |
@ckeditor/ckeditor5-engine | 编辑引擎 | ckeditor5-core 等 | 实现虚拟 DOM、树模型与操作转换 |
@ckeditor/ckeditor5-utils | 通用工具 | 无运行时外部依赖 | 提供 mixin、全局 DOM 访问等机制 |
@ckeditor/ckeditor5-markdown-gfm | 数据处理器扩展 | clipboard、core、engine | 提供 GitHub Flavored Markdown 解析 |
@ckeditor/ckeditor5-source-editing | 特性插件 | engine、ui | 提供 HTML 源码编辑视图 |
资料来源:packages/ckeditor5/package.json:1-60、packages/ckeditor5-engine/README.md:1-50、packages/ckeditor5-markdown-gfm/package.json:38-46、packages/ckeditor5-source-editing/README.md:1-15。
TypeScript 与类型导出
CKEditor 5 全量以 TypeScript 编写,通过 package.json 的 types 字段提供完整类型定义。主包 ckeditor5 在发布配置中通过 ./dist/index.d.ts 暴露类型,所有内部包(如 @ckeditor/ckeditor5-typing)同样提供类型支持 资料来源:packages/ckeditor5/package.json:23-31、packages/ckeditor5-typing/README.md:1-15。
graph LR
A[主包 ckeditor5] --> B[React]
A --> C[Next.js]
A --> D[Vue.js]
A --> E[Angular]
A --> F[Svelte]
A --> G[jQuery]
A --> H[Node.js 无头]
B -. devDeps .-> I[@ckeditor/ckeditor5-react]
C -. devDeps .-> I主入口通过 exports 字段暴露,区分开发与发布两种模式:
"main": "./src/index.ts",
"exports": { ".": "./src/index.ts", "./*": "./*" },
"publishConfig": {
"main": "./dist/ckeditor5.js",
"types": "./dist/index.d.ts"
}
资料来源:packages/ckeditor5/package.json:16-31。
这一机制回应了社区对 TypeScript 类型定义的长期需求(参考 issue #504):开发期直接消费 TypeScript 源文件以获得最新 API;发布后切换到产物与 .d.ts,使编辑器可在不同框架宿主中以统一方式导入。
核心扩展性机制
Mixin 组合工具
@ckeditor/ckeditor5-utils 包提供的 mix.ts 模块是插件复用的关键。它定义两个核心类型:
Constructor<Instance>:表示对象构造函数,可作为类型约束使用 资料来源:packages/ckeditor5-utils/src/mix.ts:9-22。Mixed<Base, Mixin>:从基类与 mixin 接口组合构造函数类型 资料来源:packages/ckeditor5-utils/src/mix.ts:38-50。
这种组合方式使特性插件能够以可组合方式附加到基类,而无需复杂的继承层次,与"特性之间通过标准化方式通信"的设计原则保持一致。
全局 DOM 访问抽象
global.ts 通过 GlobalType 接口封装对 window 与 document 的访问 资料来源:packages/ckeditor5-utils/src/dom/global.ts:14-25。在缺乏 DOM 的环境(如 Node.js 无头模式)中,模块会以 try/catch 静默捕获异常,使编辑器代码可同时在浏览器与服务器环境中运行 资料来源:packages/ckeditor5-utils/src/dom/global.ts:30-50。
这一抽象对扩展性至关重要:开发者既能在浏览器测试中使用真实 DOM,又能通过 sinon.stub(global, 'window', ...) 等方式轻松模拟以编写可测试的特性代码 资料来源:packages/ckeditor5-utils/src/dom/global.ts:18-27。
数据处理器扩展点
CKEditor 5 通过数据处理器(data processor)模式实现输入/输出格式的可插拔。@ckeditor/ckeditor5-markdown-gfm 包即是这一模式的实例:它基于 @ckeditor/ckeditor5-clipboard、ckeditor5-core、ckeditor5-engine 实现 GitHub Flavored Markdown 解析 资料来源:packages/ckeditor5-markdown-gfm/package.json:38-46。开发者可遵循相同接口实现自定义方言(如 XML、JIRA Wiki),并通过 editor.data.processor 替换默认实现,从而控制 editor.getData() 的输出(回应社区 issue #1627 中关于内联样式的需求)。
发布配置中通过 sideEffects: ["*.css", "dist/translations/*.umd.js"] 显式声明 CSS 与翻译文件的副作用,确保打包工具正确处理样式资源 资料来源:packages/ckeditor5-markdown-gfm/package.json:36-37。
集成常见陷阱与最佳实践
- 导入路径差异:开发环境下
exports指向./src/index.ts,构建工具需能解析 TypeScript;发布版本则通过publishConfig.exports切到./dist/index.js,集成时应区分构建目标 资料来源:packages/ckeditor5/package.json:16-31。 - 环境兼容性:扩展插件应通过
global.window/global.document访问 DOM,而非直接引用全局变量,以便在无头环境下优雅降级 资料来源:packages/ckeditor5-utils/src/dom/global.ts:30-50。 - SSR 框架(如 Next.js):在 SSR 环境中,需将编辑器加载限制在客户端组件内(参考社区 issue #7376 关于 Next.js 集成),避免服务器侧解析
window。 - 样式副作用:若扩展引入 CSS 或本地化文件,应在
sideEffects字段中显式声明,避免打包工具误剪裁 资料来源:packages/ckeditor5-markdown-gfm/package.json:36-37。
社区关注点映射
- TypeScript 类型(#504):已通过
types字段与 TS 源码交付解决。 - Next.js 集成(#7376):v42.0.0 起的安装方法与 SSR 工作流兼容。
getData()输出格式(#1627):可通过自定义数据处理器控制序列化输出。- 内容拖拽(#2664):基于虚拟 DOM 与 schema 的事件机制为该特性提供扩展基础。
- 媒体嵌入调整(#6593):v48.2.0 起媒体嵌入已支持拖拽手柄调整大小(参考最新发布说明)。
See Also
资料来源:packages/ckeditor5/package.json:1-60、packages/ckeditor5-engine/README.md:1-50、packages/ckeditor5-markdown-gfm/package.json:38-46、packages/ckeditor5-source-editing/README.md:1-15。
失败模式与踩坑日记
保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。
可能增加新用户试用和生产接入成本。
可能增加新用户试用和生产接入成本。
可能增加新用户试用和生产接入成本。
可能增加新用户试用和生产接入成本。
Pitfall Log / 踩坑日志
项目:ckeditor/ckeditor5
摘要:发现 21 个潜在踩坑项,其中 3 个为 high/blocking;最高优先级:维护坑 - 来源证据:Checklist cursor position。
1. 维护坑 · 来源证据:Checklist cursor position
- 严重度:high
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题:Checklist cursor position
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 证据:community_evidence:github | https://github.com/ckeditor/ckeditor5/issues/20107 | 来源讨论提到 windows 相关条件,需在安装/试用前复核。
2. 维护坑 · 来源证据:Docs issue report from "api/module_basic-styles_italic-Italic.html"
- 严重度:high
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题:Docs issue report from "api/module_basic-styles_italic-Italic.html"
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 证据:community_evidence:github | https://github.com/ckeditor/ckeditor5/issues/18352 | 来源类型 github_issue 暴露的待验证使用条件。
3. 维护坑 · 来源证据:Incorrect order of adjacent markers in output data (follow-up)
- 严重度:high
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题:Incorrect order of adjacent markers in output data (follow-up)
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 证据:community_evidence:github | https://github.com/ckeditor/ckeditor5/issues/20196 | 来源类型 github_issue 暴露的待验证使用条件。
4. 安装坑 · 来源证据:Cannot add custom button to HeadingButtonUi
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:Cannot add custom button to HeadingButtonUi
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 证据:community_evidence:github | https://github.com/ckeditor/ckeditor5/issues/18524 | 来源类型 github_issue 暴露的待验证使用条件。
5. 安装坑 · 来源证据:Column resize in nested child table.
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:Column resize in nested child table.
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 证据:community_evidence:github | https://github.com/ckeditor/ckeditor5/issues/19609 | 来源类型 github_issue 暴露的待验证使用条件。
6. 安装坑 · 来源证据:Emoji (Mention) tooltip calculates positioning doesn't update after entering text
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:Emoji (Mention) tooltip calculates positioning doesn't update after entering text
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 证据:community_evidence:github | https://github.com/ckeditor/ckeditor5/issues/18547 | 来源讨论提到 windows 相关条件,需在安装/试用前复核。
7. 安装坑 · 来源证据:How do I hide items in Heading dropdown when using HeadingButtonUi plugin ?
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:How do I hide items in Heading dropdown when using HeadingButtonUi plugin ?
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 证据:community_evidence:github | https://github.com/ckeditor/ckeditor5/issues/18525 | 来源类型 github_issue 暴露的待验证使用条件。
8. 安装坑 · 来源证据:Image config to overide default image alignment doesnt work
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:Image config to overide default image alignment doesnt work
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 证据:community_evidence:github | https://github.com/ckeditor/ckeditor5/issues/18545 | 来源类型 github_issue 暴露的待验证使用条件。
9. 安装坑 · 来源证据:Increased border radius on menu bar or toolbar in classic editor crops the border
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:Increased border radius on menu bar or toolbar in classic editor crops the border
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 证据:community_evidence:github | https://github.com/ckeditor/ckeditor5/issues/18522 | 来源类型 github_issue 暴露的待验证使用条件。
10. 安装坑 · 来源证据:Increasing indent with a cross-list selection merges items from the lower list into the upper list when the selection s…
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:Increasing indent with a cross-list selection merges items from the lower list into the upper list when the selection spans different list types
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 证据:community_evidence:github | https://github.com/ckeditor/ckeditor5/issues/19846 | 来源讨论提到 macos 相关条件,需在安装/试用前复核。
11. 安装坑 · 来源证据:New item in a to-do list inherits state from the previous one.
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:New item in a to-do list inherits state from the previous one.
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 证据:community_evidence:github | https://github.com/ckeditor/ckeditor5/issues/5620 | 来源类型 github_issue 暴露的待验证使用条件。
12. 安装坑 · 来源证据:📄 Nightly releases changelog
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:📄 Nightly releases changelog
- 对用户的影响:可能阻塞安装或首次运行。
- 证据:community_evidence:github | https://github.com/ckeditor/ckeditor5/issues/14724 | 来源讨论提到 npm 相关条件,需在安装/试用前复核。
13. 能力坑 · 能力判断依赖假设
- 严重度:medium
- 证据强度:source_linked
- 发现:README/documentation is current enough for a first validation pass.
- 对用户的影响:假设不成立时,用户拿不到承诺的能力。
- 证据:capability.assumptions | https://github.com/ckeditor/ckeditor5 | README/documentation is current enough for a first validation pass.
14. 运行坑 · 来源证据:Fullscreen: Balloon-panel can overlap toolbar for element which is taller than visible editor area
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个运行相关的待验证问题:Fullscreen: Balloon-panel can overlap toolbar for element which is taller than visible editor area
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 证据:community_evidence:github | https://github.com/ckeditor/ckeditor5/issues/20194 | 来源类型 github_issue 暴露的待验证使用条件。
15. 维护坑 · 来源证据:Table shrinks when resizing columns in editor with fixed height and scrollbar
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题:Table shrinks when resizing columns in editor with fixed height and scrollbar
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 证据:community_evidence:github | https://github.com/ckeditor/ckeditor5/issues/20117 | 来源类型 github_issue 暴露的待验证使用条件。
16. 维护坑 · 维护活跃度未知
- 严重度:medium
- 证据强度:source_linked
- 发现:未记录 last_activity_observed。
- 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
- 证据:evidence.maintainer_signals | https://github.com/ckeditor/ckeditor5 | last_activity_observed missing
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 证据:downstream_validation.risk_items | https://github.com/ckeditor/ckeditor5 | no_demo; severity=medium
18. 安全/权限坑 · 存在评分风险
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:风险会影响是否适合普通用户安装。
- 证据:risks.scoring_risks | https://github.com/ckeditor/ckeditor5 | no_demo; severity=medium
19. 安全/权限坑 · 来源证据:Make it simple to extend downcast converters for markers (and other)
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:Make it simple to extend downcast converters for markers (and other)
- 对用户的影响:可能影响授权、密钥配置或安全边界。
- 证据:community_evidence:github | https://github.com/ckeditor/ckeditor5/issues/10513 | 来源类型 github_issue 暴露的待验证使用条件。
20. 维护坑 · issue/PR 响应质量未知
- 严重度:low
- 证据强度:source_linked
- 发现:issue_or_pr_quality=unknown。
- 对用户的影响:用户无法判断遇到问题后是否有人维护。
- 证据:evidence.maintainer_signals | https://github.com/ckeditor/ckeditor5 | issue_or_pr_quality=unknown
21. 维护坑 · 发布节奏不明确
- 严重度:low
- 证据强度:source_linked
- 发现:release_recency=unknown。
- 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
- 证据:evidence.maintainer_signals | https://github.com/ckeditor/ckeditor5 | release_recency=unknown
来源:Doramagic 发现、验证与编译记录