Top View


Author k-masatany

Deno を触ってみた

2021/08/26

What's Deno

Deno は V8 エンジンと Rust で構築されたモダンな JavaScript および TypeScript 用のランタイムです。

公式サイトは下記になります。

マスコットキャラクターが可愛いですね。

公式サイトのトップページには Deno の特徴が記載されており、下記のような特徴があるようです。

  • デフォルトでセキュア。ファイル、ネットワーク、環境変数などへのアクセスには明示的な許可が必要
  • 標準で TypeScript をサポート
  • 単一の実行ファイルを出力可能
  • 依存関係の検査や、コードフォーマッタがデフォルトで組込まれている
  • Deno での動作が保証された標準モジュールが提供されている

フォーマッタや標準ライブラリの提供がされていると、余計なことを考えなくて良いので、個人的には非常に好感が持てます。

それでは、さっそく Deno を触っていきましょう。

Install

まずは公式サイトに従って Deno のインストールを行います。 筆者の検証環境は下記の通りです。

MacBook Pro 2016 13-inch
macOS 11.5.1 (Big Sur)
デュアルコア Intel Core i7 3.3GHz
・16GB メモリ

筆者は Mac を使っているので、brew でインストールします。

$ brew install deno

しばらく待つと無事にインストールされました。

$ deno --version

deno 1.13.0 (release, x86_64-apple-darwin)
v8 9.3.345.11
typescript 4.3.5

触ってみる

Deno が無事にインストールできたので、公式サイトの First steps に従って Deno を触っていきます。

Hello World

まずは Hello World から始めてみます。

Denoは、JavaScript/TypeScript用のランタイムなので、下記のコードで標準出力が可能です。

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

このコードを sample.ts として保存。実行してみます。

$ deno run sample.ts

Welcome to Deno!

無事に Deno の世界に Hello world できました。

HTTP リクエストを投げてみる

次に、外部のサーバーに対して HTTP リクエストを投げるコードを試してみます。

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

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

第1引数に URL を指定してやると、そのサイトの body を取得して標準出力に書き出してくれるようです。 早速実行してみます。

$ deno run sample.ts https://example.com

error: Uncaught PermissionDenied: Requires net access to "example.com", run again with the --allow-net flag
const res = await fetch(url_);
                  ^

怒られてしまいました。 これは、Deno はデフォルトではネットワークリソースにアクセスすることができないためです。 指示に従ってオプションを付けて実行してみます。

$ deno run --allow-net sample.ts https://example.com

<!doctype html>
<html>
<head>
    <title>Example Domain</title>
    ~ 中略 ~
</html>

無事に example.com のサイトが取得できました。

ファイル読み込み

次は、ファイルを読み込むサンプルを実行してみます。

import { copy } from "https://deno.land/std@0.106.0/io/util.ts";
const filenames = Deno.args;
for (const filename of filenames) {
  const file = await Deno.open(filename);
  await copy(file, Deno.stdout);
  file.close();
}

このファイルの引数に sample.ts を与えて、自分自身を読み込むようにしてみます。 ファイルの読み込みには --allow-read フラグが必要になるので、忘れないように付加して実行します。

$ deno run --allow-read sample.ts sample.ts

import { copy } from "https://deno.land/std@0.106.0/io/util.ts";
const filenames = Deno.args;
for (const filename of filenames) {
  const file = await Deno.open(filename);
  await copy(file, Deno.stdout);
  file.close();
}

無事にファイルの内容を読み込むことができました。

TCP サーバー

最後に、Deno を使って TCP サーバーを立てるサンプルを実行してみます。 再度公式サイトからサンプルコードを複製してきます。

const listener = Deno.listen({ port: 8000 });
console.log("http://localhost:8000/");
for await (const conn of listener) {
  (async () => {
    const requests = Deno.serveHttp(conn);
    for await (const { respondWith } of requests) {
      respondWith(new Response("Hello world"));
    }
  })();
}

このコードを sample.ts として保存。実行してみます。 こちらも、ネットワーク機能を利用するので、実行時に --allow-net オプションが必要になります。

$ deno run --allow-net sample.ts

http://localhost:8000/

サーバーが 8000 番ポートで実行されるので、ブラウザからアクセスしてみます。

hello tcp server

無事に Deno の世界に Hello world できました。

最後に

Deno を軽く触ってみて、意外とすんなりとネットワークやファイルを取り扱かうことができて感動しています。

筆者自身はバックエンドで PHP を書いている人間なので、これが js/ts でどのくらいシンプルなコードなのか判断できていないですが、書き味はシンプルで好みです。

今回はチュートリアルの一部を実行してみただけですが、引き続き、フォーマッタやシングルバイナリ出力も試してみようと思いました。

では、皆様もよい Deno ライフを。

k-masatany

k-masatany

Twitter X

インターネットの海で泳ぐときは、だいたいペンギンの姿をしています。