Contribute to this guide

guide(遗留) React 富文本编辑器组件

⚠️ 我们更改了安装方法,此遗留指南仅供用户参考。如果您正在寻找最新的 CKEditor 5 React 集成,请参阅最新版本的CKEditor 5 集成指南。

npm version

CKEditor 5 包含可立即使用的编辑器构建CKEditor 5 框架,构建基于该框架。

在 React 应用程序中使用 CKEditor 5 的最简单方法是选择一个富文本编辑器构建。此外,还可以将从源代码构建的 CKEditor 5集成到您的应用程序中。您还可以使用使用CKEditor 5 在线构建器构建的自定义编辑器在任何 React 应用程序中。

# 快速入门

本指南假设您已经有一个 React 项目。如果您想创建一个新项目,可以使用create-react-app CLI。它允许您使用模板创建和自定义您的项目。例如,您可以使用 TypeScript 支持设置您的项目。

安装适用于 React 的 CKEditor 5 所见即所得编辑器组件以及您选择的编辑器构建。假设您选择了@ckeditor/ckeditor5-build-classic

npm install --save @ckeditor/ckeditor5-react @ckeditor/ckeditor5-build-classic

在您的项目中使用<CKEditor>组件

// App.jsx / App.tsx

import React, { Component } from 'react';
import { CKEditor } from '@ckeditor/ckeditor5-react';
import ClassicEditor from '@ckeditor/ckeditor5-build-classic';

class App extends Component {
    render() {
        return (
            <div className="App">
                <h2>Using CKEditor&nbsp;5 build in React</h2>
                <CKEditor
                    editor={ ClassicEditor }
                    data="<p>Hello from CKEditor&nbsp;5!</p>"
                    onReady={ editor => {
                        // You can store the "editor" and use when it is needed.
                        console.log( 'Editor is ready to use!', editor );
                    } }
                    onChange={ ( event ) => {
                        console.log( event );
                    } }
                    onBlur={ ( event, editor ) => {
                        console.log( 'Blur.', editor );
                    } }
                    onFocus={ ( event, editor ) => {
                        console.log( 'Focus.', editor );
                    } }
                />
            </div>
        );
    }
}

export default App;

# 组件属性

<CKEditor>组件支持以下属性

  • editor(必需)– 要使用的Editor构造函数。
  • data – 创建的编辑器的初始数据。请参阅获取和设置数据指南。
  • config – 编辑器配置。请参阅配置指南。
  • id – 编辑器 ID。当此属性更改时,组件将使用新数据重新启动编辑器,而不是将其设置在已初始化的编辑器上。
  • disabled – 布尔值。如果属性设置为true,则editor将切换到只读模式。
  • disableWatchdog – 布尔值。如果设置为true,则监视器功能将被禁用。默认情况下设置为false
  • watchdogConfig监视器功能配置对象
  • onReady – 编辑器准备就绪时调用的函数,其中包含一个editor实例。如果发生错误,此回调也会在组件重新初始化后调用。
  • onChange – 编辑器数据更改时调用的函数。请参阅editor.model.document#change:data事件。
  • onBlur – 编辑器失去焦点时调用的函数。请参阅editor.editing.view.document#blur事件。
  • onFocus – 编辑器获得焦点时调用的函数。请参阅editor.editing.view.document#focus事件。
  • onError – 编辑器在初始化期间或运行时崩溃时调用的函数。它接收两个参数:错误实例和错误详细信息。
    错误详细信息是一个包含两个属性的对象
    • {String} phase: 'initialization'|'runtime' – 通知错误何时发生(在编辑器或上下文初始化期间,或初始化之后)。
    • {Boolean} willEditorRestart – 当为true时,表示编辑器组件将重新启动自身。

编辑器事件回调(onChangeonBluronFocus)接收两个参数

  1. 一个EventInfo对象。
  2. 一个Editor实例。

# 上下文功能

@ckeditor/ckeditor5-react包提供了一个上下文功能的现成组件,它在与一些CKEditor 5 协作功能一起使用时非常有用。

