0

Is there a way to use versioned skypack code with importmaps?

I am trying to import codemirror from skypack-cdn. I also want the file to work with the bundlers, like Babel, in the future. It would be very nice to avoid the excessive workflow that bundlers bring to this tiny project.

The imports in the javascript file that I would like to save from bundling looks like this

import {EditorView, basicSetup} from 'codemirror'
import {keymap} from '@codemirror/view'
import {indentWithTab} from '@codemirror/commands'
import {javascript} from '@codemirror/lang-javascript'
import {EditorState} from '@codemirror/state'

The working import map looks like this.

<script type="importmap">
      {
        "imports": {
          "codemirror" : "https://cdn.skypack.dev/codemirror/", 
          "@codemirror/" : "https://cdn.skypack.dev/@codemirror/"
        }
      }
    </script>

The problem arrises when I try to pin Codemirror to a specific version like so

<script type="importmap">
      {
        "imports": {
          "codemirror" : "https://cdn.skypack.dev/codemirror@6.0.0/", 
          "@codemirror/" : "https://cdn.skypack.dev/@codemirror@6.0.0/"
        }
      }
    </script>

The URL https://cdn.skypack.dev/@codemirror@6.0.0/commands does not exist. The correct place to look would be https://cdn.skypack.dev/@codemirror/commands@6.0.0

Is there anyway to pin this to a particular version using the import maps?

dooderson
  • 547
  • 1
  • 9
  • 16

1 Answers1

1

I have never used import maps in real life, and only read tutorials (like this one or the one from MDN), but according to them, import maps is a really straightforward feature.

You can't use regexps as keys, and the only thing you can “replace” is a prefix. So, let's use prefix for all the deps and put versions right into import paths:

<script type="importmap">
  {
    "imports": {
      "cdn/": "https://cdn.skypack.dev/"
    }
  }
</script>

<script type="module">
  import {EditorView, basicSetup} from 'cdn/codemirror@6.0.0'
  import {indentWithTab} from 'cdn/@codemirror/commands@6.0.0'
  import {javascript} from 'cdn/@codemirror/lang-javascript@6.0.0'
  import {EditorState} from 'cdn/@codemirror/state@6.0.0'

  console.log(EditorState);
</script>

But be aware, it won't work with bundlers. However, when you will add bundlers to your project, all you will need to do is to update the paths and remove the import map completely.

Igor Adamenko
  • 861
  • 1
  • 8
  • 20
  • caveat: There is a lot of cross-importing between Codemirror packages, especially `basicSetup` depends on many. And it's important to avoid duplicates especially `cdn/@codemirror/state` that you import must be same as `@codemirror/state` the other modules import; I don't know enough about skypack, but I suspect using custom `cdn/` prefix will break that assumption. See also https://github.com/skypackjs/skypack-cdn/issues/159 – Beni Cherniavsky-Paskin Jun 13 '23 at 07:56