deno icon indicating copy to clipboard operation
deno copied to clipboard

JSR import maps

Open oscarotero opened this issue 1 year ago • 4 comments

Version: Deno 1.42.4

I have the following script:

import * as types from "jsr:@std/[email protected]";
import * as mod from "jsr:@oak/[email protected]/media_types";

deno info outputs the following dependencies tree:

➜  oak deno info main.ts
local: /Users/oscarotero/oak/main.ts
type: TypeScript
dependencies: 16 unique
size: 393.66KB

file:///Users/oscarotero/oak/main.ts (114B)
├─┬ https://jsr.io/@std/media-types/0.223.0/mod.ts (1.14KB)
│ ├─┬ https://jsr.io/@std/media-types/0.223.0/content_type.ts (3.04KB)
│ │ ├─┬ https://jsr.io/@std/media-types/0.223.0/parse_media_type.ts (3.23KB)
│ │ │ └── https://jsr.io/@std/media-types/0.223.0/_util.ts (3.29KB)
│ │ ├─┬ https://jsr.io/@std/media-types/0.223.0/get_charset.ts (1.18KB)
│ │ │ ├── https://jsr.io/@std/media-types/0.223.0/parse_media_type.ts *
│ │ │ ├── https://jsr.io/@std/media-types/0.223.0/_util.ts *
│ │ │ └─┬ https://jsr.io/@std/media-types/0.223.0/_db.ts (1.26KB)
│ │ │   ├── https://jsr.io/@std/media-types/0.223.0/vendor/mime-db.v1.52.0.ts (182.13KB)
│ │ │   └── https://jsr.io/@std/media-types/0.223.0/_util.ts *
│ │ ├─┬ https://jsr.io/@std/media-types/0.223.0/format_media_type.ts (1.73KB)
│ │ │ └── https://jsr.io/@std/media-types/0.223.0/_util.ts *
│ │ ├── https://jsr.io/@std/media-types/0.223.0/_db.ts *
│ │ └─┬ https://jsr.io/@std/media-types/0.223.0/type_by_extension.ts (912B)
│ │   └── https://jsr.io/@std/media-types/0.223.0/_db.ts *
│ ├─┬ https://jsr.io/@std/media-types/0.223.0/extension.ts (780B)
│ │ └─┬ https://jsr.io/@std/media-types/0.223.0/extensions_by_type.ts (979B)
│ │   ├── https://jsr.io/@std/media-types/0.223.0/parse_media_type.ts *
│ │   └── https://jsr.io/@std/media-types/0.223.0/_db.ts *
│ ├── https://jsr.io/@std/media-types/0.223.0/extensions_by_type.ts *
│ ├── https://jsr.io/@std/media-types/0.223.0/format_media_type.ts *
│ ├── https://jsr.io/@std/media-types/0.223.0/get_charset.ts *
│ ├── https://jsr.io/@std/media-types/0.223.0/parse_media_type.ts *
│ └── https://jsr.io/@std/media-types/0.223.0/type_by_extension.ts *
└─┬ https://jsr.io/@oak/commons/0.10.1/media_types.ts (6.36KB)
  └─┬ https://jsr.io/@std/media-types/0.222.1/type_by_extension.ts (912B)
    └─┬ https://jsr.io/@std/media-types/0.222.1/_db.ts (1.26KB)
      ├── https://jsr.io/@std/media-types/0.222.1/vendor/mime-db.v1.52.0.ts (182.13KB)
      └── https://jsr.io/@std/media-types/0.222.1/_util.ts (3.29KB)

As you can see, there are two different versions of the same package: @std/media/0.223.0 and std/media/0.222.1. I want to use import maps to fix this:

{
  "imports": {
    "jsr:@std/[email protected]": "jsr:@std/[email protected]"
  }
}

But it doesn't work. I've tried different strategies:

{
  "imports": {
    "jsr:@std/[email protected]": "jsr:@std/[email protected]",
    "https://jsr.io/@std/media-types/0.222.1/": "https://jsr.io/@std/media-types/0.223.0/"
  },
  "scopes": {
    "https://jsr.io/@oak/commons/0.10.1/": {
      "https://jsr.io/@std/media-types/0.222.1/": "https://jsr.io/@std/media-types/0.223.0/"
    }
  }
}

But seems that none of them fixes this issue, deno info outputs the same tree, ignoring the import maps. Are import maps supported in JSR dependencies?

FYI I found the same issue with NPM #23459

oscarotero avatar Apr 23 '24 09:04 oscarotero

The problem is that import maps don't understand the semantics of the version in the URL, it must literally match the URL of the import.

If you look at the module https://jsr.io/@oak/commons/0.10.1/media_types.ts you'll see that it imports: jsr:@std/[email protected]/type-by-extension (ie. without the patch .1 part of the version)

So the import map will only match that whole value, or maybe one with a trailing /, so the following mapping may work:

"jsr:@std/[email protected]/type-by-extension": "jsr:@std/[email protected]/type-by-extension" or "jsr:/@std/[email protected]/": "jsr:/@std/[email protected]/" (not 100% sure on this, try it with and without the / after the jsr: scheme)

I have a similar case where a package is using older versions of @std/path, I can dedupe with the following:

"jsr:@std/[email protected]": "jsr:@std/path@^0.223.0"

jollytoad avatar Apr 23 '24 16:04 jollytoad

Thanks @jollytoad I can confirm that the following import map does the job:

{
  "imports": {
    "jsr:@std/[email protected]/type-by-extension": "jsr:@std/[email protected]/type-by-extension"
  }
}

But I think it's a very unfortunate behavior. If JSR dependencies can have different specifiers for the same file, it's really painful to work with import maps.

oscarotero avatar Apr 23 '24 16:04 oscarotero

What seems like a bug here is that this doesn't seem to work:

"jsr:@std/[email protected]": "jsr:@std/[email protected]"

But I think it's a very unfortunate behavior. If JSR dependencies can have different specifiers for the same file, it's really painful to work with import maps.

Yeah, there needs to be a better way here.

dsherret avatar Apr 23 '24 17:04 dsherret

An annoying thing (the main reason I hate exports feature of JSR packages) is the file is imported as /type-by-extension (with dashes) but deno info shows /type_by_extension.ts (with extension and underscores) which makes even more complicated to figure out what's the file that need to be mapped.

And another inconsitency: it seems that the scope must be defined in http format and the imports in jsr format.

// This works
{
  "scopes": {
    "https://jsr.io/@oak/commons/0.10.1/media_types.ts": {
      "jsr:@std/[email protected]/type-by-extension": "jsr:@std/[email protected]/type-by-extension"
    }
  },
}

// This doesn't work
{
  "scopes": {
    "jsr:@oak/[email protected]/media-types": {
      "jsr:@std/[email protected]/type-by-extension": "jsr:@std/[email protected]/type-by-extension"
    }
  },
}

// This neither
{
  "scopes": {
    "https://jsr.io/@oak/[email protected]/media_types.ts": {
      "https://jsr.io/@std/[email protected]/type_by_extension.ts": "https://jsr.io/@std/[email protected]/type_by_extension.ts"
    }
  },
}

oscarotero avatar Apr 23 '24 23:04 oscarotero