☰
CKEditor 4 插件加载配置详解:plugins / extraPlugins / removePlugins 的数组与字符串两种写法
2026/10/15 2:12:26 网站建设 项目流程
  • 前端
  • UI组件

【免费下载链接】ckeditor4

The best enterprise-grade WYSIWYG editor. Fully customizable with countless features and plugins.

项目地址:https://gitcode.com/gh_mirrors/ck/ckeditor4
点击查看免费下载

本文以仓库内手动测试用例 tests/core/config/manual/pluginsarray.md(对应功能编号 #1802,随 CKEditor 4.10.0 引入)为骨架,系统讲解 CKEditor 4 中控制插件加载的三个核心配置项plugins、extraPlugins、removePlugins:它们各自的作用、字符串与数组两种写法的等价性、底层解析与合并逻辑,以及配套的自动化测试验证。读完本文,你将能够精确控制任意编辑器实例加载的插件集合,并理解"数组写法"与"逗号分隔字符串写法"在源码层面是如何被统一处理的。

一、三个配置项的角色分工

在 CKEditor 4 中,每个编辑器实例实际加载哪些插件,由editor.config中三个配置项共同决定:

配置项类型作用默认值
pluginsString/String[]指定实例要使用的插件列表,整体替换默认插件集合''(构建时替换为默认插件列表,见 core/config.js)
extraPluginsString/String[]在plugins基础上追加额外插件,无需改动plugins原值''(core/config.js)
removePluginsString/String[]从plugins中剔除不需要的插件''(core/config.js)

这三个配置项在官方 API 文档中均声明为String/String[]双类型。传统用法是逗号分隔字符串,例如:

config.plugins = 'wysiwygarea,toolbar,basicstyles'; config.extraPlugins = 'myplugin,anotherplugin'; config.removePlugins = 'elementspath,save,font';

而从 4.10.0 开始(issue #1802),三者同样接受数组写法,例如:

config.plugins = [ 'wysiwygarea', 'toolbar', 'basicstyles' ]; config.extraPlugins = [ 'myplugin', 'anotherplugin' ]; config.removePlugins = [ 'elementspath', 'save', 'font' ];

两种写法在功能上完全等价,手动测试文档 tests/core/config/manual/pluginsarray.md 正是专门用来验证数组写法下各编辑器实际加载的插件集合是否符合预期。

二、手动测试场景还原:数组写法的三种用法

配套测试页 tests/core/config/manual/pluginsarray.html 在同一页面创建了三个编辑器实例,逐一演示三个配置项使用数组写法时的效果。

测试页首先定义了一个公共配置commonConfig,其中plugins为字符串'wysiwygarea,toolbar',并在instanceReady事件中将实例实际加载的插件名写入编辑器内容,方便人工核对:

var commonConfig = { plugins: 'wysiwygarea,toolbar', on: { instanceReady: function() { this.setData( '<p>I have following plugins loaded: ' + CKEDITOR.tools.object.keys( this.plugins ) + '</p>' ); } } };

注意这里通过CKEDITOR.tools.object.keys( this.plugins )获取编辑器实例上已加载插件的键名集合——editor.plugins在插件加载完成后会包含所有已加载的插件对象(见 core/editor.js)。

1.plugins数组:整体替换插件列表

CKEDITOR.replace( 'plugins', CKEDITOR.tools.extend( { plugins: [ 'wysiwygarea', 'toolbar', 'button' ] }, commonConfig, false ) );

该实例的plugins被数组整体覆盖为wysiwygarea、toolbar、button。文档 tests/core/config/manual/pluginsarray.md 中列出的预期结果为:

  • wysiwygarea
  • toolbar
  • button

2.extraPlugins数组:追加插件

CKEDITOR.replace( 'extraPlugins', CKEDITOR.tools.extend( { extraPlugins: [ 'button', 'blockquote' ] }, commonConfig ) );

该实例继承了公共配置plugins: 'wysiwygarea,toolbar',再通过数组extraPlugins: [ 'button', 'blockquote' ]追加两个插件,预期加载结果为:

  • wysiwygarea
  • toolbar
  • button
  • blockquote

3.removePlugins数组:剔除插件

CKEDITOR.replace( 'removePlugins', CKEDITOR.tools.extend( { removePlugins: [ 'image', 'toolbar' ] }, commonConfig ) );

该实例同样继承plugins: 'wysiwygarea,toolbar',再通过数组removePlugins: [ 'image', 'toolbar' ]剔除(其中image本就不在列表中,属冗余剔除),最终只剩:

  • wysiwygarea

手动验证流程

按文档 tests/core/config/manual/pluginsarray.md 的描述,测试步骤为:

  1. 打开测试页,检查每个编辑器中列出的已加载插件是否与上文各列表一致;
  2. 预期(Expected):所有列出的插件均已加载,与各列表完全一致;
  3. 非预期(Unexpected):实际加载的插件与列表不一致。

该文档以@bender-tags: feature, 4.10.0, 1802标注,属于 Bender 手动测试(manual test),由人工在浏览器中核对运行结果。

三、源码原理:数组如何在加载管线中被统一为字符串

数组写法之所以能与字符串写法等价,关键在于 core/editor.js 中的parsePluginsOption解析函数:

// Parse *plugins option into a string (#1802). function parsePluginsOption( option ) { if ( !option ) { return ''; } if ( CKEDITOR.tools.isArray( option ) ) { option = option.join( ',' ); } // We have to remove whitespaces (#1712). return option.replace( /\s/g, '' ); }

该函数在loadPlugins(core/editor.js)中被统一调用,对三个配置项做同样的预处理:

function loadPlugins( editor ) { var config = editor.config, plugins = parsePluginsOption( config.plugins ), extraPlugins = parsePluginsOption( config.extraPlugins ), removePlugins = parsePluginsOption( config.removePlugins ); if ( extraPlugins ) { // Remove them first to avoid duplications. var extraRegex = new RegExp( '(?:^|,)(?:' + extraPlugins.replace( /,/g, '|' ) + ')(?=,|$)', 'g' ); plugins = plugins.replace( extraRegex, '' ); plugins += ',' + extraPlugins; } if ( removePlugins ) { var removeRegex = new RegExp( '(?:^|,)(?:' + removePlugins.replace( /,/g, '|' ) + ')(?=,|$)', 'g' ); plugins = plugins.replace( removeRegex, '' ); } // Load the Adobe AIR plugin conditionally. CKEDITOR.env.air && ( plugins += ',adobeair' ); // Load all plugins defined in the "plugins" setting. CKEDITOR.plugins.load( plugins.split( ',' ), function( plugins ) { // ... } ); }

从源码可以梳理出插件列表的最终合并顺序:

  1. 解析归一:三个配置项经parsePluginsOption统一转为无空白的逗号分隔字符串(数组join(','),空值返回'');
  2. 合并extraPlugins:先通过正则将extraPlugins中已有的插件从plugins里剔除(避免重复),再整体追加到plugins末尾;
  3. 应用removePlugins:通过正则把要移除的插件从合并后的列表里删除;
  4. 环境插件追加:在 Adobe AIR 环境下条件性追加adobeair;
  5. 真正加载:将最终字符串split(',')后交给CKEDITOR.plugins.load()异步加载。

由此可见,数组写法并非另起炉灶,而是在进入加载管线前被join(',')归一为传统字符串,因此两种写法在任何行为细节上(包括去重、剔除、空值处理)都完全一致。

四、重要边界:被依赖插件不可移除

removePlugins并非可以任意使用。官方配置文档在 core/config.js 中明确说明:

A plugin required by another plugin cannot be removed and will cause an error to be thrown. So for example ifcontextmenuis required bytabletools, it can only be removed iftabletoolsis not loaded.

也就是说,若某个已加载插件声明requires了被移除的插件,加载过程会抛出错误。对应实现位于 core/editor.js:加载循环中会检查每个插件的requires(数组会被join(',')转成字符串),若与removeRegex匹配,则通过CKEDITOR.error( 'editor-plugin-required', ... )抛出非阻塞错误。

在手动测试页中,removePlugins: [ 'image', 'toolbar' ]之所以能安全移除toolbar,是因为其余已加载插件(wysiwygarea)并不依赖它;实际项目中若同时加载了依赖被移除插件的功能插件,就会触发该错误。

五、自动化测试佐证

除手动测试外,仓库还提供了完整的自动化测试 tests/core/config/plugins.js,覆盖了数组写法及各种边界情况:

  • 数组写法(#1802):test extraPlugins allows array、test plugins allows array、test removePlugins allows array三个用例,分别验证三个配置项传入数组后,editor.plugins中实际包含/不包含对应插件;
  • 空白容忍(#1712):test plugins allows whitespaces、test extraPlugins allows whitespaces、test removePlugins allows whitespaces,验证'basicstyles, image2, toolbar '这类带空格字符串能被正确解析(对应parsePluginsOption中的replace( /\s/g, '' ));
  • 空值容忍:"test plugins doesn't throw with undefined"验证三个配置项传undefined时不会抛异常(对应parsePluginsOption开头的if ( !option ) return '';)。

这些用例也印证了手动测试页中"三个编辑器各自加载的插件集合互不相同"的预期:plugins决定基础集合,extraPlugins做加法,removePlugins做减法,三者叠加后的最终集合即为 tests/core/config/manual/pluginsarray.md 中列出的三份清单。

六、实践建议

结合文档与源码,在实际项目中使用这三个配置项时,可遵循以下经验:

  1. 字符串与数组任选:二者完全等价(源码层面数组会被join(',')归一),团队约定一种风格即可;数组写法在动态生成插件列表(如由程序拼接)时更不易出错。
  2. 善用extraPlugins而非改写plugins:追加第三方或业务插件时,优先使用extraPlugins,避免因复制默认插件列表而遗漏必要插件(如wysiwygarea、toolbar),这也是 core/config.js 中该配置项的设计初衷。
  3. removePlugins谨慎剔除:剔除前确认目标插件不被任何仍将加载的插件requires,否则会触发editor-plugin-required错误。
  4. 调试利器:可在instanceReady事件中通过CKEDITOR.tools.object.keys( editor.plugins )打印实例实际加载的插件列表,与预期清单比对——这正是手动测试页 tests/core/config/manual/pluginsarray.html 的做法,也是排查"按钮消失""功能不可用"等常见问题的最快途径。
  • 前端
  • UI组件

【免费下载链接】ckeditor4

The best enterprise-grade WYSIWYG editor. Fully customizable with countless features and plugins.

项目地址:https://gitcode.com/gh_mirrors/ck/ckeditor4
点击查看免费下载

相关推荐

上一篇:3分钟上手Omarchy:LazyVim插件管理新范式
下一篇:告别寻路难题:ET框架AI路径规划实战指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询