Ckeditor5-react: How to configure it in craco.config.js

Created on 21 Jul 2020  ยท  6Comments  ยท  Source: ckeditor/ckeditor5-react

Since I'm using craco to rewrite the webpack configuration, I don't want to eject my project, so I'd like to know how to configure it in craco.

question integrations

Most helpful comment

@Mgsy Sure, but there's still a problem with localization, it doesn't work.

craco.config.js

const RawLoader = require('craco-raw-loader');
const CraCKEditorPlugin = require('./craco.ckeditor.plugin');


module.exports = {
  plugins: [
    {
      plugin: RawLoader,
      options: {
        test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/
      }
    },
    {
      plugin: CraCKEditorPlugin,
      options: {
        styleLoaderOptions: {
          injectType: 'singletonStyleTag',
          attributes: {
            'data-cke': true
          }
        },
        postcssLoaderOptions: {
          themeImporter: {
            themePath: require.resolve('@ckeditor/ckeditor5-theme-lark')
          },
          minify: true
        }
      }
    }
  ],
};

craco.ckeditor.plugin.js

const CKEditorWebpackPlugin = require('@ckeditor/ckeditor5-dev-webpack-plugin');
module.exports = {
    overrideWebpackConfig: ({ webpackConfig, pluginOptions, context: { env, paths } }) => {
        const { styles } = require('@ckeditor/ckeditor5-dev-utils');
        const {
            getLoader,
            loaderByName
        } = require("@craco/craco");

        pluginOptions = pluginOptions || {};
        const oneOfRule = webpackConfig.module.rules.find(rule => rule.oneOf);

        const postcssOptions = styles.getPostCssConfig(pluginOptions.postcssLoaderOptions || {});
        const cssExp = /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/;
        const svgExp = /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/;
        const rule = {
            test: cssExp,
            use: [
                {
                    loader: 'style-loader',
                    options: pluginOptions.styleLoaderOptions || {}
                },
                {
                    loader: 'postcss-loader',
                    options: postcssOptions
                }
            ]
        };

        const { match: fileLoaderMatch } = getLoader(
            webpackConfig,
            loaderByName("file-loader")
        );
        fileLoaderMatch.loader.exclude.push(cssExp, svgExp);

        const cssLoaders = oneOfRule.oneOf.filter((item) => item.test && !item.test.push && (item.test.test('test.css') || item.test.test('test.module.css')));
        cssLoaders.forEach(item => {
            let { exclude = [] } = item;
            if (exclude.push) {
                exclude.push(cssExp, svgExp);
            } else {
                exclude = [cssExp, svgExp, item.exclude];
            }
            item.exclude = exclude;
        })
        oneOfRule.oneOf.push(rule);


        webpackConfig.plugins.push(new CKEditorWebpackPlugin({
            language: 'zh-cn'
        }));

        return webpackConfig;
    }
}

All 6 comments

Hi, thanks for the report. We didn't test editor with _craco_, but you can find the webpack config for React integration in our docs on building from source. If you don't want to modify the webpack configuration for the editor, you can download an already built editor ( with all the plugins you need ) from Online Builder and use it right away in your React app.

@FilipTokarski Thanks, I ended up writing a craco plugin to fix it!

@LuHugo, it's great to hear that you've managed to solve your problem :)ย 

Can I ask you to post the solution here, so other users using Craco could use it?

@Mgsy Sure, but there's still a problem with localization, it doesn't work.

craco.config.js

const RawLoader = require('craco-raw-loader');
const CraCKEditorPlugin = require('./craco.ckeditor.plugin');


module.exports = {
  plugins: [
    {
      plugin: RawLoader,
      options: {
        test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/
      }
    },
    {
      plugin: CraCKEditorPlugin,
      options: {
        styleLoaderOptions: {
          injectType: 'singletonStyleTag',
          attributes: {
            'data-cke': true
          }
        },
        postcssLoaderOptions: {
          themeImporter: {
            themePath: require.resolve('@ckeditor/ckeditor5-theme-lark')
          },
          minify: true
        }
      }
    }
  ],
};

craco.ckeditor.plugin.js

