codemirror / dev

Development repository for the CodeMirror editor project
https://codemirror.net/
Other
5.85k stars 371 forks source link

Error: Unrecognized extension value in extension set ([object Object]). This sometimes happens because multiple instances of @codemirror/state are loaded, breaking instanceof checks. #608

Closed c4lliope closed 2 years ago

c4lliope commented 2 years ago

As in a similar issue, https://github.com/uiwjs/react-codemirror/issues/216 I am using Codemirror libraries directly.

I have a code playground,

import React from "react"
import styled from "styled-components"
import { observer } from "mobx-react"
import { push } from "./core"

import { EditorView, keymap } from "@codemirror/view"
import { lineNumbers } from "@codemirror/gutter"
import { EditorState, basicSetup } from "@codemirror/basic-setup"
import { defaultKeymap } from "@codemirror/commands"
import { javascript } from "@codemirror/lang-javascript"

class Playground extends React.Component {
  state = {
    code: '',
    errors: [],
  }

  constructor(p) {
    super(p)
    this.playgroundNode = React.createRef()
    this.onRecord = this.onRecord.bind(this)
    this.grabCode()

    this.playgroundModel = EditorState.create({
      doc: this.state.code,
      extensions: [
        /*javascript({ config: { jsx: true } }),*/
      /*lineNumbers(), basicSetup, keymap.of(defaultKeymap)*/
      ]
    })

    window.playgroundModel = this.playgroundModel
  }

  componentDidMount() {
    this.playgroundDisplay = new EditorView({
      state: this.playgroundModel,
      parent: this.playgroundNode.current,
    })
  }

  componentDidUpdate(prev) {
    if(prev.address !== this.props.address)
      this.grabCode()
  }

  grabCode() {
    if(!this.props.address) return null

    fetch(`http://${process.env.REACT_APP_HIERARCH_ADDRESS}/source?address=${this.props.address}`)
    .then(response => response.text())
    .then(response => {
      this.setState({ code: response })

      var change = this.playgroundModel.update({changes: {
        from: 0,
        to: this.playgroundModel.doc.length,
        insert: response,
      }})

      if(this.playgroundDisplay) this.playgroundDisplay.dispatch(change)
    })
  }

  onRecord() {
    // check code for errors

    push(
      `http://${process.env.REACT_APP_HIERARCH_ADDRESS}/upgrade`,
      {
        address: this.props.address,
        upgrades: [ { begin: 0, end: -1, grade: this.state.code } ]
      },
    )
  }

  render = () => (
    <>
      <Area lines={(this.state.code || '').split(/\r\n|\r|\n/).length} >
        <div ref={this.playgroundNode} />
      </Area>

      <Clickable onClick={this.onRecord} >
        Record and Reload
      </Clickable>
    </>
  )
}

var Area = styled.div`
height: ${({ lines }) => lines * 1.15 }em;
width: 100%;
`

var Clickable = styled.button`
display: block;
color: #fffefe;
background: #6fa7ec;
border-radius: 0.8rem;
height: 1.6rem;
`

export default observer(Playground)

I commented out the lines for various extensions I've tried running, because each time I use an extension, no mind which kind I use, I see this error.

Running with no extensions leaves me compiled and running happily.

I'm glad for any help you can lend, I need some extensions in my build.

lishid commented 2 years ago

This usually happens when your build pipeline decides to mix two copies or different versions of @codemirror/state through the dependency tree. If you're using npm, try running npm list @codemirror/state and see if you have non deduped copies of that package.

c4lliope commented 2 years ago

Yes, looks like a number of copies - 0.19.5 and 0.19.6. Any recourse?

