Node.jsの作者であるRyan Dahlが新たに開発した「Deno(ディーノ)」のv1.0がリリースされました
初めて触ってみたので過程を記事で共有します
Denoの特徴は
- 設定なしですぐ動くTypeScriptとJavaScriptの実行環境
- package.jsonの代わりにTSファイルのURLがエントリーポイント
- 標準モジュールが豊富でインストールとキャッシュ管理も自動
- ファイルやネットワークへのアクセスがデフォルトでは禁止されていてセキュア
- コードフォーマッタやテストライブラリも標準装備
最初のコミットはちょうど2年前
インストールの前に、ふと思い立って3,400以上もあるコミットの始まりを探してみました
Ryan Dahlによる最初のコミットは2018/05/14(多分NY時間だと13日)でした
ピッタリ2年目ということで2020/05/14(NYでは13日)をリリース日に決めたのでしょうね
Init - denoland/deno@f7c5e19
コミットファイルは
- main.go
- main.ts
- package.json
- tsconfig.json
DenoはGolang+TypeScript+package.jsonから始まったんですね
現在はRust+V8で構築されているようです
凄まじい進化を感じます・・・
インストール
Mac/Linux
curl -fsSL https://deno.land/x/install/install.sh | sh
MacならHomebrewもいいですね
brew install deno
Windows
iwr https://deno.land/x/install/install.ps1 -useb | iex
私はWindows10なのでPowerShellを使いました(PowerShellは標準でインストール済み)
だいたい20秒くらいでサクッと終わりました
インストールが終わったらバージョン確認コマンドを打ってみましょう
Vは大文字です
deno -V
# deno 1.0.0
Hello, world!
Denoはコマンドラインで即座にTypeScriptファイルを実行することができます
公式ドキュメント通りに「welcome.ts」を実行してみます
deno run https://deno.land/std/examples/welcome.ts
10秒くらいダウンロードに時間がかかって結果が表示されました
この点々は一体何なのだ・・・と思ってコピペしてみたら正体がわかりました
Welcome to Deno 🦕
PowerShellはサロゲートペアに対応してないようです
ソースコードはどうやって確認できるのか気になりましたが、よく考えたらURLを実行しているだけなのでChromeで開いてみれば良さそうです
Deno - welcome.ts
恐竜くんがいました、かわいいですね
パンくずをたどるとわかりますが、他にもサンプルコードが色々あります
Deno - examples
ソースコードのキャッシュ
同じコマンドを再度実行してみたらさっきとは様子が変わりました
ダウンロードが発生せず、即座に結果が表示されたのです
一度実行したファイルはキャッシュされているのでしょう
C:\Program Files\deno
あたりにディレクトリがあるのかなーと思って探したけど全く見当たらず
PATHで確認したらユーザーディレクトリ直下に.deno
ディレクトリがありました
※追記:実はインストール完了時にちゃんとインストール先ディレクトリが表示されていました・・・
Denoの本体サイズは35MBくらいなんですね
ちなみにNode.jsは本体28MB+node_modules(npm含む)
ただしここにはキャッシュファイルが見当たりませんでした
ユーザーディレクトリにDenoがいるということはAppData
が怪しいですね
ありました
console.log("Welcome to Deno 🦕");
{
"headers": {
"vary": "Authorization,Accept-Encoding",
"expect-ct": "max-age=604800, report-uri=\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\"",
"x-cache": "MISS, HIT",
"etag": "W/\"bbb\"",
"access-control-allow-origin": "*",
"x-deno-warning": "Implicitly using master branch https://deno.land/std/examples/welcome.ts",
"strict-transport-security": "max-age=31536000",
"source-age": "18",
"x-content-type-options": "nosniff",
"x-github-request-id": "F2A4:7E16:F5937:107258:5EBC7818",
"x-xss-protection": "1; mode=block",
"cache-control": "max-age=300",
"server": "cloudflare",
"content-type": "application/typescript; charset=utf-8",
"cf-request-id": "aaa",
"date": "Thu, 14 May 2020 01:50:20 GMT",
"expires": "Thu, 14 May 2020 01:55:20 GMT",
"cf-cache-status": "DYNAMIC",
"x-cache-hits": "0, 1",
"x-fastly-request-id": "zzz",
"x-frame-options": "deny",
"set-cookie": "__cfduid=xxx; expires=Sat, 13-Jun-20 01:50:20 GMT; path=/; domain=.deno.land; HttpOnly; SameSite=Lax; Secure",
"cf-ray": "111-NRT",
"x-timer": "S1589421020.086214,VS0,VE164",
"via": "1.1 varnish (Varnish/6.0), 1.1 varnish",
"content-security-policy": "default-src 'none'; style-src 'unsafe-inline'; sandbox",
"x-served-by": "cache-hnd18736-HND"
},
"url": "https://deno.land/std/examples/welcome.ts"
}
実行したいファイルのURLをmetadata.jsonのurlから探してマッチしたら同名ファイルのTypeScriptを実行する方式になっているのだろうか・・・と思いながらググってたら便利なコマンドがありました
deno info
# Show info about cache or info related to source file
私が見ていたのはRemote modules cache
でした・・・
コマンド実行の際に参照しているのは恐らくTypeScript compiler cache
の方です
"use strict";
console.log("Welcome to Deno 🦕");
//# sourceMappingURL=file:///C:/Users/xxx/AppData/Local/deno/gen/https/deno.land/std/examples/welcome.ts.js.map
TSファイルをTypeScript compilerでJSに変換した結果を置いてあるようです
これならV8で即座に実行できますね
ローカルサーバーを立ててみる
VSCodeに公式サイトのコードをコピペしました
import { serve } from "https://deno.land/std@0.50.0/http/server.ts";
const s = serve({ port: 8000 });
console.log("http://localhost:8000/");
for await (const req of s) {
req.respond({ body: "Hello World\n" });
}
Deno固有のルールにVSCodeが対応していないので2か所エラーが出ます
・インポートパスの拡張子をtsにできない(拡張子を消すと、次はモジュールが見つからないエラー)
・async関数内部でしかawaitできない
エラー解消のために公式サイトで紹介されている拡張機能をインストールします
Deno support for VSCode
インストールするだけではtsファイルをDenoのスクリプトだと判別してもらえないので設定ファイルをserver.tsと同じ場所に.vscode
ディレクトリを作成して追加
{
"deno.enable": true
}
ここまでやってVSCodeを再起動するとawaitの方のエラーは消えますが、importの方はローカルにモジュールがないというエラーが残ります
先ほどのキャッシュ領域にhttps://deno.land/std@0.50.0/http/server.ts
があれば良いのだろうと想定し以下のコマンドを実行してみました
deno install https://deno.land/std@0.50.0/http/server.ts
成功したようです
VSCodeを再起動してみたら見事にエラーが消えました!
ただ、初回実行時に存在しないモジュールは自動でダウンロードされるはずなのでこの工程は無駄ですね・・・
では実行してみます
deno run deno_test/server.ts
怒られました・・・
Denoはデフォルトでセキュアに動作するため、ファイルやネットワークへのアクセスが禁止されています
error文に書いてある通りに--allow-net
フラグを付けて実行してみましょう
deno run --allow-net deno_test/server.ts
# http://localhost:8000/
次は上手くいったようです!
この時、Windowsだとファイヤーウォールから警告が出るので許可しましょう
試しにChromeでhttp://localhost:8000/
にアクセスしてみると
テキストが返ってきました
最低限のサーバーが出来上がりです
req
オブジェクトがbodyやmethodを持っているのでPOST対応も簡単に出来そうですね
サーバー停止はCtrl+Cを1回だけ入力するだけです
server以外の標準モジュールはここから探せます
Deno Standard Modules
まとめ
TypeScriptで書いてすぐに動くのはメチャクチャ気持ちがいい!
あらゆることが明示的なので、Node.jsの環境設定がわからなくてTypeScriptに入門できてない人たちにも勧めやすいです
Node.jsの取って代わる未来がくるのかどうかはわかりませんが、個人的にはとても気に入ったのでモジュールをOSSで公開するとかでコミュニティに貢献していきたいですね
Denoじゃないですが、TypeScriptでanyになりがちなHTTPリクエストを静的に型検査可能にするOSSを公開しているのでぜひこちらも読んでみてください!
HTTPリクエストを型安全にする手法とOSS