Deno がもうそこまで来ているらしいので、始めてみた。
はじめに
「"Deno"分からないとイケてないエンジニア認定されている時代が来るかも...」なんて話を社内で聞きました。
実際に MDN でも Node.js と並んで Deno がいるではありませんか。
そこで慌ててチュートリアルをしたり GraphQL サーバーを作ったりしつつ Deno とはどんな Runtime なのか、Node.js と比較してみました。
TL;DR
Deno は以下の特徴を持つ JavaScript、TypeScript そして WebAssembly のランタイムである。
- TypeSciprt を JavaScript や WebAssembly と同じように、特に追加でインストールしたり設定したりすることなく利用できる。
- TypeScript の型の恩恵を受けつつも、型チェックのオーバーヘッドをなくす工夫がされている
- url import を採用しており、dependencies を分散的に管理できるようになっている
- ファイルの読み込みやネットワークへのアクセス制限といったセキュリティ制御を Runtime レベルでしてくれる
Deno のはじめ方
を参考に Deno を起動してスクリプトを実行してみます。
インストール方法
以下のコマンドで Deno をインストールします。
# macOS, Linux
curl -fsSL https://deno.land/x/install/install.sh | sh
# Windows (PowerShell)
irm https://deno.land/install.ps1 | iex
開発環境の設定 (VSCode)
Deno という VSCode 拡張機能をインストールします。
その後 VSCode の Command Palette (cmd + shift + P) から Deno: Initialize Workspace Configuration
を実行し Deno の開発環境をセットアップします。
こうすることで、Language Server に接続され補完などが有効化されます。
※ Node.js など他のランタイムを使いたい時には "deno.enable" フラグを False に設定する必要があります。
実行してみる
Deno では複数のスクリプト取得方法があります。
- path を指定する
deno run main.ts
- URL を指定する
deno run https://mydomain.com/main.ts
- 標準入力を利用する
cat main.ts | deno run -
URL を指定する方法で Deno by Example にある hello world を実行してみます。
deno run https://examples.deno.land/hello-world.ts
Hello, World!
では次に file を読み込むサンプルを実行してみます。
# reading-files サンプルで読み込む対象の hello.txt を作成する
echo "Hello from local!" > hello.txt
deno run https://examples.deno.land/reading-files.ts
すると
┌ ⚠️ Deno requests read access to "hello.txt".
├ Requested by `Deno.readFile()` API.
├ Run again with --allow-read to bypass this prompt.
というような警告文が出ます。
Deno ではデフォルトでファイルやネットワークなどにアクセスできないようになっており、コマンド実行時に明示的にアクセスを許可する必要があります。
deno run --allow-read https://examples.deno.land/reading-files.ts
警告文の通りファイルの読み込みを許可すると無事実行できます
Read 5 bytes
Seeked to position 6
Read 2 bytes
Modules について
Deno では現在以下の機能を標準ライブラリとして提供しています。
dotenv や file の読み込み、http サーバーなどが提供されています。
また 3rd party のライブラリも提供されています。
ちなみに Node.js のパッケージへの互換性もあります。
以下の方法で Node.js のパッケージを読み込むことができます。
-
import {} from "npm:prisma@^5.2.0"
のようにnpm:
識別子を利用して import する - package.json をそのまま読み込める機能を利用する https://docs.deno.com/runtime/manual/node/package_json
- CDN を利用する https://docs.deno.com/runtime/manual/node/cdns
Node.js との特徴的な違い
上記に加えて、GraphQL サーバーを Deno で作るのに挑戦してみました。
その中で気づいた Node.js との特徴的な違いについて 3 点ほど挙げさせていただきます。TypeScript の扱い
上記のページに書かれていますが Deno では TypeScript を JavaScript と同等の言語として扱っています。つまり typesciprt ライブラリをインストールして、tsconfig を書いて ... といった作業が不要になるということです。
また、実行時には型のチェックをスキップするのがデフォルトになっています。
この仕様により型チェックのオーバーヘッドなく実行することができます。
ちなみに
deno check https://examples.deno.land/reading-files.ts
のように check コマンドで型チェックはできます。
ライブラリの Import の仕方
Deno では中央集権的に dependecies を管理する必要がなくなっています。
つまり 3rd party アプリに関しても、利用者がすべての dependecies を把握する必要がなくなります。
また URL を指定して実行するので実行者側で手元にダウンロードする必要がないという特徴もあります。(node_modules 的な存在が不要になっているということです。)
とはいっても url import だとファイルそれぞれで import を書く必要があるので手間です。
そこで Deno では Import Maps という機能が提供されており、deno.json
上で import を集約することができます。
{
"imports": {
"fmt/": "https://deno.land/std@0.204.0/fmt/"
}
}
import { red } from "fmt/colors.ts";
Security に対してのアプローチ
実行する際に --allow-read
をつけないとファイルが読め込めないという例がありました。そのほかにもいくつかピックアップすると Deno では以下のようなオプションがあります。
option | 説明 |
---|---|
--allow-env={ENV_NAME} | 環境変数へのアクセス許可 |
--allow-net={IP/HOSTNAME} | ネットワークへのアクセス許可 |
--deny-write={FILE_PATH} | ファイルへのアクセスを拒否 |
ちなみに -A
--allow-all
ですべてのアクセスを許可することもできます。
このアプローチは dependecies に対してすべてのアクセスを許可している Node.js とかなり違うポイントになります。
感想
実は GraphQL サーバー を作る中で PostgrSQL 周りで困ったりしました。いい感じに基盤はできていますが、まだまだ枯れてはいない感じで参加するには面白そうな感じがします。
また、Runtime にセキュリティが考慮されていたり URL で実行できたりするので Edge computing やイベント駆動アーキテクチャと組み合わせると使い心地が良さそうに思いました。AWS Lambda や CloudFront とかで導入されるのが楽しみです。
とはいえ、実際はインフラレベルでセキュリティは制御する気もするので、どんな感じで活用するのがベストプラクティスなのかは引き続きウォッチしていきたいです。
Discussion