初めの一歩

このページでは Deno の基本を理解するためにいくつかの例を扱います。

このドキュメントでは JavaScript の前提知識、特に async/await を知っていることを仮定します。 JavaScript の前提知識がない場合は、Deno を始める前に JavaScript の基本を学ぶとよいでしょう。

Hello World

Deno は JavaScript/TypeScript ランタイムとして、Web と互換性を持たせようとし、また可能ならいつでもモダンな機能を使うようにするよう試みています。

ブラウザとの互換性とはつまり、Deno の Hello World プログラムがブラウザで実行できるそれと同じだということです。

console.log("Welcome to Deno 🦕");

以下のプログラムを実行してみてください。

deno run https://deno.land/std@$STD_VERSION/examples/welcome.ts

HTTP リクエストを作る

多くのプログラムが Web サーバーからデータを取得するために HTTP リクエストを使います。 ファイルを取得してターミナルに出力する小さなプログラムを書いてみましょう。

Just like in the browser you can use the web standard fetch API to make HTTP calls: HTTP リクエストを送るにはブラウザと同様に Web 標準の fetch API が使えます。

const url = Deno.args[0];
const res = await fetch(url);

const body = new Uint8Array(await res.arrayBuffer());
await Deno.stdout.write(body);

このアプリケーションがしていることを一つひとつ確認しましょう。

  1. アプリケーションに第一引数を渡し、定数 url に保存する
  2. URL を指定してリクエストを作成し、レスポンスを待ち、その結果を定数 res に保存する
  3. レスポンスの body を ArrayBuffer, としてパースして結果を待ち、それを Uint8Array に変換して定数 body に保存する
  4. body の中身を stdout に書き込む

次のプログラムを実行してみてください。

deno run https://deno.land/std@$STD_VERSION/examples/curl.ts https://example.com

実行するとわかりますが、このプログラムはネットワークアクセスがあってもなくてもエラーを返します。何か間違えたのでしょうか? 初めに Deno がデフォルトで安全なランタイムだと紹介したのを覚えているかもしれません。これはつまり、 ネットワークアクセスのようなある「特権的な」操作を行うために明示的な許可を与える必要があるということです。

正しい許可フラグを与えてもう一度実行してみましょう。

deno run --allow-net=example.com https://deno.land/std@$STD_VERSION/examples/curl.ts https://example.com

ファイルを読み込む

Deno は Web に由来しない API も提供しています。それらはすべて Deno というグローバル変数に含まれています。 この API ドキュメントは doc.deno.land にあります。

たとえばファイルシステム API は Web 標準の仕様がないため、Deno が独自で API を提供しています。

以下のプログラムは、コマンドライン引数をファイル名として、ファイルを開いて標準出力に表示します。

const filenames = Deno.args;
for (const filename of filenames) {
  const file = await Deno.open(filename);
  await Deno.copy(file, Deno.stdout);
  file.close();
}

ここで copy() 関数はカーネル→ユーザースペース→カーネルのコピーに必要なこと以外はしていません。 言い換えると、ファイルから読んだデータを保持しているメモリからそのまま標準出力に書き込まれます。 これは Deno の I/O ストリームに関する一般的な設計目標を表しています。

以下のプログラムを実行してみてください。

deno run --allow-read https://deno.land/std@$STD_VERSION/examples/cat.ts /etc/passwd

TCP サーバー

以下は 8080 番ポートで接続を待ち受けるサーバーの例です。クライアントが送ってきたデータをそのまま返します。

const hostname = "0.0.0.0";
const port = 8080;
const listener = Deno.listen({ hostname, port });
console.log(`Listening on ${hostname}:${port}`);
for await (const conn of listener) {
  Deno.copy(conn, conn);
}

セキュリティ面の理由から、Deno のプログラムは明示的な許可なしでネットワークにアクセスできません。 ネットワークアクセスを許可するにはコマンドラインでフラグを与えます。

deno run --allow-net https://deno.land/std@$STD_VERSION/examples/echo_server.ts

サーバーをテストするために、netcat を使ってデータを送ってみてください。

$ nc localhost 8080
hello world
hello world

cat.ts の例のように、ここでも copy() 関数は不必要なメモリのコピーを作りません。 カーネルから受け取ったパケットを送り返すだけです。

他の例

HTTP ファイルサーバーのような他の例は Examples の章で扱います。