Angular 13 Ckeditor5自定义插件pluginCollection-plugin-non-not-found

发布于 2025-02-09 23:27:34 字数 11257 浏览 1 评论 0原文

我在Angular应用程序中使用CKEditor5。我已经生成了自定义构建,并保存了ckeditor.js在我的项目dir中。一切都很好。我可以通过将此行添加到顶部来渲染编辑器并在角度组件中使用它:import *作为'src/ckcustombuild/ckeditor'的custombuild';

现在我正在浏览他们的样本“占位符”插件的文档,我似乎无法使其在Angular中使用。我在与ckeditor.js的同一文件夹中添加了一个名为lugin.js的新文件中的相同代码。

然后,我还将其导入我的组件,并按照以下方式构造配置:

import * as customBuild from 'src/ckCustomBuild/ckeditor';
import * as Placeholder from 'src/ckCustomBuild/placeholder.plugin';

...component boilerplate code....
  htmlEditorConfig = {
    plugins: [Placeholder],
    toolbar: {
      items: ['bold', 'italic', 'underline', 'link', 'alignment', 'bulletedList', 'numberedList', '|', 'fontFamily', 'fontSize', 'fontColor', 'fontBackgroundColor', '|', 'Paceholder'],
      shouldNotGroupWhenFull: false,
    },
    // placeholderConfig: {
    //   types: ['date', 'color', 'first name', 'surname'],
    // },
    fontSize: {
      options: [9, 11, 13, 'default', 17, 19, 21],
    },
    mediaEmbed: {
      previewsInData: true,
    },
  };

当我运行应用程序时,我会收到以下运行时错误:

    core.mjs:6494 ERROR Error: Uncaught (in promise): CKEditorError: plugincollection-plugin-not-found {"plugin":{}}
    Read more: https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/error-codes.html#error-plugincollection-plugin-not-found
    CKEditorError: plugincollection-plugin-not-found {"plugin":{}}
    Read more: https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/error-codes.html#error-plugincollection-plugin-not-found
        at p (ckeditor.js:5:432588)
        at ckeditor.js:5:432433
        at Array.forEach (<anonymous>)
        at f (ckeditor.js:5:432420)
        at wa.init (ckeditor.js:5:431516)
        at bq.initPlugins (ckeditor.js:5:703694)
        at ckeditor.js:5:831531
        at new ZoneAwarePromise (zone.js:1351:1)
        at bq.create (ckeditor.js:5:831488)
        at CKEditorComponent.<anonymous> (ckeditor-ckeditor5-angular.js:235:1)
        at resolvePromise (zone.js:1262:1)
        at resolvePromise (zone.js:1216:1)
        at zone.js:1329:1
        at push.46026._ZoneDelegate.invokeTask (zone.js:443:1)
        at Object.onInvokeTask (core.mjs:25595:1)
        at push.46026._ZoneDelegate.invokeTask (zone.js:442:1)
        at push.46026.Zone.runTask (zone.js:214:1)
        at drainMicroTaskQueue (zone.js:632:1)
        at push.46026.ZoneTask.invokeTask [as invoke] (zone.js:529:1)
        at invokeTask (zone.js:1727:1)

这是我的两个文件的内容: 占位符。plugin.js

import * as Plugin from 'src/ckCustomBuild/ckeditor';
import * as Widget from 'src/ckCustomBuild/ckeditor';
import * as Command from 'src/ckCustomBuild/ckeditor';
import * as Collection from 'src/ckCustomBuild/ckeditor';
import * as Model from 'src/ckCustomBuild/ckeditor';
import * as toWidget from 'src/ckCustomBuild/ckeditor';
import * as viewToModelPositionOutsideModelElement from 'src/ckCustomBuild/ckeditor';
import * as addListToDropdown from 'src/ckCustomBuild/ckeditor';
import * as createDropdown from 'src/ckCustomBuild/ckeditor';

 class Placeholder extends Plugin {
  static get requires() {
    return [PlaceholderEditing, PlaceholderUI];
  }
}

