1. HOME
  2. ブログ
  3. IT技術
  4. Deno(ディーノ)を使ってみよう!【Node.jsの時代は終わる?】

Deno(ディーノ)を使ってみよう!【Node.jsの時代は終わる?】

Deno(ディーノ)とは

Deno(ディーノ)は、Node.js の開発者である Ryan Dahl によって作られた、新しいJavaScript/TypeScriptランタイムです。

Dahl 氏が、Node.js の欠点を認め、反省点を踏まえて作られたのが Deno です。

v1.0.0 が、2020年5月13日にリリースされたので、Denoで簡単なコードを実行し、使い勝手を確認してみましょう。

こちらの記事もオススメ!

Denoの特徴

まずは公式サイトを確認してみましょう。

【Deno 公式サイト】
https://deno.land

Deno のアピールポイントとして、次のような特徴が書かれています。

  1. デフォルトでセキュアであり、ファイル・ネットワーク・環境変数へのアクセスには明示的な許可が必要
  2. 標準で TypeScript をサポート
  3. 単一の実行可能ファイルのみを発行可能
  4. 依存関係インスペクタ(deno info)やコードフォーマッタ(deno fmt)などの組み込みユーティリティを提供
  5. Deno での動作が保証されている標準モジュールを提供

ひとまず「そういうもの」と、心の片隅に置いて使ってみましょう。

使っていくうちに、どのようなものか実感できると思います!

Deno をインストール

さっそく Deno をインストールしましょう!

Linux 環境を例に説明します。

公式サイトのトップページにあるとおり、「curl」コマンドでインストールします。

HTTP 通信を使用するため、インターネットに接続している必要があります。

コマンドを実行

ターミナルで次のコマンドを実行しましょう。

インストール時のメッセージ

インストールに成功すると、次のようなメッセージが出力されます。

パスを実行

親切にパスを通す方法が書いてありますので、そのとおりに実行しましょう。

Deno を実行できるか確認

Deno を実行できるか確認してみましょう。

次のコマンドを実行します。

Deno のバージョンが表示されたら環境作りは成功です。

次は、簡単なスクリプトを実行してみましょう。

Hello World

実際に、簡単なコードを動かしてみます。

hello.ts を作成

次の内容のファイル「hello.ts」を作りましょう。

文字列を標準出力するだけのスクリプトです。

Node.js と同様に console.log で標準出力が可能です。

コマンドで実行

deno run コマンドによって実行します。

実行結果

実行結果を確認しましょう。

次のような結果が出力されれば成功です。

初回のみコンパイルを実行し、1行目に “Compile {ファイル名}” といったメッセージを表示します。

2回目以降の実行では、2行目の “Hello World!” のみ出力します。

次のように、-q オプションを付けることにより、コンパイルのメッセージを表示させないことも可能です。

コマンドライン引数の取得

実行時に指定したコマンドライン引数を、受け取ってみましょう。

コマンドライン引数を取得するには、配列 Deno.args を使います。

argsTest.ts を作る

次の内容のファイル「argsTest.ts」を作りましょう。

取得したいのは、次の例でいう「testです」になります。

実行結果

実行結果を示します(以降、コンパイルメッセージは省略します)。

正常に取得できています。

特に難しいことはありませんが、Node.js の process.argv に慣れていた人は、配列添え字に注意が必要です。

Node.jsのコマンドライン引数

参考までに、Node.js での process.argv を使ったコマンドライン引数取得について説明します。

こちらも配列ですが、最初の要素が「node コマンド自体」、次が「ファイル名」となり、「コマンドライン引数」は 3 番目以降に格納されます。

「testです」を取得したい場合

例えば、次のコマンドを実行した場合の「testです」を取得したいとします。

Node.js のコードは次のようになります。

process が持つ argv[0] は「node」、 argv[1] は「argsTest.js」となり、「testです」が格納されるのは argv[2] となります。

実践的なコードを書いてみよう

Deno のコードを実行する方法は分かりました。

ここからは、少し実践的なコードをいくつか書いてみましょう

ファイル入出力

標準モジュールでのファイル入出力を試します。

ファイル入出力用モジュールはこちらです。

【Deno 標準ライブラリ】
https://deno.land/std/fs

まずはテキストファイルを出力してみましょう。

writeFileTest.ts を作成

次の内容のファイル「writeFileTest.ts」を作りましょう。

ファイル読み込み用のモジュールを読み込み、変数 message に文字列を格納、最後にその内容を「sample.txt」に書き出しています。

Node.js でいうところの「npm」に相当する仕組みは無く、URL(またはパス)によってモジュールを指定します。

https://deno.land/std/fs を開くと、配下にどのようなモジュールがあるか確認できます。

まとめてインポートしたいときは、モジュールのエントリーファイルである「mod.ts」を指定すればよいでしょう。