eagle:pose grace$ npm list @codemirror/state
pose@0.1.0 /Users/grace/place/assemble/pose
├─┬ @codemirror/basic-setup@0.19.0
│ ├─┬ @codemirror/autocomplete@0.19.8
│ │ ├── @codemirror/state@0.19.6  deduped
│ │ └─┬ @codemirror/tooltip@0.19.8
│ │   ├── @codemirror/state@0.19.5 
│ │   └─┬ @codemirror/view@0.19.20
│ │     └── @codemirror/state@0.19.5  deduped
│ ├─┬ @codemirror/closebrackets@0.19.0
│ │ ├── @codemirror/state@0.19.5 
│ │ └─┬ @codemirror/view@0.19.20
│ │   └── @codemirror/state@0.19.5  deduped
│ ├─┬ @codemirror/comment@0.19.0
│ │ ├── @codemirror/state@0.19.5 
│ │ └─┬ @codemirror/view@0.19.20
│ │   └── @codemirror/state@0.19.5  deduped
│ ├─┬ @codemirror/fold@0.19.1
│ │ ├── @codemirror/state@0.19.5 
│ │ └─┬ @codemirror/view@0.19.20
│ │   └── @codemirror/state@0.19.5  deduped
│ ├─┬ @codemirror/highlight@0.19.6
│ │ ├── @codemirror/state@0.19.5 
│ │ └─┬ @codemirror/view@0.19.20
│ │   └── @codemirror/state@0.19.5  deduped
│ ├─┬ @codemirror/history@0.19.0
│ │ ├── @codemirror/state@0.19.5 
│ │ └─┬ @codemirror/view@0.19.20
│ │   └── @codemirror/state@0.19.5  deduped
│ ├─┬ @codemirror/language@0.19.5
│ │ ├── @codemirror/state@0.19.5 
│ │ └─┬ @codemirror/view@0.19.20
│ │   └── @codemirror/state@0.19.5  deduped
│ ├─┬ @codemirror/lint@0.19.3
│ │ ├─┬ @codemirror/panel@0.19.0
│ │ │ ├── @codemirror/state@0.19.5 
│ │ │ └─┬ @codemirror/view@0.19.20
│ │ │   └── @codemirror/state@0.19.5  deduped
│ │ └── @codemirror/state@0.19.6  deduped
│ ├─┬ @codemirror/matchbrackets@0.19.3
│ │ ├── @codemirror/state@0.19.5 
│ │ └─┬ @codemirror/view@0.19.20
│ │   └── @codemirror/state@0.19.5  deduped
│ ├─┬ @codemirror/rectangular-selection@0.19.1
│ │ ├── @codemirror/state@0.19.5 
│ │ └─┬ @codemirror/view@0.19.20
│ │   └── @codemirror/state@0.19.5  deduped
│ ├─┬ @codemirror/search@0.19.2
│ │ └── @codemirror/state@0.19.6  deduped
│ ├── @codemirror/state@0.19.5 
│ └─┬ @codemirror/view@0.19.20
│   └── @codemirror/state@0.19.5  deduped
├─┬ @codemirror/commands@0.19.5
│ └── @codemirror/state@0.19.6  deduped
├─┬ @codemirror/gutter@0.19.5
│ ├─┬ @codemirror/rangeset@0.19.2
│ │ └── @codemirror/state@0.19.5 
│ ├── @codemirror/state@0.19.5 
│ └─┬ @codemirror/view@0.19.20
│   └── @codemirror/state@0.19.5  deduped
├─┬ @codemirror/lang-javascript@0.19.3
│ └── @codemirror/state@0.19.5 
├── @codemirror/state@0.19.6 
└─┬ @codemirror/view@0.19.20
  └── @codemirror/state@0.19.5
lishid commented 2 years ago

Try adding @codemirror/state to your dependencies and have it target ^0.19.6, perhaps that'll force npm to use the latest version for all of them?

c4lliope commented 2 years ago

Nope, that didn't appear to affect the result of npm list @codemirror/state. Still a mixture of versions, 0.19.6 and 0.19.5.

lishid commented 2 years ago

Hmm I think at this point it's going past my area of expertise, one last suggestion might be to run something like npm update. I've also used the trick of deleting package-lock.json and rerun npm install, possibly even starting with a fresh node_modules, but depending on your setup you may want to at least keep backups of your lock file and old node_modules folder before you try that.

c4lliope commented 2 years ago

I'm glad you helped Lishid. Can you recommend anyone else who may see some more approaches here? I'm eager to make some more progress.

c4lliope commented 2 years ago

Hold on, yarn upgrade; npm list @codemirror/state displays a collapsed hierarchy;

