deno で遊んでみよう
https://3.bp.blogspot.com/-h1WdT1D_PfU/UUQ0nInZ8tI/AAAAAAAAO20/HkcRSqNaMvk/s400/Brachiosaurus.png
deno とは
Node.js のときに得た教訓をもとに設計がされていますが、Node.js と互換性のある実装というわけではありません。
JavaScript のエンジン自体は Node.js と同じく V8 を利用しています。 2020-05-13 にめでたく v1.0 がリリースされたので今回ちょっとだけ遊んでみることにします。
Node.js との違い
たくさんありますが大きな違いだけ。
TypeScript が標準でサポートされる
簡単なものであれば tsconfig.json の用意はしなくて良い
パッケージの取得はソースコードの import 文をもとに deno が実行時に取得する
スクリプトはすべて ES Module 方式になっている
npm や yarn のようなパッケージマネージャは今の所不要
バージョニングは URL をベースに行う
ファイルアクセスやネットワークなどのセキュリティフラグがいくつかある
実行時に指定したもの以外は基本的にブロックされる
細かなところは公式サイトをご覧ください。
セットアップ
deno はシングルバイナリで動作するランタイムなので Github の Releases から取得した zip を展開して得られる実行ファイルをパスの通ったところに配置すれば直ぐに利用ができます。
公式ではこの作業を簡略化するための deno_install というプロジェクトが立ち上がっておりワンライナーでインストールが可能です。 Linux / WSL / MacOS
curl -fsSL https://deno.land/x/install/install.sh | sh
MacOS
brew install deno (確認時点ではLinuxBrewには非対応)
Cargo
cargo install deno
インストール後はパスを通したりするよう指示が出たりしますが適切に対処しましょう。
正しくインストールされていればバージョン情報を確認できるようになっています。
TypeScript のバージョンまで出てるのが斬新ですね。
code:version
❯ deno --version
deno 1.0.0
v8 8.4.300
typescript 3.9.2
初めての deno
公式にリモートからコードを取得して直接実行するサンプルが用意されていますので試しに実行してみましょう。
deno run https://deno.land/std/examples/welcome.ts
実行すると下記のような出力を得ます。見たらわかりますが、リモートのURLを直接実行することができ、スクリプトがコンパイルされ実行されていますね。
code:stdout
Welcome to Deno 🦕
https://gyazo.com/b744ada92f3e51bcc9ada25370617bf3
あっけなく終わってしまいましたが deno のスクリプトを実行する事ができました。
ここまででは Node.js をインストールして サンプルスクリプトを実行したのとあまり大差ないのでもう少し遊んでみましょう。
deno をより体感する
続いても公式サイトにあるサンプルスクリプトを利用します。(自分好みにスタイルを変更しています)
下記のファイルをダウンロードするか写経して server.ts として保存しましょう。
code:server.ts
const s = serve({ port: 8000 })
for await (const req of s) {
req.respond({ body: 'Hello World 🦕\n' })
}
早速実行してみます。
code:server.tsの実行結果(bash)
❯ deno run ./server.ts
Compile file:///path/to/workspace/server.ts
...
error: Uncaught PermissionDenied: network access to "0.0.0.0:8000", run again with the --allow-net flag
at unwrapResponse ($deno$/ops/dispatch_json.ts:43:11)
at Object.sendSync ($deno$/ops/dispatch_json.ts:72:10)
at Object.listen ($deno$/ops/net.ts:51:10)
at listen ($deno$/net.ts:152:22)
at file:///path/to/workspace/server.ts:2:11
ぞろぞろとパッケージが取得されていき、実行されるかと思いきやエラーになりました。
これは最初に説明した deno のセキュリティ機構によるもので、deno run したときに許可した権限以上の処理ができないようになっています。
今回の場合、サーバーアプリケーションを起動するために必要なネットワークに対する権限が実行時に付与されていないので、権限が足りないよということを指摘されています。
ということで、--allow-net をフラグに指定して権限を追加してリトライしてみると今度はうまく起動してくれました。
試しに curl でアクセスしてみると Hello World の出力を得ることができます。
code:server.tsの実行結果(bash)
❯ deno run --allow-net ./server.ts &
❯ curl localhost:8000
Hello World 🦕
このようにして無事Webサーバーアプリケーションを deno で作って動作させることができました。
ちなみに流れで server.ts を保存しましたが最初の HelloWorld と同じく Scrapbox の API 経由でスクリプトを直接指定して実行するような使い方もできます。
ライブラリやエコシステムについて
deno には npm や yarn といったパッケージマネージャが現時点では存在していません。
ここまでやってきたように、deno の標準パッケージも含め、必要な外部ライブラリの類はすべて実行時にリモートから取得される仕組みになっています。
加えて、deno では中央集権的なパッケージリポジトリは存在しておらず、代わりにスクリプトが HTTP でアクセス可能な場所に配置されていればそれを利用することが可能なようになっています。そのため、ライブラリの公開や利用については GitHub Pages や pika.dev or jspm.io などの CDN を利用して手軽に誰でも公開することができます。 これは Node.js において npm が実質的に中央集権的なパッケージリポジトリとなってしまったことに基づく設計だそうで、「Node.jsに関する10の反省点」でも言及されています。
https://www.youtube.com/watch?v=M3BM9TB-8yA
この方式においては npm を探して必要なパッケージを見つけるというスタイルが失われてしまいますが、それを防ぐ取り組みとして deno.land/x でパッケージを探せる仕組みが提供されています。これはパッケージそのものをホスティングしているのではなく、あくまで電話帳のような仕組みなので deno.land/x を利用してやりたいことに対応するパッケージを探したりここから利用することができるようになっています。 まとめ
この度めでたく v1.0 がリリースされた deno でちょっとだけ遊んでみました。軽く触っただけでも Node.js との違いがちょっとだけわかった気がします。今後、3rd Party ライブラリがより充実したりなど、エコシステムが拡充されてくるとより輝いてくるのではないかと期待しています。
何より標準で TypeScript が実行できる状態にあるというのが TypeScript 大好きクラブ 会員としては最高だなーという印象です。
Node.js との棲み分けや移行についてが気になるところですが、少なくとも Node.js のライブラリが今すぐそのまま deno でも使えるというわけでもないので、徐々に両対応するライブラリが出てきたり(ky のようなライブラリは両対応をすでに実現しています)、deno 専用の革新的な何かが出てきたりすることを期待しています。(deno版のElectronに相当するなにかとか) これから普段遣いしていくぞというところも v1.0 のお墨付きがあるので、単純に書き捨てのスクリプトを TypeScript で書くという用途においてはもう deno でやったほうが手軽さがあるのではないかな思ったりしました。