[Deno] ライブラリをimportする

Tags:

#Deno #TypeScript #Node.js
このエントリーをはてなブックマークに追加

Denoを触ってみた際のメモです。 Denoはnpmなどのパッケージマネージャーが存在しません。 ライブラリを利用するにはライブラリのコードが存在するURLを指定してimportします。 もちろんローカルにあるファイルを相対パスでimportすることも可能です。URLを指定したimportの形式は以下のようになります。

import { hoge } from "https://xxxx/xxx/xxx.ts"

例えば、標準のlogモジュールを利用するときは以下のように書きます。

import * as log from "https://deno.land/std/log/mod.ts";

log.info("hello world");

依存しているモジュールはメインの関数を実行するときに、指定されたURLからローカルにダウンロードされます。 2回目の実行時はURLにはアクセスせず、ローカルのダウンロードを利用します。

ダウンロードされたライブラリの情報を確認するにはdeno infoコマンドを利用します。

$ deno info https://deno.land/std/log/mod.ts
local: /Users/hikaru/Library/Caches/deno/deps/https/deno.land/7b7bfb17fc1c79079c3d96a912a8251e1119834e29a8e8b39636d9e263eeef3d
type: TypeScript
compiled: /Users/hikaru/Library/Caches/deno/gen/https/deno.land/std/log/mod.ts.js
map: /Users/hikaru/Library/Caches/deno/gen/https/deno.land/std/log/mod.ts.js.map
deps:
https://deno.land/std/log/mod.ts
  ├─┬ https://deno.land/std/log/logger.ts
  │ └── https://deno.land/std/log/levels.ts
  ├─┬ https://deno.land/std/log/handlers.ts
  │ ├── https://deno.land/std/log/levels.ts
  │ ├── https://deno.land/std/fmt/colors.ts
  │ └── https://deno.land/std/fs/exists.ts
  ├─┬ https://deno.land/std/testing/asserts.ts
  │ ├── https://deno.land/std/fmt/colors.ts
  │ └── https://deno.land/std/testing/diff.ts
  └── https://deno.land/std/log/levels.ts

メイン関数の実行より前にライブラリをダウンロードしたい場合はdeno cacheコマンドを利用します。

$ deno cache https://deno.land/std/log/mod.ts

ちなみにローカルにダウンロードされたライブラリを更新したい場合は--reloadフラグをつけて、deno rundeno cacheを実行すればいいようです。

GitHubにあるライブラリをimportする

ファイルのURLさえ公開されていればimportが可能なので、GitHubにあるコードもimportが可能です。 ただ、GitHub上のコードをimportするときは一つ注意が必要です。

例えば以下のコードがadd.tsとしてhttps://github.com/hikaru7719/deno-test/blob/master/add.ts のURLに存在します。

export const add = (a: number, b: number) => {
  return a + b;
};

このadd.tsを利用するmain.tsというファイルを以下のように作成したとします。

import { add } from "https://github.com/hikaru7719/deno-test/blob/master/add.ts";

console.log(add(1,1));

このコードをdeno run main.tsで実行するとエラーになってしまいます。

$ deno run main.ts
Compile file:///Users/hikaru/develop/github.com/hikaru7719/deno-test2/main.ts
Download https://github.com/hikaru7719/deno-test/blob/master/add.ts
error: Uncaught TypeError: Cannot resolve extension for "https://github.com/hikaru7719/deno-test/blob/master/add.ts" with mediaType "Unknown".
    at getExtension ($deno$/compiler.ts:218:13)
    at new SourceFile ($deno$/compiler.ts:263:22)
    at Function.addToCache ($deno$/compiler.ts:339:16)
    at processImports ($deno$/compiler.ts:743:31)
    at async processImports ($deno$/compiler.ts:753:7)
    at async compile ($deno$/compiler.ts:1316:31)
    at async tsCompilerOnMessage ($deno$/compiler.ts:1548:22)
    at async workerMessageRecvCallback ($deno$/runtime_worker.ts:74:9)

mediaTypeがUnknownと言われています。

この原因を調べてみると以下のIssueにたどり着きました。

https://github.com/hikaru7719/deno-test/blob/master/add.ts はレスポンスとしてHTMLファイルが返ってきてしまうため、エラーになっているようです。

GitHubのファイルを利用するときはhttps://github.com/hikaru7719/deno-test/blob/master/add.ts ではなく、 https://raw.githubusercontent.com/hikaru7719/deno-test/master/main.ts の形式にしてrawデータが返ってくるようにしなくてはいけないようです。

先ほどのファイルを以下のように変更して実行すると無事動作しました。

import { add } from "https://raw.githubusercontent.com/hikaru7719/deno-test/master/main.ts";

console.log(add(1, 2));

ちなみにhttps://deno.land/std/log/mod.tsなどの標準パッケージのファイルはブラウザでアクセスするとHTML形式で返ってきますが、DenoのCLIなどを利用してブラウザ以外からアクセスするとrawデータが返ってくるようです。(以下のREADME.mdに書いてありました。)

まとめ

Denoのimportについて調べてみました。importが既存のTypeScriptとは若干違うこともあり違和感を覚えましたが、少しずつ慣れていきたいと思います。 今後もDenoについては継続的に調査していきたいと思います。

See Also