eagle:pose grace$ npm list @codemirror/state
pose@0.1.0 /Users/grace/place/assemble/pose
├─┬ @codemirror/basic-setup@0.19.0
│ ├─┬ @codemirror/autocomplete@0.19.8
│ │ ├── @codemirror/state@0.19.6  deduped
│ │ └─┬ @codemirror/tooltip@0.19.8
│ │   └── @codemirror/state@0.19.6  deduped
│ ├─┬ @codemirror/closebrackets@0.19.0
│ │ └── @codemirror/state@0.19.6  deduped
│ ├─┬ @codemirror/comment@0.19.0
│ │ └── @codemirror/state@0.19.6  deduped
│ ├─┬ @codemirror/fold@0.19.1
│ │ └── @codemirror/state@0.19.6  deduped
│ ├─┬ @codemirror/highlight@0.19.6
│ │ └── @codemirror/state@0.19.6  deduped
│ ├─┬ @codemirror/history@0.19.0
│ │ └── @codemirror/state@0.19.6  deduped
│ ├─┬ @codemirror/language@0.19.5
│ │ └── @codemirror/state@0.19.6  deduped
│ ├─┬ @codemirror/lint@0.19.3
│ │ ├─┬ @codemirror/panel@0.19.0
│ │ │ └── @codemirror/state@0.19.6  deduped
│ │ └── @codemirror/state@0.19.6  deduped
│ ├─┬ @codemirror/matchbrackets@0.19.3
│ │ └── @codemirror/state@0.19.6  deduped
│ ├─┬ @codemirror/rectangular-selection@0.19.1
│ │ └── @codemirror/state@0.19.6  deduped
│ ├─┬ @codemirror/search@0.19.2
│ │ └── @codemirror/state@0.19.6  deduped
│ └── @codemirror/state@0.19.6  deduped
├─┬ @codemirror/commands@0.19.5
│ └── @codemirror/state@0.19.6  deduped
├─┬ @codemirror/gutter@0.19.5
│ ├─┬ @codemirror/rangeset@0.19.2
│ │ └── @codemirror/state@0.19.6  deduped
│ └── @codemirror/state@0.19.6  deduped
├─┬ @codemirror/lang-javascript@0.19.3
│ └── @codemirror/state@0.19.6  deduped
├── @codemirror/state@0.19.6 
└─┬ @codemirror/view@0.19.20
  └── @codemirror/state@0.19.6  deduped
c4lliope commented 2 years ago

Success! Line numbers enabled. Screen Shot 2021-11-21 at 1 38 09 PM

marijnh commented 2 years ago

(Often completely removing your package lock and node_modules and reinstalling also helps with this issue.)

karlhorky commented 2 years ago

We fixed this in our application by adding a Yarn Resolution to force a single version of @codemirror/state (actually, we already had resolutions of a lot of other CodeMirror packages too, to fix similar breakages):

package.json (note that this is a "resolutions" key, NOT dependencies)

{
  "resolutions": {
    "@codemirror/highlight": "0.19.7",
    "@codemirror/lang-javascript": "0.19.7",
    "@codemirror/state": "0.19.9",
    "@codemirror/view": "0.19.47"
  }
}
milahu commented 2 years ago

This usually happens when your build pipeline decides to mix two copies or different versions of @codemirror/state through the dependency tree. If you're using npm, try running npm list @codemirror/state and see if you have non deduped copies of that package.

yes! this should be in the error message

to find the duplicate install of @codemirror/state, you can also use

find . -path '*/node_modules/@codemirror/state' |
  while read p; do grep -H '"version":' "$p/package.json"; done

the current message is not helpful:

This sometimes happens because multiple instances of @codemirror/state are loaded, breaking instanceof checks.

~~or, the first @codemirror/state sets a global state like window.__codemirror_state__ and all other @codemirror/state use that global state~~ too dirty

steveruizok commented 1 year ago

This same bug also happens if @codemirror/state is not installed as a dependency.

mustafa0x commented 1 year ago

Adding the following to vite config seems to fix for me (using pnpm).

    optimizeDeps: {
        exclude: ['@codemirror/state'],
    },
multiplehats commented 1 year ago

Adding the following to vite config seems to fix for me (using pnpm).

    optimizeDeps: {
        exclude: ['@codemirror/state'],
    },

Can confirm works for me too.

rupeshpadhye commented 1 year ago

tried all suggested solutions, still getting error intermittently. is there solid fix to this

liliangrong777 commented 1 year ago

Problems still exist "@uiw/react-codemirror": "^4.21.13",

milahu commented 10 months ago