// This sample assumes that the application is using a CKEditor&nbsp;5 editor built from source.

import React, { Component } from 'react';
import { CKEditor, CKEditorContext } from '@ckeditor/ckeditor5-react';

import { ClassicEditor } from '@ckeditor/ckeditor5-editor-classic';
import { Context } from '@ckeditor/ckeditor5-core';
import { Bold, Italic } from '@ckeditor/ckeditor5-basic-styles';
import { Essentials } from '@ckeditor/ckeditor5-essentials';
import { Paragraph } from '@ckeditor/ckeditor5-paragraph';
import { ContextWatchdog } from '@ckeditor/ckeditor5-watchdog';

class App extends Component {
    render() {
        return (
            <div className="App">
                <CKEditorContext context={ Context } contextWatchdog={ ContextWatchdog }>
                    <h2>Using the CKEditor&nbsp;5 context feature in React</h2>
                    <CKEditor
                        editor={ ClassicEditor }
                        config={ {
                            plugins: [ Paragraph, Bold, Italic, Essentials ],
                            toolbar: [ 'bold', 'italic' ]
                        } }
                        data="<p>Hello from the first editor working with the context!</p>"
                        onReady={ editor => {
                            // You can store the "editor" and use when it is needed.
                            console.log( 'Editor1 is ready to use!', editor );
                        } }
                    />

                    <CKEditor
                        editor={ ClassicEditor }
                        config={ {
                            plugins: [ Paragraph, Bold, Italic, Essentials ],
                            toolbar: [ 'bold', 'italic' ]
                        } }
                        data="<p>Hello from the second editor working with the context!</p>"
                        onReady={ editor => {
                            // You can store the "editor" and use when it is needed.
                            console.log( 'Editor2 is ready to use!', editor );
                        } }
                    />
                </CKEditorContext>
            </div>
        );
    }
}

export default App;

# 上下文功能属性

CKEditorContext组件支持以下属性

  • context(必需)– CKEditor 5 上下文类
  • contextWatchdog(必需)– 监视器上下文类
  • config – CKEditor 5 上下文配置。
  • isLayoutReady – 当设置为false时延迟上下文创建的属性。它在为true或未设置时创建上下文和编辑器子元素。在使用 CKEditor 5 注释或存在列表时很有用。
  • id – 上下文 ID。当此属性更改时,组件将使用其编辑器重新启动上下文,并根据当前配置重新初始化它。
  • onReady – 上下文准备就绪且内部所有编辑器都使用context实例初始化时调用的函数。如果发生错误,此回调也会在组件重新初始化后调用。
  • onError – 上下文在初始化期间或运行时崩溃时调用的函数。它接收两个参数:错误实例和错误详细信息。
    错误详细信息是一个包含两个属性的对象
    • {String} phase: 'initialization'|'runtime' – 通知错误何时发生(在编辑器或上下文初始化期间,或初始化之后)。
    • {Boolean} willContextRestart – 当为true时,表示上下文组件将重新启动自身。

可以在CKEditor 5 协作示例中找到一个同时公开上下文和经典编辑器的示例构建。

# 自定义构建

CKEditor 5 构建已经可以使用,并具有一组内置插件和预定义配置。虽然您可以通过使用<CKEditor>组件的config属性轻松更改配置,这允许您更改工具栏或删除一些插件,但您需要重新构建编辑器才能添加更多插件。

主要有三种方法可以做到这一点。

# 使用 CKEditor 5 在线构建器

使用我们的专用在线构建器,只需五个简单的步骤即可创建具有自定义插件、工具栏和语言的 CKEditor 5 构建。它是一个快速、直观的工具,允许您使用自己选择的插件集自定义您的编辑体验。在集成来自在线构建器的构建部分中阅读有关此选项的更多信息。

如果您想使用CKEditor 5 在线构建器,请确保没有选择监视器功能。React 集成已经将监视器功能集成到核心。

# 自定义预定义构建之一

此选项需要对您选择的预定义构建进行更改。与在线构建器的情况类似,您需要将自定义编辑器的文件夹放在src/目录旁边,并使用yarn add file命令将其添加为依赖项。