const CKEditorWebpackPlugin = require('@ckeditor/ckeditor5-dev-webpack-plugin');
module.exports = {
    overrideWebpackConfig: ({ webpackConfig, pluginOptions, context: { env, paths } }) => {
        const { styles } = require('@ckeditor/ckeditor5-dev-utils');
        const {
            getLoader,
            loaderByName
        } = require("@craco/craco");

        pluginOptions = pluginOptions || {};
        const oneOfRule = webpackConfig.module.rules.find(rule => rule.oneOf);

        const postcssOptions = styles.getPostCssConfig(pluginOptions.postcssLoaderOptions || {});
        const cssExp = /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/;
        const svgExp = /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/;
        const rule = {
            test: cssExp,
            use: [
                {
                    loader: 'style-loader',
                    options: pluginOptions.styleLoaderOptions || {}
                },
                {
                    loader: 'postcss-loader',
                    options: postcssOptions
                }
            ]
        };

        const { match: fileLoaderMatch } = getLoader(
            webpackConfig,
            loaderByName("file-loader")
        );
        fileLoaderMatch.loader.exclude.push(cssExp, svgExp);

        const cssLoaders = oneOfRule.oneOf.filter((item) => item.test && !item.test.push && (item.test.test('test.css') || item.test.test('test.module.css')));
        cssLoaders.forEach(item => {
            let { exclude = [] } = item;
            if (exclude.push) {
                exclude.push(cssExp, svgExp);
            } else {
                exclude = [cssExp, svgExp, item.exclude];
            }
            item.exclude = exclude;
        })
        oneOfRule.oneOf.push(rule);


        webpackConfig.plugins.push(new CKEditorWebpackPlugin({
            language: 'zh-cn'
        }));

        return webpackConfig;
    }
}

The reason the localization doesn't work is because I didn't introduce the language js file in index.html.

This error is thrown on the console when I run the yarn start or yarn build script.

[CKEditorWebpackPlugin] Error: No JS asset has been found during the compilation. You should add translation assets directly to the application from the `translations` directory. If that was intentional use the `buildAllTranslationsToSeparateFiles` option to get rif of the error.
[CKEditorWebpackPlugin] Error: No translation has been found for the zh-cn language.

The build folder generates translations folders and language files.

build
โ”œโ”€โ”€ asset-manifest.json
โ”œโ”€โ”€ favicon.ico
โ”œโ”€โ”€ index.html
โ”œโ”€โ”€ logo192.png
โ”œโ”€โ”€ logo512.png
โ”œโ”€โ”€ manifest.json
โ”œโ”€โ”€ plugin-loader.js
โ”œโ”€โ”€ precache-manifest.61735b47c0311eeb87de97f561a66499.js
โ”œโ”€โ”€ robots.txt
โ”œโ”€โ”€ service-worker.js
โ”œโ”€โ”€ static
โ”‚   โ”œโ”€โ”€ css
โ”‚   โ”‚   โ”œโ”€โ”€ 2.87de961c.chunk.css
โ”‚   โ”‚   โ”œโ”€โ”€ 2.87de961c.chunk.css.map
โ”‚   โ”‚   โ”œโ”€โ”€ main.1708bce1.chunk.css
โ”‚   โ”‚   โ””โ”€โ”€ main.1708bce1.chunk.css.map
โ”‚   โ””โ”€โ”€ js
โ”‚       โ”œโ”€โ”€ 2.213b1e35.chunk.js
โ”‚       โ”œโ”€โ”€ 2.213b1e35.chunk.js.LICENSE.txt
โ”‚       โ”œโ”€โ”€ 2.213b1e35.chunk.js.map
โ”‚       โ”œโ”€โ”€ main.0e24e694.chunk.js
โ”‚       โ”œโ”€โ”€ main.0e24e694.chunk.js.map
โ”‚       โ”œโ”€โ”€ runtime-main.1178409c.js
โ”‚       โ””โ”€โ”€ runtime-main.1178409c.js.map
โ””โ”€โ”€ translations
    โ””โ”€โ”€ zh-cn.js

The reason the localization doesn't work is because I didn't introduce the language js file in index.html.

As I see, the problem has been solved, so I'm closing this issue.

Was this page helpful?
0 / 5 - 0 ratings