still an issue with the pnpm package manager it "just works" with npm and yarn but fails with pnpm see also https://github.com/pnpm/pnpm/issues/5807

adding optimizeDeps.exclude to vite.config.js has no effect

    optimizeDeps: {
        exclude: ['@codemirror/state'],
    },

adding pnpm.overrides to package.json has no effect

{
  // ...
  "pnpm": {
    "overrides": {
      "@codemirror/state": "^6.4.0"
    }
  },
  // ...
}

to reproduce

git clone https://github.com/milahu/codemirror-lang-nix
cd codemirror-lang-nix
git checkout f83529d65a000aaeab219d0e9de53c55b5344b47
pnpm i
npm run build && npm run devbuild && npm run devserve

open the devserver page, error in js console

Uncaught Error: Unrecognized extension value in extension set ([object Object]). This sometimes happens because multiple instances of @codemirror/state are loaded, breaking instanceof checks.

what does pnpm install

This usually happens when your build pipeline decides to mix two copies or different versions of @codemirror/state through the dependency tree. If you're using npm, try running npm list @codemirror/state and see if you have non deduped copies of that package.

yes! this should be in the error message

to find the duplicate install of @codemirror/state, you can also use

find . -path '*/node_modules/@codemirror/state' |
  while read p; do grep -H '"version":' "$p/package.json"; done

the current message is not helpful:

This sometimes happens because multiple instances of @codemirror/state are loaded, breaking instanceof checks.

with npm

$ find . -path '*/node_modules/@codemirror/state' |
  while read p; do grep -H '"version":' "$p/package.json"; done

./node_modules/@codemirror/state/package.json:  "version": "6.4.0",

with yarn

$ find . -path '*/node_modules/@codemirror/state' |
  while read p; do grep -H '"version":' "$p/package.json"; done

./node_modules/@codemirror/state/package.json:  "version": "6.4.0",

with pnpm

$ find . -path '*/node_modules/@codemirror/state' |
  while read p; do grep -H '"version":' "$p/package.json"; done

./node_modules/@codemirror/state/package.json:  "version": "6.4.0",
./node_modules/.pnpm/@codemirror+commands@6.3.3/node_modules/@codemirror/state/package.json:  "version": "6.4.0",
./node_modules/.pnpm/codemirror@6.0.1_@lezer+common@1.2.0/node_modules/@codemirror/state/package.json:  "version": "6.4.0",
./node_modules/.pnpm/@codemirror+theme-one-dark@6.1.2/node_modules/@codemirror/state/package.json:  "version": "6.4.0",
./node_modules/.pnpm/@codemirror+search@6.5.5/node_modules/@codemirror/state/package.json:  "version": "6.4.0",
./node_modules/.pnpm/@codemirror+lint@6.4.2/node_modules/@codemirror/state/package.json:  "version": "6.4.0",
./node_modules/.pnpm/@codemirror+language@6.10.0/node_modules/@codemirror/state/package.json:  "version": "6.4.0",
./node_modules/.pnpm/@codemirror+view@6.23.0/node_modules/@codemirror/state/package.json:  "version": "6.4.0",
./node_modules/.pnpm/node_modules/@codemirror/state/package.json:  "version": "6.4.0",
./node_modules/.pnpm/@codemirror+autocomplete@6.11.1_@codemirror+language@6.10.0_@codemirror+state@6.4.0_@codemirr_o5ynkp4rjcyr63t72krio2opdq/node_modules/@codemirror/state/package.json:  "version": "6.4.0",
./node_modules/.pnpm/@codemirror+state@6.4.0/node_modules/@codemirror/state/package.json:  "version": "6.4.0",

so all @codemirror/state have version 6.4.0 and all @codemirror/state are symlinked to the same node_modules/.pnpm/@codemirror+state@6.4.0

possible solution

use "loose instanceof checks"

-  someObject instance of SomeClass
+  someObject.constructor.name == SomeClass.name
> 1 instanceof Number
false

> (1).constructor.name == Number.name
true
sumeetadur commented 5 months ago

This same bug also happens if @codemirror/state is not installed as a dependency.

Installing @codemirror/state as a dependency fixed this issue for me

tianshaochuan commented 1 week ago

可以尝试在node_modules中@codemirror依赖中所有的包下面各自安装的node_modules全部删掉然后重启解决

image