class PlaceholderCommand extends Command {
  execute({ value }) {
    const editor = this.editor;
    const selection = editor.model.document.selection;

    editor.model.change((writer) => {
      // Create a <placeholder> elment with the "name" attribute (and all the selection attributes)...
      const placeholder = writer.createElement('placeholder', {
        ...Object.fromEntries(selection.getAttributes()),
        name: value,
      });

      // ... and insert it into the document.
      editor.model.insertContent(placeholder);

      // Put the selection on the inserted element.
      writer.setSelection(placeholder, 'on');
    });
  }

  refresh() {
    const model = this.editor.model;
    const selection = model.document.selection;

    const isAllowed = model.schema.checkChild(selection.focus.parent, 'placeholder');

    this.isEnabled = isAllowed;
  }
}

class PlaceholderUI extends Plugin {
  init() {
    const editor = this.editor;
    const t = editor.t;
    const placeholderNames = editor.config.get('placeholderConfig.types');

    // The "placeholder" dropdown must be registered among the UI components of the editor
    // to be displayed in the toolbar.
    editor.ui.componentFactory.add('placeholder', (locale) => {
      const dropdownView = createDropdown(locale);

      // Populate the list in the dropdown with items.
      addListToDropdown(dropdownView, getDropdownItemsDefinitions(placeholderNames));

      dropdownView.buttonView.set({
        // The t() function helps localize the editor. All strings enclosed in t() can be
        // translated and change when the language of the editor changes.
        label: t('Placeholder'),
        tooltip: true,
        withText: true,
      });

      // Disable the placeholder button when the command is disabled.
      const command = editor.commands.get('placeholder');
      dropdownView.bind('isEnabled').to(command);

      // Execute the command when the dropdown item is clicked (executed).
      this.listenTo(dropdownView, 'execute', (evt) => {
        editor.execute('placeholder', { value: evt.source.commandParam });
        editor.editing.view.focus();
      });

      return dropdownView;
    });
  }
}

function getDropdownItemsDefinitions(placeholderNames) {
  const itemDefinitions = new Collection();

  for (const name of placeholderNames) {
    const definition = {
      type: 'button',
      model: new Model({
        commandParam: name,
        label: name,
        withText: true,
      }),
    };

    // Add the item definition to the collection.
    itemDefinitions.add(definition);
  }

  return itemDefinitions;
}

class PlaceholderEditing extends Plugin {
  static get requires() {
    return [Widget];
  }

  init() {
    console.log('PlaceholderEditing#init() got called');

    this._defineSchema();
    this._defineConverters();

    this.editor.commands.add('placeholder', new PlaceholderCommand(this.editor));

    this.editor.editing.mapper.on(
      'viewToModelPosition',
      viewToModelPositionOutsideModelElement(this.editor.model, (viewElement) => viewElement.hasClass('placeholder'))
    );
    this.editor.config.define('placeholderConfig', {
      types: ['date', 'first name', 'surname'],
    });
  }

  _defineSchema() {
    const schema = this.editor.model.schema;

    schema.register('placeholder', {
      // Allow wherever text is allowed:
      allowWhere: '$text',

      // The placeholder will act as an inline node:
      isInline: true,

      // The inline widget is self-contained so it cannot be split by the caret and it can be selected:
      isObject: true,

      // The inline widget can have the same attributes as text (for example linkHref, bold).
      allowAttributesOf: '$text',

      // The placeholder can have many types, like date, name, surname, etc:
      allowAttributes: ['name'],
    });
  }

  _defineConverters() {
    const conversion = this.editor.conversion;

    conversion.for('upcast').elementToElement({
      view: {
        name: 'span',
        classes: ['placeholder'],
      },
      model: (viewElement, { writer: modelWriter }) => {
        // Extract the "name" from "{name}".
        const name = viewElement.getChild(0).data.slice(1, -1);

        return modelWriter.createElement('placeholder', { name });
      },
    });

    conversion.for('editingDowncast').elementToElement({
      model: 'placeholder',
      view: (modelItem, { writer: viewWriter }) => {
        const widgetElement = createPlaceholderView(modelItem, viewWriter);

        // Enable widget handling on a placeholder element inside the editing view.
        return toWidget(widgetElement, viewWriter);
      },
    });

    conversion.for('dataDowncast').elementToElement({
      model: 'placeholder',
      view: (modelItem, { writer: viewWriter }) => createPlaceholderView(modelItem, viewWriter),
    });

    // Helper method for both downcast converters.
    function createPlaceholderView(modelItem, viewWriter) {
      const name = modelItem.getAttribute('name');

      const placeholderView = viewWriter.createContainerElement('span', {
        class: 'placeholder',
      });

      // Insert the placeholder name (as a text).
      const innerText = viewWriter.createText('{' + name + '}');
      viewWriter.insert(viewWriter.createPositionAt(placeholderView, 0), innerText);

      return placeholderView;
    }
  }
}

