Denoを対象に書かれたパッケージは、基本的にdeno.land/xやnest.landなどのレジストリで公開されることが多いです。
しかし、これらのレジストリに目当てのモジュールが見つからない場合もあるかと思います。
そのような場合は、npmパッケージの使用を検討してみるとよいかもしれません。
この章では、Denoからnpmパッケージを使用する方法について2つ紹介します。
npm:
URLを使用する
Denoでパッケージをimport
する際に、npm:<パッケージ名>@<バージョン>
という形式のURLを指定すると、対象のパッケージをnpmレジストリから読み込んでくれます。
import chalk from "npm:chalk@5.0.1";
console.info(chalk.green("Hello, world!"));
実行する際は通常通り、deno run
コマンドを利用できます。
$ deno run --allow-env --allow-read main.mjs
通常のサードパーティモジュールと同様に、初回実行時のみnpmレジストリからパッケージがダウンロードされ、以降はローカルにキャッシュされたパッケージが利用されます。
deno run
の引数にnpm:
形式のURLを指定することも可能で、Node.jsにおけるnpx
コマンドのようにnpmパッケージで提供されるコマンドを直接実行することもできます。
$ deno run --unstable --allow-env --allow-read --allow-write npm:make-dir-cli@3.0.0 src/components
npm:
URLでパッケージを読み込んだ際に、Node.jsの組み込みパッケージへの読み込みはdeno_std/nodeの読み込みに置き換えられます。
そのため、Node.jsのAPIに依存したパッケージもある程度動作させることができます。
npmパッケージを配布するCDNを利用する
Denoからnpmパッケージを利用する際の手段として、CDNから対象パッケージを直接import
する方法があります。
esm.shやSkypackなどのCDNはX-TypeScript-Types
ヘッダ[1]をサポートするため、CDNから直接npmパッケージを読み込みたいときは、これらの利用を検討するとよいかと思います。
例えば、以下はesm.shからfast-xml-parserパッケージを読み込む例です。
import { XMLParser } from "https://esm.sh/fast-xml-parser@4.0.9";
const xmlDocument = await Deno.readTextFile("./test.xml");
const parser = new XMLParser();
const obj = parser.parse(xmlDocument);
(補足) esm.shについて
esm.shは、クエリパラメータによって柔軟に挙動を制御することができます。
Denoからnpmパッケージを利用する上で便利な様々なパラメータが提供されており、FreshやAleph.jsなどのフレームワークでも活用されています。
いくつか例を挙げると、次のような機能があります。
-
?no-check
パラメータを指定すると、X-TypeScript-Types
ヘッダの付与が無効化されます。https://esm.sh/fast-xml-parser@4.0.9?no-check
-
"peerDependencies"
を利用したパッケージを使用したいときは、?external
パラメータとImport mapsを併用すると便利です。import_map.json{ "imports": { "preact": "https://esm.sh/preact@10.10.0", "preact-render-to-string": "https://esm.sh/preact-render-to-string@5.2.0?external=preact", } }
-
?alias
パラメータは、あるパッケージを別のパッケージの読み込みへ置換してくれるため、preact/compat
などのパッケージを活用したいときなどに便利です。 - Node.jsのAPIに依存したパッケージを利用するために、組み込みパッケージをdeno_std/nodeへの読み込みに置換してくれます。
esm.shにはこの他にも様々な機能があります。
より詳しくは公式ドキュメントを参照ください。
(補足) X-TypeScript-TypesヘッダをサポートしないCDNを利用する必要が出てきたときは?
X-TypeScript-Types
ヘッダをサポートしないCDNからJavaScriptパッケージをimport
した場合、Denoはそのパッケージの型定義を判断することができません。
この問題を解消するため、Denoには@deno-types
という機能が提供されています。
// @deno-types="https://esm.sh/testdouble@3.16.1/index.d.ts"
export * as td from "https://esm.sh/testdouble@3.16.1/dist/testdouble.js";
このように、あるパッケージに対応する型定義ファイルの場所をDenoに知らせることができます。
どの方法を使うべき?
基本的には、npm:
URLを使うのがよいかと思います。
Deno本体に組み込まれた機能であり、将来に渡って改善やメンテナンスが継続される可能性が高いと考えられるためです。
ただし、FreshやAleph.jsなどのようにesm.shの使用を想定したフレームワークも存在するため、esm.shの使い方についても把握しておくと便利な場合もあるかと思います。
いずれの方法を利用するにせよ、Import mapsなどで依存関係を管理しておくことで、いずれかの方法に素早く移行する余地が生まれるため、活用しておくとよいでしょう。
ポイント
-
npm:
URLを利用することで、npmレジストリから直接パッケージをimport
することができます。 - CDNからnpmパッケージを読み込む場合は、esm.shなどの
X-TypeScript-Types
ヘッダをサポートするCDNを利用すると便利です。
-
X-TypeScript-Types
ヘッダはDenoがJavaScriptで書かれたモジュールに対して型を適用するための独自機能です。Denoはサードパーティモジュールをダウンロードする際に、レスポンスにX-TypeScript-Types
ヘッダが設定されていれば、そこで指定されたURLから型定義ファイルも一緒にダウンロードし、対象のJavaScriptモジュールへ適用してくれます。 ↩︎