CKEditor sources cannot be imported dynamically
📝 Provide detailed reproduction steps (if any)
- Create a TypeScript project that allows dynamic imports to be used.
- Then, install the
@ckeditor/ckedito5-uipackage. - Then, try to import something like this:
const { DefaultMenuBarItems } = await import('@ckeditor/ckeditor5-ui/src/menubar/utils.js');
or
const { DefaultMenuBarItems } = await import('@ckeditor/ckeditor5-ui');
✔️ Expected result
Import what I ask for.
❌ Actual result
When importing a particular file:
TypeError: Unknown file extension ".css" for /home/pomek/Projects/ckeditor/ckeditor5-builder/node_modules/@ckeditor/ckeditor5-ui/theme/components/menubar/menubarmenulistitem.css
at Object.getFileProtocolModuleFormat [as file:] (node:internal/modules/esm/get_format:160:9)
at defaultGetFormat (node:internal/modules/esm/get_format:203:36)
at defaultLoad (node:internal/modules/esm/load:143:22)
at async ModuleLoader.load (node:internal/modules/esm/loader:396:7)
at async ModuleLoader.moduleProvider (node:internal/modules/esm/loader:278:45) {
code: 'ERR_UNKNOWN_FILE_EXTENSION'
}
When importing the package:
TypeError: Unknown file extension ".css" for /home/pomek/Projects/ckeditor/ckeditor5-builder/node_modules/@ckeditor/ckeditor5-ui/theme/globals/globals.css
at Object.getFileProtocolModuleFormat [as file:] (node:internal/modules/esm/get_format:160:9)
at defaultGetFormat (node:internal/modules/esm/get_format:203:36)
at defaultLoad (node:internal/modules/esm/load:143:22)
at async ModuleLoader.load (node:internal/modules/esm/loader:396:7)
at async ModuleLoader.moduleProvider (node:internal/modules/esm/loader:278:45) {
code: 'ERR_UNKNOWN_FILE_EXTENSION'
}
❓ Possible solution
For this case, we can extract the object to a JSON file that I can import using a full path. It will no longer work once we drop the old installation methods support, but it gives us time to find the proper solution.
Working sample:
import JSDOM from 'jsdom';
const jsdom = new JSDOM.JSDOM();
const { window } = jsdom;
const { document } = window;
global.document = document
global.window = window
global.DOMParser = window.DOMParser
global.HTMLElement = window.HTMLElement
const { DefaultMenuBarItems } = await import('ckeditor5');
console.log( DefaultMenuBarItems );
I am not happy with that.
```ts const { DefaultMenuBarItems } = await import('@ckeditor/ckeditor5-ui/src/menubar/utils.js');```
```ts const { DefaultMenuBarItems } = await import('@ckeditor/ckeditor5-ui');```
These are both imports from the "old methods". They won't work because there are CSSes and SVGs in the dependency tree of those files.
If you want to import CKEditor sources in Node, you need to use the new installation methods, just like you did here:
const { DefaultMenuBarItems } = await import('ckeditor5');
The only "ugly" part is polyfiling the globals, but I don't see anything particularly wrong with this because, after all, CKEditor is a browser component and it's designed to work in this environment.
In other words, with the new installation methods that we're introducing, I think there's not much more that we need to improve here.
cc @filipsobol
you need to use the new installation methods, just like you did here:
Or accessing a specific package dist.
The only "ugly" part is polyfiling the globals, but I don't see anything particularly wrong with this because, after all, CKEditor is a browser component and it's designed to work in this environment.
One thing that we shouldn't do, and I don't like is that it breaks on the import and not initialization. This means we are doing something before the editor is created.
One thing that we shouldn't do, and I don't like is that it breaks on the import and not initialization. This means we are doing something before the editor is created.
This is the exact same issue we have with SSR.
const { DefaultMenuBarItems } = await import('@ckeditor/ckeditor5-ui/dist/index.js');
file:///home/pomek/Projects/ckeditor/ckeditor5-builder/node_modules/@ckeditor/ckeditor5-engine/src/view/filler.ts:72
const fillerBr = domDocument.createElement( 'br' );
^
TypeError: domDocument.createElement is not a function
at BR_FILLER (file:///home/pomek/Projects/ckeditor/ckeditor5-builder/node_modules/@ckeditor/ckeditor5-engine/src/view/filler.ts:72:31)
at file:///home/pomek/Projects/ckeditor/ckeditor5-builder/node_modules/@ckeditor/ckeditor5-engine/src/view/domconverter.ts:54:23
There has been no activity on this issue for the past year. We've marked it as stale and will close it in 30 days. We understand it may still be relevant, so if you're interested in the solution, leave a comment or reaction under this issue.
We've closed your issue due to inactivity. We understand that the issue may still be relevant. If so, feel free to open a new one (and link this issue to it).