component.ts

import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { CKEditorUploadAdapter } from 'src/app/_helpers/ckeditor-upload-adapter';
import { ConferenceViewModelWithDetails, PaperAcknowledgementViewModel, PaperConfigurationViewModel } from 'src/app/_models/generatedModels';
import { AuthenticationService } from 'src/app/_services/authentication.service';
import { AdminCallForPapersService, OrganizationService } from 'src/app/_services/generatedServices';
import { ToasterService } from 'src/app/_services/toaster.service';
import * as customBuild from 'src/ckCustomBuild/ckeditor';
//import * as Placeholder from 'src/ckCustomBuild/ckeditor';
import * as Placeholder from 'src/ckCustomBuild/placeholder.plugin';


@Component({
  selector: 'bxl-abstract-management-configuration',
  templateUrl: 'abstract-management-configuration.component.html',
})
export class AbstractManagementConfigurationComponent implements OnInit {
  initialized = false;
  public Editor = customBuild;
  htmlEditorConfig = {
    plugins: [Placeholder],
    toolbar: {
      items: ['bold', 'italic', 'underline', 'link', 'alignment', 'bulletedList', 'numberedList', '|', 'fontFamily', 'fontSize', 'fontColor', 'fontBackgroundColor', '|', 'Paceholder'],
      shouldNotGroupWhenFull: false,
    },
    // placeholderConfig: {
    //   types: ['date', 'color', 'first name', 'surname'],
    // },
    fontSize: {
      options: [9, 11, 13, 'default', 17, 19, 21],
    },
    mediaEmbed: {
      previewsInData: true,
    },
  };
  organizationId: string;
  conferenceId: any;
  configuration: PaperConfigurationViewModel;

  constructor(private auth: AuthenticationService, private orgService: OrganizationService, private router: Router, private route: ActivatedRoute, private cfpService: AdminCallForPapersService, private toaster: ToasterService) {}

  ngOnInit(): void {
    this.route.paramMap.subscribe((params) => {
      this.organizationId = params.get('organizationId');
      this.conferenceId = params.get('conferenceId');

      this.cfpService.getPaperConfiguration(this.organizationId, this.conferenceId).subscribe((result) => {
        this.configuration = result;
        this.initialized = true;
      });
    });
  }

I am using CKEditor5 within my angular application. I have generated a custom build and saved the ckeditor.js file in my project dir. Everything works fine. I am able to render the editor and use it without issue in an angular component by adding this line to the top: import * as customBuild from 'src/ckCustomBuild/ckeditor';

Now I am going through the documentation for their sample "placeholder" plugin and I can't seem to get it to work in angular. I've added the same code from their site to a new file called placeholder.plugin.js in the same folder as ckeditor.js above.

I then import it into my component also, and structure the config as follows:

import * as customBuild from 'src/ckCustomBuild/ckeditor';
import * as Placeholder from 'src/ckCustomBuild/placeholder.plugin';

...component boilerplate code....
  htmlEditorConfig = {
    plugins: [Placeholder],
    toolbar: {
      items: ['bold', 'italic', 'underline', 'link', 'alignment', 'bulletedList', 'numberedList', '|', 'fontFamily', 'fontSize', 'fontColor', 'fontBackgroundColor', '|', 'Paceholder'],
      shouldNotGroupWhenFull: false,
    },
    // placeholderConfig: {
    //   types: ['date', 'color', 'first name', 'surname'],
    // },
    fontSize: {
      options: [9, 11, 13, 'default', 17, 19, 21],
    },
    mediaEmbed: {
      previewsInData: true,
    },
  };

When I go to run the application, I get the following runtime error:

    core.mjs:6494 ERROR Error: Uncaught (in promise): CKEditorError: plugincollection-plugin-not-found {"plugin":{}}
    Read more: https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/error-codes.html#error-plugincollection-plugin-not-found
    CKEditorError: plugincollection-plugin-not-found {"plugin":{}}
    Read more: https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/error-codes.html#error-plugincollection-plugin-not-found
        at p (ckeditor.js:5:432588)
        at ckeditor.js:5:432433
        at Array.forEach (<anonymous>)
        at f (ckeditor.js:5:432420)
        at wa.init (ckeditor.js:5:431516)
        at bq.initPlugins (ckeditor.js:5:703694)
        at ckeditor.js:5:831531
        at new ZoneAwarePromise (zone.js:1351:1)
        at bq.create (ckeditor.js:5:831488)
        at CKEditorComponent.<anonymous> (ckeditor-ckeditor5-angular.js:235:1)
        at resolvePromise (zone.js:1262:1)
        at resolvePromise (zone.js:1216:1)
        at zone.js:1329:1
        at push.46026._ZoneDelegate.invokeTask (zone.js:443:1)
        at Object.onInvokeTask (core.mjs:25595:1)
        at push.46026._ZoneDelegate.invokeTask (zone.js:442:1)
        at push.46026.Zone.runTask (zone.js:214:1)
        at drainMicroTaskQueue (zone.js:632:1)
        at push.46026.ZoneTask.invokeTask [as invoke] (zone.js:529:1)
        at invokeTask (zone.js:1727:1)

Here is the contents of my 2 files:
placeholder.plugin.js

import * as Plugin from 'src/ckCustomBuild/ckeditor';
import * as Widget from 'src/ckCustomBuild/ckeditor';
import * as Command from 'src/ckCustomBuild/ckeditor';
import * as Collection from 'src/ckCustomBuild/ckeditor';
import * as Model from 'src/ckCustomBuild/ckeditor';
import * as toWidget from 'src/ckCustomBuild/ckeditor';
import * as viewToModelPositionOutsideModelElement from 'src/ckCustomBuild/ckeditor';
import * as addListToDropdown from 'src/ckCustomBuild/ckeditor';
import * as createDropdown from 'src/ckCustomBuild/ckeditor';

 class Placeholder extends Plugin {
  static get requires() {
    return [PlaceholderEditing, PlaceholderUI];
  }
}

class PlaceholderCommand extends Command {
  execute({ value }) {
    const editor = this.editor;
    const selection = editor.model.document.selection;

    editor.model.change((writer) => {
      // Create a <placeholder> elment with the "name" attribute (and all the selection attributes)...
      const placeholder = writer.createElement('placeholder', {
        ...Object.fromEntries(selection.getAttributes()),
        name: value,
      });

      // ... and insert it into the document.
      editor.model.insertContent(placeholder);

      // Put the selection on the inserted element.
      writer.setSelection(placeholder, 'on');
    });
  }

  refresh() {
    const model = this.editor.model;
    const selection = model.document.selection;

    const isAllowed = model.schema.checkChild(selection.focus.parent, 'placeholder');

    this.isEnabled = isAllowed;
  }
}

class PlaceholderUI extends Plugin {
  init() {
    const editor = this.editor;
    const t = editor.t;
    const placeholderNames = editor.config.get('placeholderConfig.types');

    // The "placeholder" dropdown must be registered among the UI components of the editor
    // to be displayed in the toolbar.
    editor.ui.componentFactory.add('placeholder', (locale) => {
      const dropdownView = createDropdown(locale);

      // Populate the list in the dropdown with items.
      addListToDropdown(dropdownView, getDropdownItemsDefinitions(placeholderNames));

      dropdownView.buttonView.set({
        // The t() function helps localize the editor. All strings enclosed in t() can be
        // translated and change when the language of the editor changes.
        label: t('Placeholder'),
        tooltip: true,
        withText: true,
      });

      // Disable the placeholder button when the command is disabled.
      const command = editor.commands.get('placeholder');
      dropdownView.bind('isEnabled').to(command);

      // Execute the command when the dropdown item is clicked (executed).
      this.listenTo(dropdownView, 'execute', (evt) => {
        editor.execute('placeholder', { value: evt.source.commandParam });
        editor.editing.view.focus();
      });

      return dropdownView;
    });
  }
}

function getDropdownItemsDefinitions(placeholderNames) {
  const itemDefinitions = new Collection();

  for (const name of placeholderNames) {
    const definition = {
      type: 'button',
      model: new Model({
        commandParam: name,
        label: name,
        withText: true,
      }),
    };

    // Add the item definition to the collection.
    itemDefinitions.add(definition);
  }

  return itemDefinitions;
}

class PlaceholderEditing extends Plugin {
  static get requires() {
    return [Widget];
  }

