-
Notifications
You must be signed in to change notification settings - Fork 101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to integrate CKEditor5 from source in create-react-app@3+ #152
Comments
Hi, integrating CKEditor 5 with React from source is the same in create-react-app@3 as in 2, please follow integration tutorial. I just checked it and it works fine for me. As it comes to using react-app-rewired, @ma2ciek can you take a look at it? |
cc @pomek, I guess that you have a better understanding of this tool than me. |
Thanks, I integrated with react app rewired. I will have a package which rewires CRA App with CKEditor without any need of configuration soon. |
@henok-tesfaye any updates on the package? We're looking for ways to integrate without ejecting too. Thanks! |
For anyone who is trying to integrate CKEditor into their React app without ejecting We used config-overrides.js:const { addWebpackModuleRule, adjustStyleLoaders, override } = require('customize-cra');
// Use the `tap` function to output the config files for debugging.
// const { addWebpackModuleRule, adjustStyleLoaders, override, tap} = require('customize-cra');
const { styles } = require('@ckeditor/ckeditor5-dev-utils');
// These are copies of the regexes defined in CRA's Webpack config:
// eslint-disable-next-line max-len
// https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/config/webpack.config.js#L63
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const forceToArray = (value) => {
let arr = value;
// If this is not an array, but is a defined value, put it in an array.
// Otherwise, return empty array.
if (!Array.isArray(arr)) {
arr = arr ? [arr] : [];
}
return arr;
};
const adjustFileLoader = () => (config) => {
// Function that we'll call on each rule, which will modify the rule
// if it is a rule for file-loader.
const updateIfFileLoaderRule = (rule) => {
// The `loader` property contains the filepath to the loader.
if (/file-loader/.test(rule.loader)) {
console.log('customize-cra: Update exclude rules for file-loader');
rule.exclude = [
// Ensure we keep any existing exclude rules.
...forceToArray(rule.exclude),
/ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
/ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/
];
}
};
config.module.rules.forEach(rule => {
if (Array.isArray(rule.oneOf)) {
// This rule contains an array of rules, so look through each of those.
rule.oneOf.forEach(updateIfFileLoaderRule);
} else {
// This is a standalone rule.
updateIfFileLoaderRule(rule);
}
});
return config;
};
module.exports = override(
// Outputs current config to "customize-cra--before.log", with a prepended message
// tap({ dest: 'customize-cra--before.log', message: 'Before changes for CKEditor' }),
// -------------------------------------------------------------------------
// BEGIN: Webpack modifications for loading CKEditor
// -------------------------------------------------------------------------
/* eslint-disable max-len */
// These are described in detail here:
// https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/frameworks/react.html#modifying-webpack-configuration
// Helpful Medium post:
// https://medium.com/@adamerose/using-ckeditor-5-in-create-react-app-without-ejecting-cc24ffb3fd9c
/* eslint-enable max-len */
// (1) Add new rules
addWebpackModuleRule({
test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
use: ['raw-loader'],
}),
addWebpackModuleRule({
test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
use: [
{
loader: 'style-loader',
// The options are slightly different from what CKE has on their
// integration guide, b/c we have an older version of style-loader
// installed for some reason (v0.23.1, instead of v1+).
options: {
singleton: true,
attrs: {
'data-cke': true
}
}
},
{
loader: 'postcss-loader',
options: styles.getPostCssConfig({
themeImporter: {
themePath: require.resolve('@ckeditor/ckeditor5-theme-lark')
},
minify: true,
})
}
]
}),
// (2) Modify config for css loaders
adjustStyleLoaders((loader) => {
// Exclude CKE theme files from loaders that have `test: cssRegex` or
// `test: cssModuleRegex`.
if (loader.test instanceof RegExp &&
(loader.test.toString() === cssRegex.toString() ||
loader.test.toString() === cssModuleRegex.toString())
) {
console.log(`customize-cra: Update exclude rules for ${loader.test.toString()}`);
loader.exclude = [
// Ensure we keep any existing exclude rules.
...forceToArray(loader.exclude),
/ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
];
}
}),
// (3) Modify config for file loaders
adjustFileLoader()
// Outputs final config to "customize-cra--after.log", with a prepended message
// tap({ dest: 'customize-cra--after.log', message: 'After changes for CKEditor' }),
); CKEditor.js:import React from 'react';
import CKEditor from '@ckeditor/ckeditor5-react';
// NOTE: Use the editor from source (not a build)!
import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials';
import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
const editorConfiguration = {
plugins: [Essentials, Bold, Italic, Paragraph],
toolbar: ['bold', 'italic']
};
export default function CKEditorTest() {
return (
<CKEditor
editor={ClassicEditor}
config={editorConfiguration}
data="<p>Hello from CKEditor 5!</p>"
onInit={editor => {
// You can store the "editor" and use when it is needed.
console.log('Editor is ready to use!', editor);
}}
onChange={(event, editor) => {
const data = editor.getData();
console.log({ event, editor, data });
}}
onBlur={(event, editor) => {
console.log('Blur.', editor);
}}
onFocus={(event, editor) => {
console.log('Focus.', editor);
}}
/>
);
} /cc @17cliu |
Currently, it's not possible to integrate CKEditor 5 with React from the source, however, we'll be thinking about introducing a convenient way to achieve it. Please, refer to the proper issue - #170. |
@sharpar - your solution is working on my side, thanks a lot for sharing this! |
@qathom awesome! Glad it helped! 🥳 |
@sharpar Thanks, small changes to your solution and it worked. Here is the complete code const {
addWebpackModuleRule,
adjustStyleLoaders,
override,
} = require("customize-cra");
const { styles } = require("@ckeditor/ckeditor5-dev-utils");
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const forceToArray = (value) => {
let arr = value;
// If this is not an array, but is a defined value, put it in an array.
// Otherwise, return empty array.
if (!Array.isArray(arr)) {
arr = arr ? [arr] : [];
}
return arr;
};
const adjustFileLoader = () => (config) => {
// Function that we'll call on each rule, which will modify the rule
// if it is a rule for file-loader.
const updateIfFileLoaderRule = (rule) => {
// The `loader` property contains the filepath to the loader.
if (/file-loader/.test(rule.loader)) {
console.log("customize-cra: Update exclude rules for file-loader");
rule.exclude = [
// Ensure we keep any existing exclude rules.
...forceToArray(rule.exclude),
/ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
/ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
];
}
};
config.module.rules.forEach((rule) => {
if (Array.isArray(rule.oneOf)) {
// This rule contains an array of rules, so look through each of those.
rule.oneOf.forEach(updateIfFileLoaderRule);
} else {
// This is a standalone rule.
updateIfFileLoaderRule(rule);
}
});
return config;
};
module.exports = override(
// Outputs current config to "customize-cra--before.log", with a prepended message
// tap({ dest: 'customize-cra--before.log', message: 'Before changes for CKEditor' }),
// -------------------------------------------------------------------------
// BEGIN: Webpack modifications for loading CKEditor
// -------------------------------------------------------------------------
/* eslint-disable max-len */
// These are described in detail here:
// https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/frameworks/react.html#modifying-webpack-configuration
// Helpful Medium post:
// https://medium.com/@adamerose/using-ckeditor-5-in-create-react-app-without-ejecting-cc24ffb3fd9c
/* eslint-enable max-len */
// (1) Add new rules
addWebpackModuleRule({
test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
use: ["raw-loader"],
}),
addWebpackModuleRule({
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,
}),
},
},
],
}),
// (2) Modify config for css loaders
adjustStyleLoaders((loader) => {
// Exclude CKE theme files from loaders that have `test: cssRegex` or
// `test: cssModuleRegex`.
if (
loader.test instanceof RegExp &&
(loader.test.toString() === cssRegex.toString() ||
loader.test.toString() === cssModuleRegex.toString())
) {
console.log(
`customize-cra: Update exclude rules for ${loader.test.toString()}`
);
loader.exclude = [
// Ensure we keep any existing exclude rules.
...forceToArray(loader.exclude),
/ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
];
}
}),
// (3) Modify config for file loaders
adjustFileLoader()
// Outputs final config to "customize-cra--after.log", with a prepended message
// tap({ dest: 'customize-cra--after.log', message: 'After changes for CKEditor' }),
); |
@sharpar @vishalkrv |
@memsenpai did you check our tutorial? |
Any help for a project that uses |
@henok-tesfaye we also use |
I checked this doc, https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/frameworks/react.html#integrating-ckeditor-5-built-from-source, and it is for create-react-app@2+, how about for@ 3+, without ejecting the webpack, like using https://www.npmjs.com/package/react-app-rewired.
The text was updated successfully, but these errors were encountered: