René Korsgaard
René Korsgaard

Reputation: 1

Adding custom CKEditor build produces Uncaught SyntaxError: Cannot use import statement outside a module error

UPDATE

Per @jcastroa87's comment I added the ckeditor-init.js to the description and updated the ckeditor.js to better reflect what is actually in my project. I also explained how the CKEditor build was created.

I am trying to add a custom CKEditor5 to a ckeditor field in my setupCreateOperation() in laravel Backpack. I am following the guide in the documentation. It has me creating a custum CKEditor build here. In the creation process choose the HTMLEditor preset in the preset step, remove all premium plugins in the features step, leave everything default in the toolbar step, and choose technology -> vanillajs, integration method -> self hosted (npm), output -> download project. The ckeditor.js file, is the main.js file from the downloaded project.

When using this CKEditor build to my custom_builds on my ckefitor field, I get the following error in my javascript console: Uncaught SyntaxError: Cannot use import statement outside a module.

As far as I can deduce the problem stems from the fact that the javascript code which the CKEditor Builder generates includes several import statements for the plugins:

import {
    ClassicEditor,
    AccessibilityHelp,
    Autoformat,
    AutoImage,
    AutoLink,
    Autosave,
    Base64UploadAdapter,
    Bold,
    Code,
    CodeBlock,
    Essentials,
    GeneralHtmlSupport,
    Heading,
    HtmlComment,
    HtmlEmbed,
    ImageBlock,
    ImageCaption,
    ImageInline,
    ImageInsert,
    ImageInsertViaUrl,
    ImageResize,
    ImageStyle,
    ImageTextAlternative,
    ImageToolbar,
    ImageUpload,
    Italic,
    Link,
    LinkImage,
    List,
    ListProperties,
    Markdown,
    MediaEmbed,
    Paragraph,
    SelectAll,
    ShowBlocks,
    SourceEditing,
    Table,
    TableCaption,
    TableCellProperties,
    TableColumnResize,
    TableProperties,
    TableToolbar,
    TextTransformation,
    Undo
} from 'ckeditor5';

import 'ckeditor5/ckeditor5.css';

const editorConfig = {
    'language': '{{ app()->getLocale() }}',
    toolbar: {
        items: [
            'undo',
            'redo',
            '|',
            'sourceEditing',
            'showBlocks',
            '|',
            'heading',
            '|',
            'bold',
            'italic',
            'code',
            '|',
            'link',
            'insertImage',
            'mediaEmbed',
            'insertTable',
            'codeBlock',
            'htmlEmbed',
            '|',
            'bulletedList',
            'numberedList'
        ],
        shouldNotGroupWhenFull: false
    },
    plugins: [
        AccessibilityHelp,
        Autoformat,
        AutoImage,
        AutoLink,
        Autosave,
        Base64UploadAdapter,
        Bold,
        Code,
        CodeBlock,
        Essentials,
        GeneralHtmlSupport,
        Heading,
        HtmlComment,
        HtmlEmbed,
        ImageBlock,
        ImageCaption,
        ImageInline,
        ImageInsert,
        ImageInsertViaUrl,
        ImageResize,
        ImageStyle,
        ImageTextAlternative,
        ImageToolbar,
        ImageUpload,
        Italic,
        Link,
        LinkImage,
        List,
        ListProperties,
        Markdown,
        MediaEmbed,
        Paragraph,
        SelectAll,
        ShowBlocks,
        SourceEditing,
        Table,
        TableCaption,
        TableCellProperties,
        TableColumnResize,
        TableProperties,
        TableToolbar,
        TextTransformation,
        Undo
    ],
    heading: {
        options: [
            {
                model: 'paragraph',
                title: 'Paragraph',
                class: 'ck-heading_paragraph'
            },
            {
                model: 'heading1',
                view: 'h1',
                title: 'Heading 1',
                class: 'ck-heading_heading1'
            },
            {
                model: 'heading2',
                view: 'h2',
                title: 'Heading 2',
                class: 'ck-heading_heading2'
            },
            {
                model: 'heading3',
                view: 'h3',
                title: 'Heading 3',
                class: 'ck-heading_heading3'
            },
            {
                model: 'heading4',
                view: 'h4',
                title: 'Heading 4',
                class: 'ck-heading_heading4'
            },
            {
                model: 'heading5',
                view: 'h5',
                title: 'Heading 5',
                class: 'ck-heading_heading5'
            },
            {
                model: 'heading6',
                view: 'h6',
                title: 'Heading 6',
                class: 'ck-heading_heading6'
            }
        ]
    },
    htmlSupport: {
        allow: [
            {
                name: /^.*$/,
                styles: true,
                attributes: true,
                classes: true
            }
        ]
    },
    image: {
        toolbar: [
            'toggleImageCaption',
            'imageTextAlternative',
            '|',
            'imageStyle:inline',
            'imageStyle:wrapText',
            'imageStyle:breakText',
            '|',
            'resizeImage'
        ]
    },
    initialData:
        'Test',
    link: {
        addTargetToExternalLinks: true,
        defaultProtocol: 'https://',
        decorators: {
            toggleDownloadable: {
                mode: 'manual',
                label: 'Downloadable',
                attributes: {
                    download: 'file'
                }
            }
        }
    },
    list: {
        properties: {
            styles: true,
            startIndex: true,
            reversed: true
        }
    },
    placeholder: 'Type or paste your content here!',
    table: {
        contentToolbar: ['tableColumn', 'tableRow', 'mergeTableCells', 'tableProperties', 'tableCellProperties']
    }
};

The ckeditor-init.js file then looks like:

async function bpFieldInitCustomCkeditorElement(element) {
    // To create CKEditor 5 classic editor
    let ckeditorInstance = await ClassicEditor.create(element[0], editorConfig).catch(error => {
        console.error( error );
    });

    if (!ckeditorInstance) return;

    element.on('CrudField:delete', function (e) {
        ckeditorInstance.destroy();
    });

    // trigger the change event on textarea when ckeditor changes
    ckeditorInstance.editing.view.document.on('layoutChanged', function (e) {
        element.trigger('change');
    });

    element.on('CrudField:disable', function (e) {
        ckeditorInstance.enableReadOnlyMode('CrudField');
    });

    element.on('CrudField:enable', function (e) {
        ckeditorInstance.disableReadOnlyMode('CrudField');
    });
}

When adding the two files to the custom_build option for the ckeditor field, the field then calls the directives @basset(public_path('assets/js/ckeditor/ckeditor.js')) and @basset(public_path('assets/js/ckeditor/ckeditor-init.js')) in the ckeditor field blade. The directive then smartly finds that it is javascript files and adds the following scripts to the page:

<script src="http://0.0.0.0:5173/public/assets/js/ckeditor.js"></script>
<script src="http://0.0.0.0:5173/public/assets/js/ckeditor-init.js"></script>

However there are no type='module' on these script, so the error occurs.

For reference I am using CKEditor5 version 43.1.0 (installed via npm), backpack/crud version 6.7.38, and backpack/pro 2.2.17

Does anyone know if there are anyway to force a type="module" on the script tag without manipulating with laravel backpack's source files?

Upvotes: 0

Views: 53

Answers (0)

Related Questions