ここでは「write_file_str.ts」だけで事足りるため、個別にインポートしました。

実行

では実行してみましょう。

エラーが発生しました

「ファイルに対して書き込みアクセスを行うならば –allow-write フラグとともに実行してください」と書いてあります。

エラーを修正し実行

言われたとおり、–allow-write フラグを追加して実行してみましょう。

今度は実行できました

「ls」コマンドなどで確認し、「sample.txt」が作られていれば成功です。

これが Deno の公式サイトに書いている「ファイル・ネットワーク・環境変数へのアクセスには明示的な許可が必要」ということです。

「ファイルへの書き込みアクセスを許可する」と明示する必要

今回実行したのは、ファイル出力を含んだコードでしたので、実行時にそれを明示的に許可する必要がありました

たとえば、どこかからコードを拝借し、中身を確認せずに実行しても「ファイルへの書き込みアクセスを許可する」と明示しない限りはファイル出力は行われません。

ファイルを読み込む

書き出しに成功しましたので、次は出力したファイルを読み込んでみましょう。

次の内容のファイル「readFileTest.ts」を作りましょう。

ファイル読み込み用のモジュールを読み込み、変数 message にファイルの内容を格納、 message を標準出力するという流れです。

実行

実行時には –allow-read フラグによって読み込みを許可する必要があります。

正常にファイルの内容が取得できました。

「トップレベル await」

書き込み/読み込みともに、「async」で宣言した関数内ではないのに await を使っています。

Deno は、最上位の階層で await を使うことが可能です。

これは「トップレベル await」と呼ばれます。

await を使うために、async 関数を作る必要はありません。

Node.js も v14.3.0 から「トップレベル await」が可能になっています。

環境変数へのアクセス

テストと本番で使う値を変えるために、環境変数を使うのが便利です。

「.env」 というファイルを作成し、次の内容を記述します。

では Deno で、これらの値を取得してみます。

値を取得する

サードパーティー製の「dotenvモジュール」を使用します。

「envTest.ts」として、次の内容を記述します。

実行

実行には –allow-env で環境変数へのアクセスを許可して実行します。

環境変数 GREETING の値が取得できました。

他の記述の仕方

環境変数へのアクセスは、次のようにも記述できます。

標準モジュールは、https://deno.land/std にありましたが、サードパーティーのモジュールは https://deno.land/x にあります。

ここでは、https://deno.land/x/dotenv を使いました。

環境変数へのアクセス用に、 env というオブジェクトを作成します。

こちらを実行するには –allow-env ではなく –allow-read フラグが必要になります。

データベースアクセス

データベースから情報を取得してみましょう。

ここでは MongoDB を使います。

dbAccessTest.ts を作成

次の内容のファイル「dbAccessTest.ts」を作りましょう。

DBユーザ名、パスワード、ホストなどは「.env」に記述されているものとします。

MongoDB はコレクションにドキュメントを保存する際に、”_id” というプロパティに ObjectID を自動的に付与します。

その ObjectID によって保存されているドキュメントを1件取得する例です。

何もフラグを付けずに実行しようとすれば、その都度コンソールにどんな権限が足りないかのエラーメッセージを表示するので、与えるフラグはすぐにわかります。

実行するコマンド

実行するためのコマンドは次のようになります。

dbAccess.ts 内では Read しか実行していませんが、コレクションに対して、Create、Update、Delete の操作を実行する可能性もあるためか、–allow-write なども必要になるようです。

標準出力

実行すると、 findOne によって検索した結果にヒットする1件を標準出力します。

HTTPサーバ化

HTTP リクエストを受け付け、要求されたパスに応じてレスポンスを返してみましょう。

serverTest.ts を作成

次の内容のファイル「serverTest.ts」を作りましょう。

なお、「serverTest.ts」と同じ階層にある「views」フォルダの下に「index.html」があるものとします。

‘/’ に対して GET リクエストがあった場合のみ、./views/index.html の内容をレスポンスとして返します。

ネットワークアクセスを行うため、実行時には –allow-net フラグが必要です。

また、./views/index.html ファイルを読み込むため、 –allow-read フラグも必要です。

実行

次のコマンドで実行します。

実行すると、3000 番ポートで HTTP リクエストを受け付けます。

http://localhost:3000/ にブラウザでアクセスすれば、./views/index.html を表示します。

それ以外のパスへのリクエスト、あるいは GET ではないリクエストでは、ステータスコード 404 とともに、”not implemented” というテキストをレスポンスとして返します。

サーバは Ctrl+C で停止させます。

opine によるルーティング

Deno でも「Express」のようなルーティングが可能です。

opine モジュールを利用します。

opineTest.ts を作成

次の内容のファイル「opineTest.ts」を作りましょう。

