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.0package.json / packages/ckeditor5/package.json
主包名(聚合发布)ckeditor5packages/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.0package.json

资料来源:package.jsonpackages/ckeditor5/package.jsonpackages/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 提供 ConstructorMixed<Base, Mixin> 等类型工具,用于以类型安全的方式组合多个 mixin,例如把额外行为注入 Plugin 基类。
  • DOM 抽象层:通过 global.window / global.document 暴露全局对象,便于测试时通过 sinon.stub 替换浏览器原生 API。
  • 引擎层说明@ckeditor/ckeditor5-engine 包自身的 README 描述了编辑引擎的职责,包括数据模型、Schema、命令、选择等核心概念。

快速开始

README 中提供了多种安装路径,业务方可以根据自身需求选择最合适的方案:

资料来源:README.md

资料来源:README.md

资料来源:README.md

  1. 使用 CKEditor 5 Builder:通过在线 Builder 选择编辑器类型与需要的插件,下载一个预配置好的开箱即用包。这是 README 推荐的最简方式。
  2. 按框架集成:对于需要把 CKEditor 5 集成到现有 SPA 框架中的项目,官方提供 Angular、React、Vue 等集成文档。
  3. 使用 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.jsonpublishConfig 也明确指出:"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.jsonIssue #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.0pnpm >=10.28.0,并在 engines 字段中明确提示“我们现在使用 pnpm”。
  • 许可协议:项目采用 GPL-2.0-or-later 与 CKSource 商业许可证双许可模式。
  • 贡献流程:贡献者应阅读官方 contributors 指南,并在该仓库的 Issues 区提交反馈与功能请求。

常见失败模式

基于仓库结构与社区反馈,新用户最常遇到的“踩坑点”包括:

资料来源:package.json

资料来源:packages/ckeditor5/package.json

资料来源:Issue #1627

  1. 使用 npm / yarn 而非 pnpm:根 package.json 中明确以横幅提示项目已迁移至 pnpm,使用其他包管理器可能无法正确解析 workspace:* 依赖。
  2. 运行旧版本 Node:低于 24.11.0 的 Node 可能在 engines 检查阶段被工具链拒绝。
  3. 混淆“特性包”与“聚合包”:直接 @ckeditor/ckeditor5-engine 等只暴露底层 API,而 ckeditor5 聚合包才汇总了常用特性;从 packages/ckeditor5/package.jsonexportsdependencies 可以看出两者关系。
  4. 数据格式假设错误:若业务期望 editor.getData() 直接返回带内联样式的 HTML,需要通过数据处理器或自定义转换逻辑实现,而非默认输出。

See Also

资料来源:package.jsonpackages/ckeditor5/package.jsonpackages/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.jsonpackage.json

整体架构层次

CKEditor 5 自底向上大致可分为四层,各层由独立 npm 包实现,职责清晰、低耦合:

层级主要包职责
工具层ckeditor5-utils提供 mixin、全局对象、DOM 抽象等基础设施
核心层ckeditor5-core插件、命令、编辑器生命周期、配置归一化
引擎层ckeditor5-engine数据模型、视图树、Schema、转换器、协同 OT
特性层ckeditor5-imageckeditor5-heading标题、图片、表格、源码编辑等具体功能

各特性包通过声明对核心/引擎包(例如 @ckeditor/ckeditor5-engine@ckeditor/ckeditor5-core)的 workspace:* 依赖完成装配。资料来源:packages/ckeditor5-core/package.jsonpackages/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 之间的双向转换通过可注册的自定义函数实现,支持自定义属性(如 altsrcsrcset)。
  • 可测试性。官方宣称测试数量是 React 的 3 倍,各包均维持 100% 代码覆盖率。资料来源:packages/ckeditor5-engine/README.md

以图片块编辑为例,ImageBlockEditinginit() 中通过 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() 声明对 ImageEditingImageSizeAttributesImageUtilsImagePlaceholderClipboardPipeline 等的依赖,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 模块统一封装了 windowdocument 访问,从而让测试可以通过 stub 模拟各种浏览器环境,而无需真正修改全局对象。资料来源:packages/ckeditor5-utils/src/dom/global.ts

UI 层与典型特性包

ckeditor5-ui 提供了与引擎解耦的 UI 框架,包含工具栏、块工具栏、气泡栏、下拉菜单、对话框等组件,这些组件通过订阅 editor.commandseditor.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)、表格、媒体嵌入、剪贴...

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 块级图像:ImageBlockEditing

继续阅读本节完整说明和来源证据。

章节 <picture 上转换

继续阅读本节完整说明和来源证据。

概述

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' 继承块级对象语义,并显式允许 altsrcsrcset 三个属性。资料来源:packages/ckeditor5-image/src/image/imageblockediting.ts:38-55

插件通过 static get requires 声明强依赖:ImageEditingImageSizeAttributesImageUtilsImagePlaceholderClipboardPipeline,体现"图像-尺寸-工具-占位-剪贴板"的标准组合。资料来源: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> 收集 srcsetmediatypesizes 等键值,存入 Map<ViewElement, Record<string, string|undefined>>。资料来源:packages/ckeditor5-image/src/image/converters.ts:1-50

Clipboard、拖放与社区关注点

ClipboardPipeline 出现在 ImageBlockEditingrequires 中,说明图像与剪贴板管线是紧耦合设计:所有来自外部 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 接口,包含只读的 windowdocument 字段;通过 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-breakmarkdown-gfm 等独立包均以 "type": "module" 形式发布,统一依赖 ckeditor5-coreckeditor5-engineckeditor5-uickeditor5-utilsckeditor5-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 约束(altsrcsrcset)保证一致性。资料来源: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...

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 核心包概览

继续阅读本节完整说明和来源证据。

章节 Mixin 组合工具

继续阅读本节完整说明和来源证据。

章节 全局 DOM 访问抽象

继续阅读本节完整说明和来源证据。

Framework Integration and Extensibility(框架集成与可扩展性)

概述与设计目标

CKEditor 5 是一个现代化的 JavaScript 富文本编辑器,采用 MVC 架构、自定义数据模型和虚拟 DOM,从零开始使用 TypeScript 编写 资料来源:README.md:30-32。该项目被定位为"用于构建富文本编辑器的框架",强调可扩展性、事件驱动和高度解耦的设计原则 资料来源:packages/ckeditor5-engine/README.md:14-22

编辑器架构围绕三个核心特性构建:

单仓库结构与包组织

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数据处理器扩展clipboardcoreengine提供 GitHub Flavored Markdown 解析
@ckeditor/ckeditor5-source-editing特性插件engineui提供 HTML 源码编辑视图

资料来源:packages/ckeditor5/package.json:1-60packages/ckeditor5-engine/README.md:1-50packages/ckeditor5-markdown-gfm/package.json:38-46packages/ckeditor5-source-editing/README.md:1-15

TypeScript 与类型导出

CKEditor 5 全量以 TypeScript 编写,通过 package.jsontypes 字段提供完整类型定义。主包 ckeditor5 在发布配置中通过 ./dist/index.d.ts 暴露类型,所有内部包(如 @ckeditor/ckeditor5-typing)同样提供类型支持 资料来源:packages/ckeditor5/package.json:23-31packages/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 模块是插件复用的关键。它定义两个核心类型:

这种组合方式使特性插件能够以可组合方式附加到基类,而无需复杂的继承层次,与"特性之间通过标准化方式通信"的设计原则保持一致。

全局 DOM 访问抽象

global.ts 通过 GlobalType 接口封装对 windowdocument 的访问 资料来源: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-clipboardckeditor5-coreckeditor5-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

集成常见陷阱与最佳实践

  1. 导入路径差异:开发环境下 exports 指向 ./src/index.ts,构建工具需能解析 TypeScript;发布版本则通过 publishConfig.exports 切到 ./dist/index.js,集成时应区分构建目标 资料来源:packages/ckeditor5/package.json:16-31
  2. 环境兼容性:扩展插件应通过 global.window/global.document 访问 DOM,而非直接引用全局变量,以便在无头环境下优雅降级 资料来源:packages/ckeditor5-utils/src/dom/global.ts:30-50
  3. SSR 框架(如 Next.js):在 SSR 环境中,需将编辑器加载限制在客户端组件内(参考社区 issue #7376 关于 Next.js 集成),避免服务器侧解析 window
  4. 样式副作用:若扩展引入 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-60packages/ckeditor5-engine/README.md:1-50packages/ckeditor5-markdown-gfm/package.json:38-46packages/ckeditor5-source-editing/README.md:1-15

失败模式与踩坑日记

保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。

high 来源证据:Checklist cursor position

可能增加新用户试用和生产接入成本。

high 来源证据:Docs issue report from "api/module_basic-styles_italic-Italic.html"

可能增加新用户试用和生产接入成本。

high 来源证据:Incorrect order of adjacent markers in output data (follow-up)

可能增加新用户试用和生产接入成本。

medium 来源证据:Cannot add custom button to HeadingButtonUi

可能增加新用户试用和生产接入成本。

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 发现、验证与编译记录