# 从源代码集成编辑器

在这种方法中,您将包含一个从源代码构建的 CKEditor 5,因此您将选择所需的编辑器创建器以及插件列表等。它功能更强大,并能创建应用程序和所见即所得编辑器之间的更紧密集成,但是,它需要根据 CKEditor 5 的需要调整您的webpack.config.js

从源代码集成 CKEditor 5部分中详细了解此选项。

# 使用文档编辑器构建

如果您使用文档(解耦)编辑器,您需要手动将工具栏添加到 DOM

import DecoupledEditor from '@ckeditor/ckeditor5-build-decoupled-document';

class App extends Component {
    editor = null;

    render() {
        return (
            <div className="App">
                <h2>CKEditor&nbsp;5 using a custom build - decoupled editor</h2>
                <CKEditor
                    onReady={ editor => {
                        console.log( 'Editor is ready to use!', editor );

                        // Insert the toolbar before the editable area.
                        editor.ui.getEditableElement().parentElement.insertBefore(
                            editor.ui.view.toolbar.element,
                            editor.ui.getEditableElement()
                        );

                        this.editor = editor;
                    } }
                    onError={ ( error, { willEditorRestart } ) => {
                        // If the editor is restarted, the toolbar element will be created once again.
                        // The `onReady` callback will be called again and the new toolbar will be added.
                        // This is why you need to remove the older toolbar.
                        if ( willEditorRestart ) {
                            this.editor.ui.view.toolbar.element.remove();
                        }
                    } }
                    onChange={ ( event ) => console.log( event ) }
                    editor={ DecoupledEditor }
                    data="<p>Hello from CKEditor&nbsp;5's decoupled editor!</p>"
                    config={ /* the editor configuration */ }
                />
            </div>
        );
    }
}

export default App;

# 将编辑器与协作插件一起使用

在 React 应用程序中集成协作插件 的最简单方法是从源代码构建编辑器,其中包括协作插件以及 React 应用程序。

# 集成来自在线构建器的构建

本指南假设您已使用CKEditor 5 在线构建器创建了一个包含编辑器构建的 zip 存档。

包含编辑器构建的目录不能放在src/目录内,因为 Node 可能返回错误。

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

因此,我们建议将目录放在src/node_modules/文件夹旁边。

├── ckeditor5
│   ├── build
│   ├── sample
│   ├── src
│   ├── ...
│   ├── package.json
│   └── webpack.config.js
├── node_modules
├── public
├── src
├── ...
└── package.json

然后,将ckeditor5目录中的包添加为项目的依赖项。

yarn add file:./ckeditor5

现在,在您的应用程序中导入构建。

import React, { Component } from 'react';
import Editor from 'ckeditor5-custom-build/build/ckeditor';
import { CKEditor } from '@ckeditor/ckeditor5-react'

const editorConfiguration = {
    toolbar: [ 'bold', 'italic' ]
};

class App extends Component {
    render() {
        return (
            <div className="App">
                <h2>Using CKEditor&nbsp;5 from online builder in React</h2>
                <CKEditor
                    editor={ Editor }
                    config={ editorConfiguration }
                    data="<p>Hello from CKEditor&nbsp;5!</p>"
                    onReady={ editor => {
                        // You can store the "editor" and use when it is needed.
                        console.log( 'Editor is ready to use!', editor );
                    } }
                    onChange={ ( event ) => {
                        console.log( event );
                    } }
                    onBlur={ ( event, editor ) => {
                        console.log( 'Blur.', editor );
                    } }
                    onFocus={ ( event, editor ) => {
                        console.log( 'Focus.', editor );
                    } }
                />
            </div>
        );
    }
}

export default App;

# Vite

Vite 要求链接的包为 ESM,不幸的是,CKEditor 构建尚未成为 ESM(但我们正在努力)。因此,您必须修改vite.config.js文件,以将自定义构建与 Vite 集成。以下代码段将允许您在 Vite 包中包含自定义构建。查看Vite 文档,了解更多详细信息。