最初の3行を除けば、「Express」を利用して Node.js で記述するのとほぼ同じです。

「Express」に慣れていれば馴染みやすいでしょう。

実行

次のコマンドで実行します。

sendFile によってファイルの内容をレスポンスにしていますが、意外なことに –allow-read フラグなしで実行できました

実行したら、ブラウザでそれぞれのパスにアクセスして挙動を確認してみましょう。

opine で指定できるルート・パス

opine で指定できるルート・パスについて、Express と同じではありますが補足しておきます。

ルート・パスには文字列の他に正規表現が指定可能です。

また、コロンを使ってルートパラメータを取得することも可能です。

opineTest.ts を作成

次の内容のファイル「opineTest.ts」を作りましょう。

これについても Express と同じです。

fetchによるリクエスト

Deno は、ブラウザで使える Web API のひとつである Fetch API がそのまま利用可能です。

Fetch API については MDN に詳しく記述されています。

【MDN :Fetchを使う】
https://developer.mozilla.org/ja/docs/Web/API/Fetch_API/Using_Fetch

これを Deno で試してみます。

fetchTest.ts を作成

次の内容の「fetchTest.ts」ファイルを作りましょう。

1行目の URL はダミーですので、送信したいリクエスト先に適宜書き換えてください

あとは適当なオプションを指定して GET リクエストを送信し、レスポンスを取得するだけです。

実行

–allow-net フラグを付けて実行します。

リクエスト先が存在すれば、これでレスポンスが取得できます。

Fetch API さえ知っていれば、新しい知識がなくても HTTP 通信が可能です

Denoのその他の特徴

最後に Deno の特徴を他にも少しだけ紹介します。

標準機能でテストが可能

はじめから Deno にはテストの仕組みが備わっています

外部モジュールを使用しなくても、Deno.test によってテストを行うことが可能です。

次のような「testTest.ts」を用意します。

deno test によって実行

このスクリプトを、deno run ではなく、deno test によって実行します。

実行結果

実行結果は次のとおりです。

変数の値が期待どおりであることが確認できました。

Uncaught Exceptionでは処理を終了する

Node.js では、process にイベントを定義することにより、Uncaught Exception が発生した際の挙動を制御できました。

例えば次のように記述します。

このときに process.exit を実行しなければ処理を継続することが可能です。

ですが、Deno ではその機能が無く、処理は終了してしまうようです

モジュールのバージョン指定

モジュールをインポートする際には、次のように書きました。

このとき、使用するモジュールを特定のバージョンに限定したい場合は、”@” を使って次のように記述することができます

さいごに

Deno の機能について、取り留めなく書き連ねましたが、どのような印象を持たれたでしょうか。

個人的な感想としては、現時点でもかなり使えそうだと思いました

Node.js に慣れていれば、それほど違和感なく使えるはずです。

一部の機能については、Node.js よりも優れているとも感じました

もしかすると Deno の時代は、案外早く訪れるのかもしれません。

ぜひ皆さんも、Deno の使い勝手を確かめてみてください!

(株)ライトコードは、WEB・アプリ・ゲーム開発に強い、「好きを仕事にするエンジニア集団」です。
JavaScriptでのシステム開発依頼・お見積もりはこちらまでお願いします。
また、JavaScriptが得意なエンジニアを積極採用中です!詳しくはこちらをご覧ください。

※現在、多数のお問合せを頂いており、返信に、多少お時間を頂く場合がございます。

こちらの記事もオススメ!

ライトコードよりお知らせ

にゃんこ師匠にゃんこ師匠
システム開発のご相談やご依頼はこちら
ミツオカミツオカ
ライトコードの採用募集はこちら
にゃんこ師匠にゃんこ師匠
社長と一杯飲みながらお話してみたい方はこちら
ミツオカミツオカ
フリーランスエンジニア様の募集はこちら
にゃんこ師匠にゃんこ師匠
その他、お問い合わせはこちら
ミツオカミツオカ
   
お気軽にお問い合わせください!せっかくなので、別の記事もぜひ読んでいって下さいね!

一緒に働いてくれる仲間を募集しております!

ライトコードでは、仲間を募集しております!

当社のモットーは「好きなことを仕事にするエンジニア集団」「エンジニアによるエンジニアのための会社」。エンジニアであるあなたの「やってみたいこと」を全力で応援する会社です。

また、ライトコードは現在、急成長中!だからこそ、あなたにお任せしたいやりがいのあるお仕事は沢山あります。「コアメンバー」として活躍してくれる、あなたからのご応募をお待ちしております!

なお、ご応募の前に、「話しだけ聞いてみたい」「社内の雰囲気を知りたい」という方はこちらをご覧ください。

ライトコードでは一緒に働いていただける方を募集しております!

採用情報はこちら

関連記事