  init() {
    console.log('PlaceholderEditing#init() got called');

    this._defineSchema();
    this._defineConverters();

    this.editor.commands.add('placeholder', new PlaceholderCommand(this.editor));

    this.editor.editing.mapper.on(
      'viewToModelPosition',
      viewToModelPositionOutsideModelElement(this.editor.model, (viewElement) => viewElement.hasClass('placeholder'))
    );
    this.editor.config.define('placeholderConfig', {
      types: ['date', 'first name', 'surname'],
    });
  }

  _defineSchema() {
    const schema = this.editor.model.schema;

    schema.register('placeholder', {
      // Allow wherever text is allowed:
      allowWhere: '$text',

      // The placeholder will act as an inline node:
      isInline: true,

      // The inline widget is self-contained so it cannot be split by the caret and it can be selected:
      isObject: true,

      // The inline widget can have the same attributes as text (for example linkHref, bold).
      allowAttributesOf: '$text',

      // The placeholder can have many types, like date, name, surname, etc:
      allowAttributes: ['name'],
    });
  }

  _defineConverters() {
    const conversion = this.editor.conversion;

    conversion.for('upcast').elementToElement({
      view: {
        name: 'span',
        classes: ['placeholder'],
      },
      model: (viewElement, { writer: modelWriter }) => {
        // Extract the "name" from "{name}".
        const name = viewElement.getChild(0).data.slice(1, -1);

        return modelWriter.createElement('placeholder', { name });
      },
    });

    conversion.for('editingDowncast').elementToElement({
      model: 'placeholder',
      view: (modelItem, { writer: viewWriter }) => {
        const widgetElement = createPlaceholderView(modelItem, viewWriter);

        // Enable widget handling on a placeholder element inside the editing view.
        return toWidget(widgetElement, viewWriter);
      },
    });

    conversion.for('dataDowncast').elementToElement({
      model: 'placeholder',
      view: (modelItem, { writer: viewWriter }) => createPlaceholderView(modelItem, viewWriter),
    });

    // Helper method for both downcast converters.
    function createPlaceholderView(modelItem, viewWriter) {
      const name = modelItem.getAttribute('name');

      const placeholderView = viewWriter.createContainerElement('span', {
        class: 'placeholder',
      });

      // Insert the placeholder name (as a text).
      const innerText = viewWriter.createText('{' + name + '}');
      viewWriter.insert(viewWriter.createPositionAt(placeholderView, 0), innerText);

      return placeholderView;
    }
  }
}

Component.ts

import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { CKEditorUploadAdapter } from 'src/app/_helpers/ckeditor-upload-adapter';
import { ConferenceViewModelWithDetails, PaperAcknowledgementViewModel, PaperConfigurationViewModel } from 'src/app/_models/generatedModels';
import { AuthenticationService } from 'src/app/_services/authentication.service';
import { AdminCallForPapersService, OrganizationService } from 'src/app/_services/generatedServices';
import { ToasterService } from 'src/app/_services/toaster.service';
import * as customBuild from 'src/ckCustomBuild/ckeditor';
//import * as Placeholder from 'src/ckCustomBuild/ckeditor';
import * as Placeholder from 'src/ckCustomBuild/placeholder.plugin';


@Component({
  selector: 'bxl-abstract-management-configuration',
  templateUrl: 'abstract-management-configuration.component.html',
})
export class AbstractManagementConfigurationComponent implements OnInit {
  initialized = false;
  public Editor = customBuild;
  htmlEditorConfig = {
    plugins: [Placeholder],
    toolbar: {
      items: ['bold', 'italic', 'underline', 'link', 'alignment', 'bulletedList', 'numberedList', '|', 'fontFamily', 'fontSize', 'fontColor', 'fontBackgroundColor', '|', 'Paceholder'],
      shouldNotGroupWhenFull: false,
    },
    // placeholderConfig: {
    //   types: ['date', 'color', 'first name', 'surname'],
    // },
    fontSize: {
      options: [9, 11, 13, 'default', 17, 19, 21],
    },
    mediaEmbed: {
      previewsInData: true,
    },
  };
  organizationId: string;
  conferenceId: any;
  configuration: PaperConfigurationViewModel;

