Issues with configuring CKEditor with Webpack

I am in the process of setting up a webpack configuration for CKEditor 5 to create a custom build. Below is my webpack.mix.js file:

const mix = require('laravel-mix');
require('laravel-mix-purgecss');


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

const webpack = require('webpack');
/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel applications. By default, we are compiling the CSS
 | file for the application as well as bundling up all the JS files.
 |
 */

mix.js('resources/js/app.js', 'public/js').vue()
        .postCss('resources/css/app.css', 'public/css', [
        require('postcss-import'),
        require('tailwindcss'),
        require('autoprefixer'),
        ])
    .webpackConfig(require('./webpack.config'));
const CKEditorWebpackPlugin = require('@ckeditor/ckeditor5-dev-webpack-plugin')
const CKEStyles = require('@ckeditor/ckeditor5-dev-utils').styles
const CKERegex = {
    svg: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
    css: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/
}

Mix.listen('configReady', webpackConfig => {
    const rules = webpackConfig.module.rules
    const targetSVG = /(\.(png|jpe?g|gif|webp)$|^((?!font).)*\.svg$)/
    const targetCSS = /\.css$/

    // exclude CKE regex from mix's default rules
    // if there's a better way to loop/change this, open to suggestions
    for (const rule of rules) {
        if (rule.test.toString() === targetSVG.toString()) {
            rule.exclude = CKERegex.svg
        } else if (rule.test.toString() === targetCSS.toString()) {
            rule.exclude = CKERegex.css
        }
    }
});

mix.webpackConfig({
    module: {
        rules: [
            {
                test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,

                use: [ 'raw-loader' ]
            },
            {
                test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.scss$/,

                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
                            } )
                        }
                    }
                ]
            }
        ]
    },
    }
);

However, despite my efforts, I am encountering the following error:

CKEditorError: svg is null Read more: is null

XML parsing error: incorrect Line 1, character 1:

I am attempting to integrate a custom CKEditor 5 build into my Vue.js and Laravel application.

Answer №1

To successfully resolve my issue, I had to make adjustments to the webpack.mix.js file and include the npm module svg-inline-loader

const CKEStyles = require('@ckeditor/ckeditor5-dev-utils').styles;

const CKERegex = {
    svg: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
    css: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/
};

Mix.listen('configReady', webpackConfig => {
    const rules = webpackConfig.module.rules;
    const targetSVG = /(\.(png|jpe?g|gif|webp|avif)$|^((?!font).)*\.svg$)/;
    const targetFont = /(\.(woff2?|ttf|eot|otf)$|font.*\.svg$)/;
    const targetCSS = /\.p?css$/;

    // Exclude CK Editor regex from mix's default rules
    for (let rule of rules) {
        if (rule.test.toString() === targetSVG.toString()) {
            rule.exclude = CKERegex.svg;
        } else if (rule.test.toString() === targetFont.toString()) {
            rule.exclude = CKERegex.svg;
        } else if (rule.test.toString() === targetCSS.toString()) {
            rule.exclude = CKERegex.css;
        }
    }
});

/**
 * Webpack Config for CK Editor
 */
mix.webpackConfig({
    module: {
        rules: [
            {
                test: CKERegex.svg,
                use: ['raw-loader']
            },
            {
                test: CKERegex.css,
                use: [
                    {
                        loader: 'postcss-loader',
                        options: {
                            postcssOptions: CKEStyles.getPostCssConfig({
                                themeImporter: {
                                    themePath: require.resolve('@ckeditor/ckeditor5-theme-lark')
                                },
                                minify: true
                            })
                        }
                    }
                ]
            }
        ]
    }
});

Prior to the mix.js(

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Sending a post request using an AngularJS service

I have implemented the following code in my application. The dataService holds all the $http requests in my app. In the controller, I am using this function to call a Web Api service which returns the correct response. However, when the function customer ...

What is the best way to create a continuous typewriter effect in Next.js?

I have a unique project that features a typewriter effect, but I'm encountering an issue where it only types the text once. What I really want is for the typewriter effect to continuously loop, starting over and typing out the words again. I've b ...

The created function in VueJS may sometimes result in an undefined outcome

I recently started a project with VueJs where I encountered an issue while making a GET request using the Axios library. The data was returned as expected, but I faced difficulties calling the loadUsers function inside mounted. Here is my code snippet: ex ...

List component in Angular not refreshing after sorting the array in the service

Currently, I am delving into the realm of Angular (version 5+) to enhance my skills by working on a small project. The project involves setting up basic routing functionalities to showcase the ContactList component upon selecting a navigation tab. Addition ...

Unable to shrink array within an object

I'm encountering an issue while trying to reduce an array within an object. The error message I receive is: push is not a function To begin, I initialized my arrays as empty and created an add function to use as the first argument: function add(a,b ...

Looking to implement comment filtering with Vue.js?

Here's what I have in my perspective: <select class="sort_by"> <option selected disabled>SORT BY</option> <option value="name" >Name</option> <option value="date">Date</option> </sel ...

Using the ng-click directive in combination with Bootstrap Rating functionality

My Bootstrap Rating component requires the use of the on-leave method to call my JavaScript function. However, I noticed that in all browsers except for IE, the on-leave function is also triggered by a click event. Strangely in IE, the function is only cal ...

ESLint detects the error "screen not found in @testing-library/vue"

When trying to utilize @testing-library/vue with the screen method imported, I encountered an error from ESLint stating: "screen not found in @testing-library/vue". // The render function doesn't give an error but screen does import { render ...

encountering an issue "Error in p5practice.js:97 - Uncaught TypeError: Unable to access property 'y' of undefined"

While working on the paddle section of my code and resolving other errors, I encountered a new issue. After fixing the previous errors, I received the following error message: "p5practice.js:97 Uncaught TypeError: Cannot read property 'y' of unde ...

Retrieve the ID of the image element using Jquery from a collection of images within a div container

I'm encountering a simple issue that I can't seem to solve. I am working on a basic slider/gallery with the following functionalities: 1) "If button 1 is clicked, image one will appear." 2) "Clicking on button 2 will make IMAGE 1 slide left and I ...

Having trouble displaying dynamically added images in my jsx-react component. The images are not showing up as expected

import React from "react"; import ReactDOM from "react-dom"; var bImg = prompt("Enter the URL of the image you want to set as the background:"); const bStyle = { backgroundImage: "url(bImg)"; // The link is stored ...

What might be the reason my $q.defer().resolve is not functioning properly?

I have noticed an interesting behavior in my code. When I define a promise in the service and return it back (promise1 in this case), it does not resolve at all. However, when I define the promise in the controller (promise2), it works perfectly fine. Why ...

Executing Javascript on Selenium RC with PHP is a crucial skill to have in your toolkit

Is there a way to execute Javascript from Selenium RC? I have been trying different methods with no success so far. I attempted the following approach: I created a custom function in user-extensions.js: function sayhello() { document.write('hel ...

Using JavaScript's document.write method to display HTML code, along with a variable retrieved from a Flash application

Can I ask two questions at once? Firstly, how can I achieve the following? document.write(' <div id="jwplayer"> <center> <div id='mediaplayer'></div> <script type="text/javascript"> jwplayer('mediapl ...

What could be the reason behind Cesium viewer's failure to show a model after I upload it?

My application features a 3D map of a city with an "Add building" button. Upon clicking this button, a model of a building should be inserted into the map. However, all I see is a selection marker at the intended location without the actual building appea ...

Efficiency boost: Implementing ajax to load content

Let's discuss the best methods for optimizing content loading with ajax. I will outline a few techniques and provide my insights on each one. Loading html directly - This method makes it easy to load content without much additional processing requir ...

A guide on parsing a stringified HTML and connecting it to the DOM along with its attributes using Angular

Looking for a solution: "<div style="text-align: center;"><b style="color: rgb(0, 0, 0); font-family: "Open Sans", Arial, sans-serif; text-align: justify;">Lorem ipsum dolor sit amet, consectetur adipiscing e ...

Unable to identify the pdf file using multer in node.js

const multer=require('multer'); var fileStorage = multer.diskStorage({ destination:(req,file,cb)=>{ if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/jpg' || file.mimetype==='image/png') { ...

Issue with converting form data to JSON format

Having an issue converting a filled form in HTML to a JSON request for sending to the server via HTTP POST. Despite having a filled form, the JSON request only shows an empty array. Here is the JavaScript snippet: $("#submitSurveyBtn").on("click", functi ...

Creating a Map in TypeScript from an Array

I have a series of TypeScript objects structured like this: interface MyObject { id: string, position: number } My goal is to transform this array into a map format where it shows the relationship between id and position, as needed for a future JSON ...