🦕

Deno ユーザーは https import と jsr import のどちらを使うべきか?

2024/05/06に公開

JSR meetup で出た質問の中で、Deno ユーザーは JSR をどう見るべきかについての質問がいくつか出てきたので、その中からいくつかの質問を抜粋してまとめました。

Q. Deno ユーザーは https import と jsr import のどちらを使うべきか?

A. 可能な限り JSR import を使うべき。

理由1. 依存の dedupe (重複排除) が出来るのは jsr import だけなので

JSR を使う場合の大きなメリットの一つとして semver range による依存の dedupe (重複排除) があります。

https import の場合、依存の中にマイナーバージョン違いや、パッチバージョン違いのモジュールがあった場合にそれらはすべて異なるモジュールとして扱われていました。

import { Application } from "https://deno.land/x/oak@v14.1.0/mod.ts";
import { Application } from "https://deno.land/x/oak@v14.2.0/mod.ts";

例えば上記のようなコードが依存の別の場所で現れた場合に、2つの Application クラスは実体として別のものになります。対して、JSR を使うと:

import { Application } from "jsr:@oak/oak@^14.1.0";
import { Application } from "jsr:@oak/oak@^14.2.0";

上記の2つの import があった時に、Deno は ^14.1.0^14.2.0 という2つのバージョンを 14.2.0 にまとめることが出来ると判断して一つの依存とする事ができます。semver のルールによれば 14.2.014.1.0 に対して、機能追加とバグフィクスの違いしかないはずなので、この重複排除は理にかなっていると言えます。

理由2. deno.land/x は今後レジストリとしては開発されなくなる

Deno チームは今後 deno.land/x を大規模に開発していく予定はありません。代わりに JSR に投資していく予定です。

Deno 標準ライブラリなどもまもなく JSR に移行予定 (URL は https://jsr.io/@std )で、既存の deno.land/std は更新が止まる予定になっています。

(なお、deno.land/xdeno.land/std のホスティング自体は終了する予定はないので、既存の Deno プログラムが動かなくなることはないので安心してください。)

Q. Deno から JSR パッケージを使う場合、jsr: インポート指定子 (specifier) はソースコード上に直接書くべきか?

A. deno.json 内のインポートマップでパッケージ名から jsr: 指定子にマップするのがおすすめ

次のようにインポートマップを記述することで、パッケージ名から直接モジュールをインポートすることが出来ます。

{
  "imports": {
    "@std/path": "jsr:@std/path@^0.224.0",
    "@std/fs": "jsr:@std/fs@^0.224.0"
  }
}

上のように記述すると、ソースコード上では次のように書けます。

import { join } from "@std/path";
import { copy } from "@std/fs";

この記述方法は、JSR を Node/npm から使う場合と同じ記述方法になっていて、クロスプラットフォームな記述方法にもなっています。

なお、このインポートマップの記述方法は、手で直接書く必要はなくて、次のように deno add コマンドを利用すると、Deno 本体が自動的に deno.json に追記してくれます。

$ deno add @std/path @std/fs
Add @std/fs - jsr:@std/fs@^0.224.0
Add @std/path - jsr:@std/path@^0.224.0

このように、Deno 本体が、上のパターンをサポートするためのコマンドを持っています。

Discussion