// vite.config.js

export default defineConfig({
  optimizeDeps: {
    include: ['@workspace/ckeditor5-custom-build'],
  },
  build: {
    commonjsOptions: {
     include: [/@workspace\/ckeditor5-custom-build/, /node_modules/],
    }
  }
})

#JavaScript heap out of memory错误

使用yarn build命令为生产构建应用程序时,可能会出现与构建机器上可用内存相关的错误。

<--- Last few GCs --->

[32550:0x110008000]    42721 ms: Scavenge (reduce) 4061.0 (4069.6) -> 4060.5 (4070.8) MB, 4.3 / 0.0 ms  (average mu = 0.358, current mu = 0.374) allocation failure
[32550:0x110008000]    42726 ms: Scavenge (reduce) 4061.2 (4069.8) -> 4060.6 (4071.3) MB, 4.0 / 0.0 ms  (average mu = 0.358, current mu = 0.374) allocation failure
[32550:0x110008000]    42730 ms: Scavenge (reduce) 4061.4 (4073.3) -> 4060.9 (4073.3) MB, 3.7 / 0.0 ms  (average mu = 0.358, current mu = 0.374) allocation failure

<--- JS stacktrace --->

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
 1: 0x1012e4da5 node::Abort() (.cold.1) [/usr/local/bin/node]

此问题尚未修复,但是,有一个解决方法。使用--max_old_space_size修饰符增加 Node.js 的可用内存应该可以解决问题。

node --max_old_space_size=4096 node_modules/.bin/react-scripts build

可以全局设置内存限制。

# Save it in the `.bash_profile` file to avoid typing it after rebooting the machine.
export NODE_OPTIONS="--max-old-space-size=4096"

yarn build

也可以按需设置,每个命令调用一次。

NODE_OPTIONS="--max-old-space-size=4096" yarn build

# 集成从源代码构建的 CKEditor 5

从源代码集成富文本编辑器允许您使用CKEditor 5 框架的全部功能。

# 创建 React 应用程序

本指南假设您使用Create React App CLI作为您的样板,并且它会逐步调整它以适应 CKEditor 5 的需要。如果您使用自定义 webpack 设置,请阅读有关包含从源代码构建的 CKEditor 5的更多信息。

需要弹出配置,以使自定义 webpack 配置成为可能。要从源代码构建 CKEditor 5,您需要告诉 webpack 如何处理 CKEditor 5 的 SVG 和 CSS 文件(通过添加加载器配置)。此外,您需要将 CKEditor 5 源代码从现有的加载器中排除。

您可以在此示例项目中查看所有描述的更改:https://github.com/ckeditor/ckeditor5-react-example/.

首先使用create-react-app@3+创建一个示例应用程序。

npx create-react-app ckeditor5-react-example

如果您想使用 TypeScript,请选择相应的模板。

npx create-react-app ckeditor5-react-example --template typescript

然后,移动到您新创建的项目。

cd ckeditor5-react-example

现在,您可以弹出配置(您可以在这里找到有关弹出的更多信息)。

yarn eject

# 安装缺少的依赖项

在开始修改 webpack 配置之前,首先安装一些您将需要的 CKEditor 5 依赖项。

yarn add \
    raw-loader@4 \
    @ckeditor/ckeditor5-dev-utils@43 \
    @ckeditor/ckeditor5-theme-lark \
    @ckeditor/ckeditor5-react \
    @ckeditor/ckeditor5-editor-classic \
    @ckeditor/ckeditor5-essentials \
    @ckeditor/ckeditor5-paragraph \
    @ckeditor/ckeditor5-basic-styles

请注意,所有包(不包括@ckeditor/ckeditor5-dev-*@ckeditor/ckeditor5-react)必须与基础编辑器包具有相同的版本。

# 修改 webpack 配置

弹出配置并安装依赖项后,您现在可以编辑 webpack 配置(config/webpack.config.js)。

首先,导入一个对象,该对象提供了一个实用程序,用于为 PostCSS 创建配置。