  constructor(private auth: AuthenticationService, private orgService: OrganizationService, private router: Router, private route: ActivatedRoute, private cfpService: AdminCallForPapersService, private toaster: ToasterService) {}

  ngOnInit(): void {
    this.route.paramMap.subscribe((params) => {
      this.organizationId = params.get('organizationId');
      this.conferenceId = params.get('conferenceId');

      this.cfpService.getPaperConfiguration(this.organizationId, this.conferenceId).subscribe((result) => {
        this.configuration = result;
        this.initialized = true;
      });
    });
  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

等风也等你 2025-02-16 23:27:34

在您的loteholder.plugin.js中,将以下内容放置在

import * as Plugin from 'src/app/ckeditor/ckeditor';
import * as Widget from 'src/app/ckeditor/ckeditor';
import * as Command from 'src/app/ckeditor/ckeditor';
import * as Collection from 'src/app/ckeditor/ckeditor';
import * as Model from 'src/app/ckeditor/ckeditor';
import * as toWidget from 'src/app/ckeditor/ckeditor';
import * as viewToModelPositionOutsideModelElement from 'src/app/ckeditor/ckeditor';
import * as addListToDropdown from 'src/app/ckeditor/ckeditor';
import * as createDropdown from 'src/app/ckeditor/ckeditor';

这些行中,而不是

import * as Plugin from 'src/ckCustomBuild/ckeditor';
import * as Widget from 'src/ckCustomBuild/ckeditor';
import * as Command from 'src/ckCustomBuild/ckeditor';
import * as Collection from 'src/ckCustomBuild/ckeditor';
import * as Model from 'src/ckCustomBuild/ckeditor';
import * as toWidget from 'src/ckCustomBuild/ckeditor';
import * as viewToModelPositionOutsideModelElement from 'src/ckCustomBuild/ckeditor';
import * as addListToDropdown from 'src/ckCustomBuild/ckeditor';
import * as createDropdown from 'src/ckCustomBuild/ckeditor';

指错误的路径,它必须是通往您ckeditor.js的路径。这样,您可以消除该文件中的模块加载错误。

In your placeholder.plugin.js put the below content,

import * as Plugin from 'src/app/ckeditor/ckeditor';
import * as Widget from 'src/app/ckeditor/ckeditor';
import * as Command from 'src/app/ckeditor/ckeditor';
import * as Collection from 'src/app/ckeditor/ckeditor';
import * as Model from 'src/app/ckeditor/ckeditor';
import * as toWidget from 'src/app/ckeditor/ckeditor';
import * as viewToModelPositionOutsideModelElement from 'src/app/ckeditor/ckeditor';
import * as addListToDropdown from 'src/app/ckeditor/ckeditor';
import * as createDropdown from 'src/app/ckeditor/ckeditor';

Instead of these lines,

import * as Plugin from 'src/ckCustomBuild/ckeditor';
import * as Widget from 'src/ckCustomBuild/ckeditor';
import * as Command from 'src/ckCustomBuild/ckeditor';
import * as Collection from 'src/ckCustomBuild/ckeditor';
import * as Model from 'src/ckCustomBuild/ckeditor';
import * as toWidget from 'src/ckCustomBuild/ckeditor';
import * as viewToModelPositionOutsideModelElement from 'src/ckCustomBuild/ckeditor';
import * as addListToDropdown from 'src/ckCustomBuild/ckeditor';
import * as createDropdown from 'src/ckCustomBuild/ckeditor';

It was referring to a wrong path and it must be the path to your ckeditor.js. In this way you can eliminate the module load error in that file.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文