如何在React+Vite项目中使用CKEditor 5自定义构建版本?
过去几个月我一直用Create React App构建应用,现在Ionic支持Vite了,打算把应用从CRA迁移到Vite。
我之前用CKEditor 5在线构建工具做了自定义构建版本,在React里的配置如下:
import React from 'react'; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore Ckeditor does not supply TypeScript typings. import { CKEditor } from '@ckeditor/ckeditor5-react'; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore Ckeditor does not supply TypeScript typings. import Editor from 'ckeditor5-custom-build/build/ckeditor';
构建应用前,我会先构建自定义CKEditor:
cd ckeditor5; npm run build
CKEditor的构建命令是webpack --mode production。
现在配置好Vite后,运行npm run build时出现错误:
'default' is not exported by ckeditor5/build/ckeditor.js, imported by src/components/contentTypeCard/CKEditorInput.tsx
CKEditor的问题队列里有关于Vite相关文档缺失的讨论,但没有针对这个问题的具体解决方法。
已尝试的方法
我试过用开发模式构建CKEditor(webpack --mode development),然后查看ckeditor.js文件找导出的Editor,但文件有10万多行,根本找不到头绪。
这个问题源于Vite与Webpack对ES模块的处理逻辑差异,CKEditor 5自定义构建的默认导出方式在Vite环境下不兼容,可尝试以下方案:
方案1:调整导入语法
CKEditor 5自定义构建实际导出了命名编辑器类(比如ClassicEditor,具体取决于你构建的编辑器类型),将默认导入改为命名导入即可:
// 替换原默认导入语句 import { ClassicEditor as Editor } from 'ckeditor5-custom-build/build/ckeditor';
如果你的自定义构建是其他类型(如InlineEditor、BalloonEditor),替换为对应类名即可。
方案2:配置Vite兼容处理
在vite.config.ts(或vite.config.js)中添加优化规则,让Vite正确识别CKEditor的导出结构:
import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; export default defineConfig({ plugins: [react()], optimizeDeps: { include: ['ckeditor5-custom-build/build/ckeditor'], esbuildOptions: { loader: { '.js': 'jsx', }, }, force: true // 强制Vite重新处理依赖,避免缓存问题 }, resolve: { alias: { 'ckeditor5-custom-build': './path/to/ckeditor5-custom-build' // 替换为你的CKEditor构建目录路径 } } });
方案3:修改CKEditor构建配置
若你能修改CKEditor自定义构建的webpack.config.js,可调整输出格式以适配ES模块规范:
module.exports = { // 其他原有配置... experiments: { outputModule: true }, output: { // 其他原有配置... libraryTarget: 'module' } };
修改后重新执行cd ckeditor5; npm run build构建CKEditor,再导入测试。
验证步骤
修改后先运行npm run dev确认编辑器能正常加载,无报错后再执行npm run build验证构建错误是否消失。
内容的提问来源于stack exchange,提问作者Patrick Kenny