const { styles } = require( '@ckeditor/ckeditor5-dev-utils' );

然后,在module.rules数组(作为oneOf数组的新项目)中,将两个新元素添加到导出的对象中。这些是处理 CKEditor 5 源代码所需的 SVG 和 CSS 加载器。

{
    test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.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( {
                    themeImporter: {
                        themePath: require.resolve( '@ckeditor/ckeditor5-theme-lark' )
                    },
                    minify: true
                } )
            }
        }
    ]
},

现在,您需要将 CKEditor 5 使用的 CSS 文件从项目的 CSS 加载器中排除。

首先,找到一个加载器,其定义以以下代码开头:test: cssRegex。然后修改它。

{
    test: cssRegex,
    exclude: [
        cssModuleRegex,
        /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
    ],
    // (...)
}

在它下面,您会找到另一个处理 CSS 文件的加载器。您也需要为 CKEditor 5 CSS 禁用它。它的定义以test: cssModuleRegex开头。

{
    test: cssModuleRegex,
    exclude: [
        /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
    ],
    // (...)
}

最后,从file-loader中排除 CKEditor 5 SVG 和 CSS 文件。找到module.rules数组中的最后一项,它应该是file-loader配置,并修改它,使其看起来像这样。

{
    loader: require.resolve( 'file-loader' ),
    options: {
        // Exclude `js` files to keep the "css" loader working as it injects
        // its runtime that would otherwise be processed through the "file" loader.
        // Also exclude `html` and `json` extensions so they get processed
        // by webpack's internal loaders.
        exclude: [
            /\.(js|mjs|jsx|ts|tsx)$/,
            /\.html$/,
            /\.json$/,
            /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
            /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/
        ],
        name: 'static/media/[name].[hash:8].[ext]',
    }
}

现在,您使用create-react-app的设置已完成。您还可以查看下一节中如何配置 Vite,或者直接转到使用编辑器从源代码

# Vite

本指南假设您使用create-vite作为您的样板。要开始使用 Vite 和 React,请运行以下命令。

# npm 6.x
npm create vite@latest ckeditor5-react-example --template react

# npm7+, extra double-dash is needed:
npm create vite@latest ckeditor5-react-example -- --template react

此命令将安装并执行create-vite,这是 Vite 的官方项目脚手架工具。如果您想使用 TypeScript,请选择相应的模板。

# npm 6.x
npm create vite@latest ckeditor5-react-example --template react-ts

# npm7+, extra double-dash is needed:
npm create vite@latest ckeditor5-react-example -- --template react-ts

# 安装必要的包

除了 CKEditor 5 的基础和插件之外,您还需要安装其他包,以便从源代码使用它与 React 和 Vite:Vite 插件、官方 React 组件和默认主题。

使用 Vite 插件从源代码在 Vite 中构建 CKEditor 5 仍处于实验阶段。我们鼓励您测试它并向我们提供反馈。要详细了解与 Vite 的集成或其限制,请查看使用 Vite 从源代码集成指南。

使用以下命令安装必要的包以及默认主题。

npm install --save \
    @ckeditor/vite-plugin-ckeditor5 \
    @ckeditor/ckeditor5-react \
    @ckeditor/ckeditor5-theme-lark \
    @ckeditor/ckeditor5-editor-classic \
    @ckeditor/ckeditor5-essentials \
    @ckeditor/ckeditor5-paragraph \
    @ckeditor/ckeditor5-basic-styles

# 配置vite.config.js / vite.config.ts

使用 React 和 Vite 配置 CKEditor 5 很简单。通过导入ckeditor5并将它添加到插件列表中,修改现有配置。

// vite.config.js / vite.config.ts

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import ckeditor5 from '@ckeditor/vite-plugin-ckeditor5';

export default defineConfig( {
  plugins: [
    react(),
    ckeditor5( { theme: require.resolve( '@ckeditor/ckeditor5-theme-lark' ) } )
  ],
} )

