Is there a way to debug language features not kicking in?

I have a curious situation where a local project with CSS, HTML, JS, and Markdown language features works perfectly fine:

import { basicSetup, EditorView } from "codemirror";
import { EditorState } from "@codemirror/state";

import { css } from "@codemirror/lang-css";
import { html } from "@codemirror/lang-html";
import { javascript } from "@codemirror/lang-javascript";
import { markdown } from "@codemirror/lang-markdown";

function getInitialState(filename, data) {
  const doc = data.toString();
  const extensions = [basicSetup];

  // Can we add syntax highlighting?
  const ext = filename.substring(filename.lastIndexOf(`.`) + 1);
  const syntax = { css, html, js: javascript, md: markdown}[ext];
  if (syntax) extensions.push(syntax());

  // What did we just build?
  console.log(extensions);

  return EditorState.create({ doc, extensions });
}

Nothing special there, we import the languages, and then activate one if we’re building an editor for a filename with the relevant file extension. This gets bundled and works exactly as expected on my local dev machine.

If, however, if I run the same code on a deploy box with the same build tasks, the highlighting disappears. Now, this isn’t really codemirror itself being the problem: the bundler does something differently that causes things to no longer work, but there are no errors or warnings or info’s in the dev console that lets me figure out why. That console log shows what looks to be the exact same β€œextensions” array as part of the console log, so as far as I can determine this should work, but whatever code the bundler produces on the deploy box does something differently such that when codemirror creates an editor, the language features don’t kick in…

Is there some way to force codemirror into an β€œoverly verbose” mode where it reports on everything it’s doing during an editor instance creation to help figure out at what point in the process the local and remote projects diverge?

This somewhat sounds like it might be a duplicated dependency issue. If you’re using an old npm version (or, even worse, yarn) to do the dependency installation on that deploy box, moving to a recent npm could help.

The deploy machine β€œstarts from nothing” every time it starts up, there is literally no possibility of old npm modules (there is no filesystem beyond the code itself, so no node_modules dirs; the first thing it does is install node and nvm, then runs npm install and then npm start).

So if there’s a way to get more information out of codemirror about what’s happening while it’s loading extensions, that’d be mighty useful.

Also, while it’s not the most recent version of npm, the following dependency list after install doesn’t show anything weird that I can see:

main
β”œβ”€β”¬ @codemirror/lang-css@6.2.1
β”‚ β”œβ”€β”¬ @codemirror/autocomplete@6.16.3
β”‚ β”‚ β”œβ”€β”€ @codemirror/language@6.10.2 deduped
β”‚ β”‚ β”œβ”€β”€ @codemirror/state@6.4.1 deduped
β”‚ β”‚ β”œβ”€β”¬ @codemirror/view@6.28.2
β”‚ β”‚ β”‚ β”œβ”€β”€ @codemirror/state@6.4.1 deduped
β”‚ β”‚ β”‚ β”œβ”€β”€ style-mod@4.1.2 deduped
β”‚ β”‚ β”‚ └── w3c-keyname@2.2.8 deduped
β”‚ β”‚ └── @lezer/common@1.2.1 deduped
β”‚ β”œβ”€β”¬ @codemirror/language@6.10.2
β”‚ β”‚ β”œβ”€β”€ @codemirror/state@6.4.1 deduped
β”‚ β”‚ β”œβ”€β”€ @codemirror/view@6.28.2 deduped
β”‚ β”‚ β”œβ”€β”€ @lezer/common@1.2.1 deduped
β”‚ β”‚ β”œβ”€β”¬ @lezer/highlight@1.2.0
β”‚ β”‚ β”‚ └── @lezer/common@1.2.1 deduped
β”‚ β”‚ β”œβ”€β”¬ @lezer/lr@1.4.1
β”‚ β”‚ β”‚ └── @lezer/common@1.2.1 deduped
β”‚ β”‚ └── style-mod@4.1.2
β”‚ β”œβ”€β”€ @codemirror/state@6.4.1 deduped
β”‚ β”œβ”€β”€ @lezer/common@1.2.1
β”‚ └─┬ @lezer/css@1.1.8
β”‚   β”œβ”€β”€ @lezer/common@1.2.1
β”‚   β”œβ”€β”¬ @lezer/highlight@1.2.0
β”‚   β”‚ └── @lezer/common@1.2.1 deduped
β”‚   └─┬ @lezer/lr@1.4.1
β”‚     └── @lezer/common@1.2.1 deduped
β”œβ”€β”¬ @codemirror/lang-html@6.4.9
β”‚ β”œβ”€β”¬ @codemirror/autocomplete@6.16.3
β”‚ β”‚ β”œβ”€β”€ @codemirror/language@6.10.2 deduped
β”‚ β”‚ β”œβ”€β”€ @codemirror/state@6.4.1 deduped
β”‚ β”‚ β”œβ”€β”€ @codemirror/view@6.28.2 deduped
β”‚ β”‚ └── @lezer/common@1.2.1 deduped
β”‚ β”œβ”€β”€ @codemirror/lang-css@6.2.1 deduped
β”‚ β”œβ”€β”€ @codemirror/lang-javascript@6.2.2 deduped
β”‚ β”œβ”€β”¬ @codemirror/language@6.10.2
β”‚ β”‚ β”œβ”€β”€ @codemirror/state@6.4.1 deduped
β”‚ β”‚ β”œβ”€β”€ @codemirror/view@6.28.2 deduped
β”‚ β”‚ β”œβ”€β”€ @lezer/common@1.2.1 deduped
β”‚ β”‚ β”œβ”€β”¬ @lezer/highlight@1.2.0
β”‚ β”‚ β”‚ └── @lezer/common@1.2.1 deduped
β”‚ β”‚ β”œβ”€β”¬ @lezer/lr@1.4.1
β”‚ β”‚ β”‚ └── @lezer/common@1.2.1 deduped
β”‚ β”‚ └── style-mod@4.1.2 deduped
β”‚ β”œβ”€β”€ @codemirror/state@6.4.1 deduped
β”‚ β”œβ”€β”¬ @codemirror/view@6.28.2
β”‚ β”‚ β”œβ”€β”€ @codemirror/state@6.4.1 deduped
β”‚ β”‚ β”œβ”€β”€ style-mod@4.1.2 deduped
β”‚ β”‚ └── w3c-keyname@2.2.8
β”‚ β”œβ”€β”€ @lezer/common@1.2.1
β”‚ β”œβ”€β”€ @lezer/css@1.1.8 deduped
β”‚ └─┬ @lezer/html@1.3.10
β”‚   β”œβ”€β”€ @lezer/common@1.2.1
β”‚   β”œβ”€β”¬ @lezer/highlight@1.2.0
β”‚   β”‚ └── @lezer/common@1.2.1 deduped
β”‚   └─┬ @lezer/lr@1.4.1
β”‚     └── @lezer/common@1.2.1 deduped
β”œβ”€β”¬ @codemirror/lang-javascript@6.2.2
β”‚ β”œβ”€β”¬ @codemirror/autocomplete@6.16.3
β”‚ β”‚ β”œβ”€β”€ @codemirror/language@6.10.2 deduped
β”‚ β”‚ β”œβ”€β”€ @codemirror/state@6.4.1 deduped
β”‚ β”‚ β”œβ”€β”€ @codemirror/view@6.28.2 deduped
β”‚ β”‚ └── @lezer/common@1.2.1 deduped
β”‚ β”œβ”€β”¬ @codemirror/language@6.10.2
β”‚ β”‚ β”œβ”€β”€ @codemirror/state@6.4.1 deduped
β”‚ β”‚ β”œβ”€β”€ @codemirror/view@6.28.2 deduped
β”‚ β”‚ β”œβ”€β”€ @lezer/common@1.2.1 deduped
β”‚ β”‚ β”œβ”€β”¬ @lezer/highlight@1.2.0
β”‚ β”‚ β”‚ └── @lezer/common@1.2.1 deduped
β”‚ β”‚ β”œβ”€β”¬ @lezer/lr@1.4.1
β”‚ β”‚ β”‚ └── @lezer/common@1.2.1 deduped
β”‚ β”‚ └── style-mod@4.1.2 deduped
β”‚ β”œβ”€β”¬ @codemirror/lint@6.8.1
β”‚ β”‚ β”œβ”€β”€ @codemirror/state@6.4.1 deduped
β”‚ β”‚ β”œβ”€β”€ @codemirror/view@6.28.2 deduped
β”‚ β”‚ └── crelt@1.0.6
β”‚ β”œβ”€β”€ @codemirror/state@6.4.1 deduped
β”‚ β”œβ”€β”¬ @codemirror/view@6.28.2
β”‚ β”‚ β”œβ”€β”€ @codemirror/state@6.4.1 deduped
β”‚ β”‚ β”œβ”€β”€ style-mod@4.1.2 deduped
β”‚ β”‚ └── w3c-keyname@2.2.8 deduped
β”‚ β”œβ”€β”€ @lezer/common@1.2.1
β”‚ └─┬ @lezer/javascript@1.4.17
β”‚   β”œβ”€β”€ @lezer/common@1.2.1
β”‚   β”œβ”€β”¬ @lezer/highlight@1.2.0
β”‚   β”‚ └── @lezer/common@1.2.1 deduped
β”‚   └─┬ @lezer/lr@1.4.1
β”‚     └── @lezer/common@1.2.1 deduped
β”œβ”€β”¬ @codemirror/lang-markdown@6.2.5
β”‚ β”œβ”€β”¬ @codemirror/autocomplete@6.16.3
β”‚ β”‚ β”œβ”€β”€ @codemirror/language@6.10.2 deduped
β”‚ β”‚ β”œβ”€β”€ @codemirror/state@6.4.1 deduped
β”‚ β”‚ β”œβ”€β”€ @codemirror/view@6.28.2 deduped
β”‚ β”‚ └── @lezer/common@1.2.1 deduped
β”‚ β”œβ”€β”€ @codemirror/lang-html@6.4.9 deduped
β”‚ β”œβ”€β”¬ @codemirror/language@6.10.2
β”‚ β”‚ β”œβ”€β”€ @codemirror/state@6.4.1 deduped
β”‚ β”‚ β”œβ”€β”€ @codemirror/view@6.28.2 deduped
β”‚ β”‚ β”œβ”€β”€ @lezer/common@1.2.1 deduped
β”‚ β”‚ β”œβ”€β”¬ @lezer/highlight@1.2.0
β”‚ β”‚ β”‚ └── @lezer/common@1.2.1 deduped
β”‚ β”‚ β”œβ”€β”¬ @lezer/lr@1.4.1
β”‚ β”‚ β”‚ └── @lezer/common@1.2.1 deduped
β”‚ β”‚ └── style-mod@4.1.2 deduped
β”‚ β”œβ”€β”€ @codemirror/state@6.4.1 deduped
β”‚ β”œβ”€β”¬ @codemirror/view@6.28.2
β”‚ β”‚ β”œβ”€β”€ @codemirror/state@6.4.1 deduped
β”‚ β”‚ β”œβ”€β”€ style-mod@4.1.2 deduped
β”‚ β”‚ └── w3c-keyname@2.2.8 deduped
β”‚ β”œβ”€β”€ @lezer/common@1.2.1
β”‚ └─┬ @lezer/markdown@1.3.0
β”‚   β”œβ”€β”€ @lezer/common@1.2.1
β”‚   └─┬ @lezer/highlight@1.2.0
β”‚     └── @lezer/common@1.2.1 deduped
β”œβ”€β”€ @codemirror/state@6.4.1
β”œβ”€β”¬ codemirror@6.0.1
β”‚ β”œβ”€β”¬ @codemirror/autocomplete@6.16.3
β”‚ β”‚ β”œβ”€β”€ @codemirror/language@6.10.2 deduped
β”‚ β”‚ β”œβ”€β”€ @codemirror/state@6.4.1 deduped
β”‚ β”‚ β”œβ”€β”€ @codemirror/view@6.28.2 deduped
β”‚ β”‚ └── @lezer/common@1.2.1
β”‚ β”œβ”€β”¬ @codemirror/commands@6.6.0
β”‚ β”‚ β”œβ”€β”€ @codemirror/language@6.10.2 deduped
β”‚ β”‚ β”œβ”€β”€ @codemirror/state@6.4.1 deduped
β”‚ β”‚ β”œβ”€β”€ @codemirror/view@6.28.2 deduped
β”‚ β”‚ └── @lezer/common@1.2.1 deduped
β”‚ β”œβ”€β”¬ @codemirror/language@6.10.2
β”‚ β”‚ β”œβ”€β”€ @codemirror/state@6.4.1 deduped
β”‚ β”‚ β”œβ”€β”€ @codemirror/view@6.28.2 deduped
β”‚ β”‚ β”œβ”€β”€ @lezer/common@1.2.1 deduped
β”‚ β”‚ β”œβ”€β”¬ @lezer/highlight@1.2.0
β”‚ β”‚ β”‚ └── @lezer/common@1.2.1 deduped
β”‚ β”‚ β”œβ”€β”¬ @lezer/lr@1.4.1
β”‚ β”‚ β”‚ └── @lezer/common@1.2.1 deduped
β”‚ β”‚ └── style-mod@4.1.2 deduped
β”‚ β”œβ”€β”¬ @codemirror/lint@6.8.1
β”‚ β”‚ β”œβ”€β”€ @codemirror/state@6.4.1 deduped
β”‚ β”‚ β”œβ”€β”€ @codemirror/view@6.28.2 deduped
β”‚ β”‚ └── crelt@1.0.6 deduped
β”‚ β”œβ”€β”¬ @codemirror/search@6.5.6
β”‚ β”‚ β”œβ”€β”€ @codemirror/state@6.4.1 deduped
β”‚ β”‚ β”œβ”€β”€ @codemirror/view@6.28.2 deduped
β”‚ β”‚ └── crelt@1.0.6 deduped
β”‚ β”œβ”€β”€ @codemirror/state@6.4.1 deduped
β”‚ └─┬ @codemirror/view@6.28.2
β”‚   β”œβ”€β”€ @codemirror/state@6.4.1 deduped
β”‚   β”œβ”€β”€ style-mod@4.1.2 deduped
β”‚   └── w3c-keyname@2.2.8 deduped
β”‚
<unrelated other packages follow>

This is not about old modules. This is about multiple instances being installed loaded.

And that list you show looks like that’s the caseβ€”if you remove all the lines with β€˜deduped’, you still see a bunch of copies of the library package.

1 Like

Ahh, thank you. Explicitly running an npm dedupe after npm install apparently makes it wake up and go β€œoh right hold on I forgot some stuff” and then does dedupe all the remaining duplicates, with the bundle working perfectly fine.

Fun times!

What npm version is this? Anything halfway recent shouldn’t do this stuff to begin with.

v7.20 - this is on infrastructure that’s in the process of being uplifted to Node 20, but that work has not yet finished.