How to use CKEditor as an NPM module built with webpack or similar

The problem

As far as I can tell it isn't currently possible to load CKEDITOR directly into webpack as a chunck without getting some errors, especially when starting to load additional plugins. One of the reasons for this seems to be that ckeditor does it's own async requests at runtime causing various things to break in nearly all of the implementations I have tried.

The solution

Use scriptjs to load it as an external library.

npm install scriptjs --save

Now in your code you can call it like so:

var $s = require('scriptjs');
$s('./vendor/ckeditor/ckeditor.js', function(){
    CKEDITOR.replace('editor1');
});

Please Note.

This will not work on the uncompressed source because the ckeditor functions are not directly in the ckeditor.js file. This will cause the rest of your logic to run before the CKEDITOR object is fully constructed due to unfinished network requests.

If you wish to modify the source code of CKEDITOR clone https://github.com/ckeditor/ckeditor-dev and run it's build script to get a working customised version.

It looks like CKEditor is embracing ES6 in version 5 and I suspect they will have webpack support in this version but who knows how long it will be in development before it is released.

If there is a better way of doing this, please let me know.


It is posible to use CKEditor with Webpack, it requires that you bundle with Webpack the CKEditor files will be loading from the browser, like plugins and language files.

It is done with the require.context() api.

Create your own Webpack module and name it ckeditor_loader with the following files:

/* index.js */

import './loader.js'
import 'ckeditor/ckeditor'

// You can replace this with you own init script, e.g.:
// - jQuery(document).ready()
window.onload = function () {
  window.CKEDITOR.replaceAll()
}
/* loader.js */

window.CKEDITOR_BASEPATH = `/node_modules/ckeditor/` # This should beging with your `output.publicPath` Webpack option. 

// Load your custom config.js file for CKEditor.
require(`!file-loader?context=${__dirname}&outputPath=node_modules/ckeditor/&name=[path][name].[ext]!./config.js`)

// Load files from ckeditor.
require.context(
  '!file-loader?name=[path][name].[ext]!ckeditor/',
  true,
  /.*/
)
/* config.js */

window.CKEDITOR.editorConfig = function (config) {
  // Define changes to default configuration here.
  // For complete reference see:
  // http://docs.ckeditor.com/#!/api/CKEDITOR.config
}

Now make sure your module is loaded:

// Include in one of the javascript files that webpack
// is already processing. Probably index.js or app.js:
import 'ckeditor_loader'

This is a very basic implementation. I wrote a more extensive tutorial, which allows for faster compilation times and more customization options: How to use CKEditor 4 with Webpack


CK Editor 5 can be easily used with webpack: https://docs.ckeditor.com/ckeditor5/latest/framework/guides/quick-start.html

Although it should be noted that as of Feb 2018 it is still in alpha2: https://github.com/ckeditor/ckeditor5#packages

I was able to get started with Rails and webpacker by using the following:

yarn add \
    css-loader  \
    node-sass \
    raw-loader \
    sass-loader \
    style-loader

yarn add \
    @ckeditor/ckeditor5-editor-classic \
    @ckeditor/ckeditor5-essentials \
    @ckeditor/ckeditor5-paragraph \
    @ckeditor/ckeditor5-basic-styles

In the code I copied directly from the quick start guide:

import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor'
import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials'
import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'
import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold'
import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic'

const element = document.getElementById('editor')

ClassicEditor.create(element, {
  plugins: [Essentials, Paragraph, Bold, Italic],
  toolbar: ['bold', 'italic']
})
.then(editor => {
  console.log('Editor was initialized', editor)
})
.catch(error => {
  console.error(error.stack)
})

Finally I had to add a loader for ckeditor svg icons as per the quick start guide. I used the webpacker reference here for that https://github.com/rails/webpacker/blob/master/docs/webpack.md#react-svg-loader

// config/webpacker/environment.js
const { environment } = require('@rails/webpacker')

environment.loaders.insert('svg', {
  test: /ckeditor5-[^/]+\/theme\/icons\/[^/]+\.svg$/,
  use: 'raw-loader'
}, { after: 'file' })

const fileLoader = environment.loaders.get('file')
fileLoader.exclude = /ckeditor5-[^/]+\/theme\/icons\/[^/]+\.(svg)$/i

module.exports = environment

Install

npm install ckeditor --save

Load

require('ckeditor');

After loading chkeditor becomes available as global variable CKEDITOR

Replace

CKEDITOR.replace('elementId');

Issues

The editor loads it's own required CSS/JS assets, likely these cannot be found. You can refer to the CDN version for these resources or you can copy the CKeditor directory to an public reachable folder. Define the URL of the public reachable resources with CKEDITOR_BASEPATH.

window.CKEDITOR_BASEPATH    = '//cdn.ckeditor.com/4.6.2/full-all/';

Note: Define window.CKEDITOR_BASEPATH before your import statement!

Tags:

Ckeditor