Getting error when trying to import codemirror

The exported identifier "CodeMirror" is not declared in Babel's scope tracker
as a JavaScript value binding, and "@babel/plugin-transform-typescript"
never encountered it as a TypeScript type declaration.
It will be treated as a JavaScript value.

This problem is likely caused by another plugin injecting
"CodeMirror" without registering it in the scope tracker. If you are the author
 of that plugin, please use "scope.registerDeclaration(declarationPath)".

Getting this error while trying to import codemirror package to ember Ember version: 3.28.10 codemirror: 5.65.13

Made following entries in ember-cli-build.js

app.import('node_modules/codemirror/lib/codemirror.css');
  app.import('node_modules/codemirror/mode/javascript/javascript.js');
  app.import('node_modules/codemirror/mode/django/django.js');
  app.import('node_modules/codemirror/mode/css/css.js');
  app.import('node_modules/codemirror/mode/sass/sass.js');
  app.import('node_modules/codemirror/mode/markdown/markdown.js');
  app.import('node_modules/codemirror/mode/meta.js');
  app.import('node_modules/codemirror/addon/edit/matchtags.js');
  app.import('node_modules/codemirror/addon/fold/foldcode.js');
  app.import('node_modules/codemirror/addon/fold/foldgutter.js');
  app.import('node_modules/codemirror/addon/fold/xml-fold.js');
  app.import('node_modules/codemirror/addon/fold/brace-fold.js');

In webpack.config.common.js

optimization: {
  runtimeChunk: {
    name: 'manifest'
  },
  splitChunks: {
    minSize: 0,
    chunks: 'all',
    cacheGroups: {
      codemirror: {
        test: /[\\/]node_modules[\\/](codemirror)[\\/]/,
        name: 'codemirror',
        idHint: 'codemirror',
        chunks: 'all',
        filename: `assets/codemirror${env === 'prod' ? '.[chunkhash]' : ''}.js`,
      },
    },
  },
},

importing the code inside the component as

let CodeMirror = await import(‘codemirror’);

Embroider and typescript is enabled in the code base

Have tried codemirror version 6 as well, but results in the same error

app.import is a legacy feature that is probably not going to do what you want. It cannot support await import() for example. So I would start by deleting all of that.

I just copied this code from Codemirror’s website:

import {EditorView, basicSetup} from "codemirror"
import {javascript} from "@codemirror/lang-javascript"

let editor = new EditorView({
  extensions: [basicSetup, javascript()],
  parent: document.body
})

and put it into an Ember modifier:

// app/modifiers/codemirror.js
import { modifier } from 'ember-modifier';
import { EditorView, basicSetup } from 'codemirror';
import { javascript } from '@codemirror/lang-javascript';

export default modifier(function codemirror(element /*, positional, named*/) {
  let editor = new EditorView({
    extensions: [basicSetup, javascript()],
    parent: element,
  });
  return () => {
    editor.destroy();
  };
});

And you invoke it like:

<div {{codemirror}} />

And it worked on the first try for me. I used these deps:

    "@codemirror/lang-javascript": "^6.2.1",
    "codemirror": "^6.0.1"

After you see it working you can worry about lazy loading. The easiest split point for lazy loading depends on your use case.

If you’re already using Embroider’s splitAtRoutes, this whole modifier and codemirror will only load on the routes that need it, and there’s nothing else you need to do.

Alternatively, as long as you have staticModifiers enabled, you can await import("../modifiers/codemirror") to load the whole thing only when you want to manually load it.

Alternatively, you can make the modifier itself lazy load codemirror, but then you need to absorb the asynchrony manually.

1 Like

Thanks for the code it worked with the above configuration, but however when i try to use import { EditorState } from '@codemirror/state'; getting the following error

ember-onerror.js:41 Error: Could not find module `@codemirror/state` imported from `(require)`

But the module is present in the node_modules under @codemirror/state/dist/index.js

Also noted that import {javascript} from "@codemirror/lang-javascript" uses few classes from above files

is @codemirror/state in your package.json?

@NullVoxPopuli Yes it’s present in the package.json as well

The issue has been fixed. The dist generate was not updated due to some cache issue. Thanks @ef4 and @NullVoxPopuli