CKEditor 5 新安装方式迁移指南:从 webpack 定制配置到 npm 包与浏览器构建(v42.0.0+)
【免费下载链接】ckeditor5Powerful rich text editor framework with a modular architecture, modern integrations, and features like collaborative editing.项目地址: https://gitcode.com/GitHub_Trending/ck/ckeditor5
本篇指南聚焦 CKEditor 5 自 v42.0.0 起引入的新安装方式(New Installation Methods,简称 NIM)。它回答三个问题:旧安装方式(预定义构建、自定义构建、DLL)到底难在哪里;新的 npm 包与浏览器构建两种路径应该如何落地配置;以及旧方式各自的废弃时间表与迁移步骤。读完本篇,你可以判断当前项目应采用哪种新安装方式、需要改动哪些配置,并对照仓库源码理解ckeditor5统一入口包的实现原理。
一、为什么需要新的安装方式:旧方式的痛点
在 42.0.0 之前,CKEditor 5 有多种安装途径,每一种都有各自的限制和"怪癖",在特定场景下难以甚至无法使用。由于各种配置彼此差异巨大,官方文档也很难在不显得过度复杂的前提下覆盖所有可能。
旧方式一个典型问题就是:即使只是"用 webpack 把编辑器打出来",也必须维护一段 CKEditor 5 专属的构建配置,来处理翻译、CSS 和 SVG 文件。下面是一个旧 npm 安装方式的真实示例(引自官方迁移文档 migration-to-new-installation-methods.md):
// webpack.config.js const path = require( 'path' ); const { CKEditorTranslationsPlugin } = require( '@ckeditor/ckeditor5-dev-translations' ); const { styles } = require( '@ckeditor/ckeditor5-dev-utils' ); module.exports = { entry: './src/index.js', output: { path: path.resolve( __dirname, 'dist' ), filename: 'bundle.js' }, plugins: [ new CKEditorTranslationsPlugin( { language: 'en' } ) ], module: { rules: [ { test: /\.svg$/, use: [ 'raw-loader' ] }, { test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/, use: [ { loader: 'style-loader', options: { injectType: 'singletonStyleTag', attributes: { 'data-cke': true } } }, 'css-loader', { loader: 'postcss-loader', options: { postcssOptions: styles.getPostCssConfig( { minify: true } ) } } ] } ] } };// src/index.js import { ClassicEditor } from '@ckeditor/ckeditor5-editor-classic'; import { Essentials } from '@ckeditor/ckeditor5-essentials'; import { Bold, Italic } from '@ckeditor/ckeditor5-basic-styles'; import { Paragraph } from '@ckeditor/ckeditor5-paragraph'; import { Mention } from '@ckeditor/ckeditor5-mention'; import { FormatPainter } from '@ckeditor/ckeditor5-format-painter'; import { SlashCommand } from '@ckeditor/ckeditor5-slash-command'; ClassicEditor .create( { attachTo: document.querySelector( '#editor' ), plugins: [ Essentials, Bold, Italic, Paragraph, Mention, FormatPainter, SlashCommand ], toolbar: [ /* ... */ ], licenseKey: '<YOUR_LICENSE_KEY>', // This value must be kept in sync with the language defined in webpack.config.js. language: 'en' } );注意示例中这条注释:language: 'en'必须与 webpack 配置中CKEditorTranslationsPlugin的语言保持手动同步——翻译、样式、图标全部依赖构建时注入和全局状态,这正是旧方式难以维护的根源。如果还想用 TypeScript,这套配置只会更复杂。
二、新安装方式:只有两条路径
新安装方式将可选路径收敛到仅两种:npm 包和浏览器构建(browser builds)。与旧方式相比:
- 不再需要添加几十个独立 npm 包或 JavaScript bundle;
- 编辑器与所有开源插件从
ckeditor5包导入,商业功能从ckeditor5-premium-features包导入; - 不需要任何 CKEditor 5 专属的 webpack 或 Vite 配置,开箱即用于任何现代打包器或 Next.js 等 JavaScript 元框架。
2.1 npm 包方式
这是使用模块打包器(Vite、webpack)或流行元框架时的推荐方式。下面展示了同时使用开源与商业功能、并导入翻译的完整配置:
import { ClassicEditor, Essentials, Bold, Italic, Paragraph, Mention } from 'ckeditor5'; import { FormatPainter, SlashCommand } from 'ckeditor5-premium-features'; import coreTranslations from 'ckeditor5/translations/pl.js'; import premiumFeaturesTranslations from 'ckeditor5-premium-features/translations/pl.js'; import 'ckeditor5/ckeditor5.css'; import 'ckeditor5-premium-features/ckeditor5-premium-features.css'; ClassicEditor .create( { attachTo: document.querySelector( '#editor' ), plugins: [ Essentials, Bold, Italic, Paragraph, Mention, FormatPainter, SlashCommand ], toolbar: [ /* ... */ ], licenseKey: '<YOUR_LICENSE_KEY>', translations: [ coreTranslations, premiumFeaturesTranslations ] } );配置要点:
- 统一入口:所有开源能力(编辑器类型、插件、指令)都从
ckeditor5这一个包导入;商业功能从ckeditor5-premium-features导入。 - CSS 独立导入:
import 'ckeditor5/ckeditor5.css'。样式与 JS 分离,既利于性能,也方便定制或删除默认编辑器样式。 - 翻译作为对象传入:
ckeditor5/translations/pl.js等翻译文件是 ES 模块默认导出,作为translations数组传给编辑器实例,替代了旧方式依赖全局状态的副作用导入(import '...')。这一点在编辑器源码中有直接印证:editor.ts 中创建编辑器时会执行const { translations = defaultTranslations, ...rest } = config;,并将translations一并传入新建的Context(约 L355–L363)。 - 零构建配置:不再需要处理 SVG、CSS 主题选择器、翻译插件等 loader 规则。
2.2 浏览器构建方式
不打算使用模块打包器时,可以使用浏览器构建。它以 JavaScript 模块形式发布,可直接通过<script type="module">加载,配合 import maps 把包名映射到 CDN 上的构建 URL({@var ckeditor5-version}处填入具体版本号):
<link rel="stylesheet" href="https://cdn.ckeditor.com/ckeditor5/{@var ckeditor5-version}/ckeditor5.css" /> <link rel="stylesheet" href="https://cdn.ckeditor.com/ckeditor5-premium-features/{@var ckeditor5-version}/ckeditor5-premium-features.css" /> <script type="importmap"> { "imports": { "ckeditor5": "https://cdn.ckeditor.com/ckeditor5/{@var ckeditor5-version}/ckeditor5.js", "ckeditor5/": "https://cdn.ckeditor.com/ckeditor5/{@var ckeditor5-version}/", "ckeditor5-premium-features": "https://cdn.ckeditor.com/ckeditor5-premium-features/{@var ckeditor5-version}/ckeditor5-premium-features.js", "ckeditor5-premium-features/": "https://cdn.ckeditor.com/ckeditor5-premium-features/{@var ckeditor5-version}/" } } </script> <script type="module"> import { ClassicEditor, Essentials, Bold, Italic, Paragraph, Mention } from 'ckeditor5'; import { FormatPainter, SlashCommand } from 'ckeditor5-premium-features'; import coreTranslations from 'ckeditor5/translations/pl.js'; import premiumFeaturesTranslations from 'ckeditor5-premium-features/translations/pl.js'; ClassicEditor .create( { attachTo: document.querySelector( '#editor' ), plugins: [ Essentials, Bold, Italic, Paragraph, Mention, FormatPainter, SlashCommand ], toolbar: [ /* ... */ ], licenseKey: '<YOUR_LICENSE_KEY>', translations: [ coreTranslations, premiumFeaturesTranslations ] } ); </script>注意 import map 中同时映射了ckeditor5(主模块)和ckeditor5/(前缀映射),后者正是import 'ckeditor5/translations/pl.js'这类子路径导入能生效的原因。
如果运行环境既不支持 import maps 也不支持 JavaScript 模块,则使用UMD 构建。UMD 会注册全局变量,供传统<script>标签脚本使用:
<!-- Style sheets --> <link rel="stylesheet" href="https://cdn.ckeditor.com/ckeditor5/{@var ckeditor5-version}/ckeditor5.css" /> <link rel="stylesheet" href="https://cdn.ckeditor.com/ckeditor5-premium-features/{@var ckeditor5-version}/ckeditor5-premium-features.css" /> <!-- Scripts --> <script src="https://cdn.ckeditor.com/ckeditor5/{@var ckeditor5-version}/ckeditor5.umd.js"></script> <script src="https://cdn.ckeditor.com/ckeditor5-premium-features/{@var ckeditor5-version}/ckeditor5-premium-features.umd.js"></script> <!-- Translations --> <script src="https://cdn.ckeditor.com/ckeditor5/{@var ckeditor5-version}/translations/pl.umd.js"></script> <script src="https://cdn.ckeditor.com/ckeditor5-premium-features/{@var ckeditor5-version}/translations/pl.umd.js"></script> <script> const { ClassicEditor, Essentials, Bold, Italic, Paragraph, Mention } = CKEDITOR; const { FormatPainter, SlashCommand } = CKEDITOR_PREMIUM_FEATURES; ClassicEditor .create( { attachTo: document.querySelector( '#editor' ), plugins: [ Essentials, Bold, Italic, Paragraph, Mention, FormatPainter, SlashCommand ], toolbar: [ /* ... */ ], licenseKey: '<YOUR_LICENSE_KEY>' } ); </script>UMD 构建注册的全局变量是CKEDITOR(核心)与CKEDITOR_PREMIUM_FEATURES(商业功能)。这个命名在仓库构建脚本中可以直接核实:scripts/nim/utils.mjs 的generateCKEditor5BrowserBuild()以name: 'CKEDITOR'生成浏览器构建,且browser: true与minify: true分别对应浏览器环境与压缩。
三、新旧方式对比:What's new 与功能矩阵
相比旧安装方式,新方式有四个突出变化(引自官方文档):
- 一切只从
ckeditor5与ckeditor5-premium-features两个包导入;浏览器中通过 import maps 将包名映射到构建 URL; - CSS 文件与 JS 文件分开导入,提升性能并让定制/移除默认样式更简单;
- 翻译以 JavaScript 对象形式传给编辑器实例,不再使用依赖全局状态的副作用导入;
- 无需再维护 CKEditor 5 专属的 webpack 或 Vite 配置,可与任何现代打包器或元框架搭配。
官方给出了新旧五种安装方式(npm、CDN、预定义、自定义、DLL)的功能对比矩阵:
| 安装方式 | npm(新) | CDN(新) | 预定义构建 | 自定义构建 | DLL |
|---|---|---|---|---|---|
| 无需构建步骤(No build step) | ❌ | ✅ | ✅ | ❌ | ✅ |
| 可用于任何现代打包器 | ✅ | ✅ | ✅ | ❌ | ❌ |
| 允许添加插件 | ✅ | ✅ | ❌ | ✅ | ✅ |
| 样式定制 | ✅ | ✅ | ❌ | ⚠️¹ | ❌ |
| 图标定制 | ✅ | ❌ | ❌ | ✅ | ❌ |
| 不依赖全局状态 | ✅ | ✅ | ❌ | ❌ | ❌ |
| 提供编辑器/纯内容样式表 | ✅ | ✅ | ❌ | ❌ | ❌ |
| 样式表与 JavaScript 分离 | ✅ | ✅ | ❌ | ⚠️² | ❌ |
| 可优化以减小 bundle 体积 | ✅ | ❌ | ❌ | ✅ | ✅ |
注:¹ 自定义构建仅通过 webpack 配置部分支持样式定制;² 自定义构建可通过自定义 webpack 配置把 CSS 从 JS 中分离。
矩阵中"预定义构建"指@ckeditor/ckeditor5-build-*系列 npm 包及其 CDN 对应物,"自定义构建"指从源码或旧版 Online Builder 构建的包,"DLL" 指 webpack DLL 插件方式。从表中可以看到新方式的独特组合:CDN 路径"零构建 + 可加插件 + 无全局状态",npm 路径则额外支持图标定制与 bundle 优化(tree-shaking 生效的前提是只用到的模块被实际 import,这与 src/index.ts 的模块再导出结构相匹配)。
四、仓库源码印证:ckeditor5统一入口包是怎么实现的
新安装方式的核心是ckeditor5这个统一入口包。结合当前仓库源码,可以看清它的实现:
1. 源码入口就是"聚合再导出"。packages/ckeditor5/src/index.ts 全文约 70 行,逐个export * from '@ckeditor/ckeditor5-*',覆盖 ui、core、engine、各编辑器类型及所有开源插件。文件头部注释特别说明了一个细节:@ckeditor/ckeditor5-ui的导出必须放在最上面,因为打包后的样式表遵循该顺序,而 ui 包的 theme 入口提供了其他样式所依赖的全局样式(reset、CSS 变量)。
2. 发布形态以dist为入口。packages/ckeditor5/package.json 中:开发态main指向./src/index.ts,而publishConfig把main/exports切换到./dist/ckeditor5.js与./dist/index.d.ts,子路径经"./*": "./dist/*"映射——这正是文档中"子路径导入ckeditor5/translations/pl.js、ckeditor5/ckeditor5.css"在发布包中成立的机制。files字段也表明发布产物只包含dist与文档类文件。
3. 构建流程分三步。scripts/nim/build-ckeditor5.mjs 依次执行:初始化 NPM 构建(清理旧输出、生成 TypeScript 声明与翻译文件)→ 生成dist/ckeditor5.js(ESM,external: ['ckeditor5'])→ 生成浏览器构建(输出到dist/browser/ckeditor5.js,压缩、挂载CKEDITOR全局名)。这与上面 UMD 示例中全局变量的来源完全对应。
4. 有回归测试保证"再导出完整性"。packages/ckeditor5/tests/node.js 遍历全部约 50 个@ckeditor/ckeditor5-*子包,断言ckeditor5统一入口的每个导出与对应子包的导出是同一引用(expect( ckeditor5[ exportName ] ).toBe( pkg[ exportName ] ))。这意味着"从ckeditor5导入"与"从子包导入"拿到的是同一份代码,为树摇优化和类型解析提供了基础。
五、旧安装方式的废弃时间表
随着 42.0.0 发布,官方决定废弃旧的设置方式。考虑到迁移需要排期,官方承诺按下表时间线继续支持,不因"废弃路径"而阻断错误修复与改进。
5.1 预定义构建(predefined builds)
ckeditor5-build-classic等官方预定义构建支持至2025 年第一季度末(2025 年 3 月)。该日期起:
- 移除预定义构建与 superbuild 的文档;
- 不再向 npm 发布预定义构建包的新版本;
- 构建环境目标提升至 ES2022,从而放弃对 webpack 4 的支持。
详见 predefined-builds 迁移指南。
5.2 自定义构建(custom builds)
"webpack-first" 的自定义构建方式(从src目录导入特定包)支持至2026 年第一季度末(2026 年 3 月)。该日期起:
- 移除自定义构建文档;
- 新版 npm 包不再包含
src目录,dist成为主要导入入口,所有导入都经由包索引进行(这与第四节中publishConfig的exports设计一致); - 废弃
@ckeditor/ckeditor5-dev-translations包(新方式不再需要它); - 待定事项:可能废弃从
CKEDITOR_TRANSLATIONS全局加载翻译——因为新安装方式提倡通过编辑器配置传入翻译。
详见 customized-builds 迁移指南。
5.3 DLL 构建
DLL 是一种高级方式,用于在浏览器端动态创建编辑器及其配置。由于浏览器构建现已开箱即用地提供同等能力,DLL 同样被废弃;考虑到其在复杂 CMS 中的使用深度,时间线相对更长:支持至 2026 年第一季度末(2026 年 3 月)。该日期起:
- 移除 DLL 文档;
- 此后发布的 npm 包新版本将不再带有
build目录。
详见 dll-builds 迁移指南。
官方在上述时间线之外,还维护了一个 GitHub issue 记录细节与对新安装方式的计划改进;如果你对某个时间线有顾虑,官方表示愿意讨论时间线或你需要的支持场景。
六、迁移步骤:从旧安装方式到新方式
整体顺序是:先迁移自定义插件包 → 再迁移主项目 → 最后更新框架集成包。
6.1 第一步:迁移自定义插件包
如果你以独立包的形式维护任何 CKEditor 5 自定义插件(无论是 monorepo 内还是发布到 npm),需要先迁移它们,详见 custom-plugins 迁移指南。核心改动包括:用新版 package generator 重建项目、给 ESM 导入补全文件扩展名、把包根导入统一改写为ckeditor5。
6.2 第二步:按你所用的旧方式迁移主项目
根据当前使用的旧安装方式,选择对应指南:
- 预定义构建 → Migrating from predefined builds;
- 旧版 Online Builder → Migrating from legacy Online Builder;
- 自定义构建 → Migrating from customized builds;
- DLL 构建 → Migrating from DLL builds。
无论走哪条路径,最终形态都应达到第二节示例的目标状态:只从ckeditor5/ckeditor5-premium-features导入、CSS 单独导入、翻译对象化传入、删除 CKEditor 专属的打包配置。
6.3 第三步:更新框架集成包
如果使用官方的 React、Vue 或 Angular 集成,需要一并升级:
| 集成包 | 目标版本 | 备注 |
|---|---|---|
@ckeditor/ckeditor5-react | ^8.0.0 | 该版本引入了一处小破坏性变更,需查阅该包的 CHANGELOG |
@ckeditor/ckeditor5-vue | ^6.0.0 | — |
@ckeditor/ckeditor5-angular | ^8.0.0 | — |
6.4 遇到问题时
迁移过程中如遇报错,官方在 GitHub 仓库中维护了"常见迁移错误"issue 清单供排查;若清单中没有你的问题,可新开 issue 求助。
七、小结
- 新安装方式只有两条路径:npm 包(推荐,配合任意现代打包器)与浏览器构建(
<script type="module">+ import maps,无模块环境则用 UMD 全局变量CKEDITOR); - 迁移收益是确定的:单一入口包、CSS 与 JS 分离、翻译配置化、无专属构建配置;
- 从仓库源码看,这一切由
packages/ckeditor5的聚合再导出入口、以dist为发布主入口的exports设计、以及三步式构建脚本共同支撑,并有 tests/node.js 保障导出完整性; - 旧方式时间表:预定义构建已于 2025 年 3 月 sunset,自定义构建与 DLL 支持至 2026 年 3 月——如果你的项目仍在使用这些方式,现在就是制定迁移计划的时候。
【免费下载链接】ckeditor5Powerful rich text editor framework with a modular architecture, modern integrations, and features like collaborative editing.项目地址: https://gitcode.com/GitHub_Trending/ck/ckeditor5
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考