对于 ESM 项目,配置略有不同。如果您尝试使用npm run dev命令启动开发服务器,您可能会遇到错误:require.resolve is not a function。在这种情况下,您需要一些额外的代码行。

// vite.config.js / vite.config.ts

import { createRequire } from 'node:module';
const require = createRequire( import.meta.url );

如果您想使用.ts配置,您可能需要为节点安装额外的类型。

npm install --save @types/node

# 使用编辑器从源代码

更新配置后,您可以直接从源代码使用 CKEditor 5。通过编辑src/App.jsxsrc/App.tsx来测试它。

// App.jsx / App.tsx

import React, { Component } from 'react';

import { CKEditor } from '@ckeditor/ckeditor5-react';

// NOTE: Use the editor from source (not a build)!
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';

const editorConfiguration = {
    plugins: [ Essentials, Bold, Italic, Paragraph ],
    toolbar: [ 'bold', 'italic' ]
};

class App extends Component {
    render() {
        return (
            <div className="App">
                <h2>Using CKEditor&nbsp;5 from source in React</h2>
                <CKEditor
                    editor={ ClassicEditor }
                    config={ editorConfiguration }
                    data="<p>Hello from CKEditor&nbsp;5!</p>"
                    onReady={ editor => {
                        // You can store the "editor" and use when it is needed.
                        console.log( 'Editor is ready to use!', editor );
                    } }
                    onChange={ ( event ) => {
                        console.log( event );
                    } }
                    onBlur={ ( event, editor ) => {
                        console.log( 'Blur.', editor );
                    } }
                    onFocus={ ( event, editor ) => {
                        console.log( 'Focus.', editor );
                    } }
                />
            </div>
        );
    }
}

export default App;

最后,您可以看到您的应用程序直播。根据模块捆绑器,选择相应的命令。如果您使用 webpack,请运行。

yarn start

如果您使用 Vite,请运行。

npm run dev

您可以在高级设置指南中阅读有关从源代码使用 CKEditor 5 的更多信息。

# 本地化

CKEditor 5 支持多种 UI 语言,官方 React 组件也是如此。请按照以下说明在您的 React 应用程序中翻译 CKEditor 5。

# 预定义构建

使用预定义构建之一或在线构建器构建的编辑器时,您需要先导入翻译。

官方编辑器构建

import ClassicEditor from '@ckeditor/ckeditor5-build-classic';

// Import translations for the German language.
import '@ckeditor/ckeditor5-build-classic/build/translations/de';

// ...

来自在线构建器的编辑器构建

import Editor from 'ckeditor5-custom-build/build/ckeditor';

// Import translations for the German language.
import 'ckeditor5-custom-build/build/translations/de';

然后,在组件中配置编辑器的语言。

<CKEditor
    config={ {
        // Use the German language for this editor.
        language: 'de',

        // ...
    } }
    editor={ ClassicEditor }
    data="<p>Hello from CKEditor&nbsp;5!</p>"
/>

有关更多信息,请参考设置 UI 语言指南。

# 从源代码构建的 CKEditor 5

使用从源代码构建的编辑器需要您修改 webpack 配置。首先,安装官方翻译 webpack 插件,该插件允许本地化编辑器构建。

yarn add @ckeditor/ckeditor5-dev-translations --dev

然后,将安装的插件添加到 webpack 配置中。

// webpack.config.js
'use strict';

// ...
const { CKEditorTranslationsPlugin } = require( '@ckeditor/ckeditor5-dev-translations' );

module.exports = {
    // ...

    plugins: [
        // ....

        new CKEditorTranslationsPlugin( {
            // The UI language. Language codes follow the https://en.wikipedia.org/wiki/ISO_639-1 format.
            language: 'de',
            addMainLanguageTranslationsToAllAssets: true
        } ),

        // ....
    ],

    // ...
};

构建应用程序后,CKEditor 5 将以翻译成指定语言的 UI 运行。

有关更多信息,请参考设置 UI 语言指南。

# 贡献和报告问题

React 的富文本编辑器组件的源代码在 GitHub 上的https://github.com/ckeditor/ckeditor5-react中提供。