JSR import maps
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
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"
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.
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.
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"
}
},
}