Deno ってのがあるらしい
今日のQiitaのトレンドみてたらRustってキーワードで釣られました。
そして出てきたDeno。Denoってなんぞや??
node.js本家の人がいろいろアレなんでdenoでどうでしょう?ってことかな?
-Node.js における設計ミス By Ryan Dahl
TypeScript がそのまま動く実行環境ってことでしょうか?
そして見つけた本家サイトはこちら。
- 本家サイト: https://deno.land/
- ドキュメント: https://github.com/denoland/deno/blob/master/Docs.md
- GitHub: https://github.com/denoland/deno
- API doc: https://deno.land/typedoc/index.html
さっそく install
対象の環境は Mac(macOs High Sierra)でございます。
本家サイトにならってインストールしてみます。
$ curl -fL https://deno.land/x/install/install.sh | sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 1049 100 1049 0 0 878 0 0:00:01 0:00:01 --:--:-- 878
######################################################################## 100.0%
Deno was installed successfully to /Users/xxxxxxx/.deno/bin/deno
Manually add the directory to your $HOME/.bash_profile (or similar)
export PATH="/Users/xxxxxx/.deno/bin:$PATH"
Run '/Users/xxxxxxx/.deno/bin/deno --help' to get started
とあっさりインストール完了。さらに表示されたご案内に従ってパスを通し、deno
コマンドを叩いてみます。
$ vi .bash_profile #--> export PATH="~/.deno/bin:$PATH" を追加
$ source .bash_profile
$ deno -v
deno: 0.2.10
v8: 7.2.502.16
$ deno --help
Usage: deno script.ts
Options:
--allow-write Allow file system write access.
--allow-net Allow network access.
--allow-env Allow environment access.
--allow-run Allow running subprocesses.
-A, --allow-all Allow all permissions.
--recompile Force recompilation of TypeScript code.
-h, --help Print this message.
-D, --log-debug Log debug output.
-v, --version Print the version.
-r, --reload Reload cached remote resources.
--v8-options Print V8 command line options.
--types Print runtime TypeScript declarations.
--prefetch Prefetch the dependencies.
--info Show source file related info
--fmt Format code.
Environment variables:
DENO_DIR Set deno's base directory.
わーい!クララdeno が動いた〜!
VS code から hello world
hello worldくらいならコマンドラインから動かしてもいいんですが、今後のお付き合いも考えるとVS Codeでどんくらいイケるんだ?というのが気になります。
とりあえずVS codeを立ち上げて以下のようなファイルを作成します。
console.log("hello world");
いや、面目無い。Typescriptならではっていう気の利いたコードがさっと出てこなくて。
でもプログラムはプログラム。ターミナルから以下のようにdenoを動かす。
$ deno sample.ts
Compiling /Users/xxxxxxx/xxxxxx/xxxxx/xxxxxx/sample.ts
hello world
あぁなんかそれっぽい。
でもconsoleとかモロ手打ちなのはいただけないのでコード補完パワーが欲しくなります。
VSCodeのextension で deno
と打つと deno-vscode
というモロそれっぽいpluginがヒットしました。これを入れてみますか。
インストール後、Command + P
でコマンドパレットが開くので、>deno init
と打ちます。
数秒後、"準備ができましたので再起動します"的なメッセージが一瞬流れて VSCode再起動・・・おいおいおw
ちょっと勝手に再起動はどうなんだろう?と思いつつ、吐き出されたファイルを見てみると、結構、出てますね。。。
$ ls -1
node_modules
package-lock.json
package.json
sample.ts
tsconfig.json
えっと、package.jsonとかnode_modulesとかnode.jsの悪い文化だからここから脱却したかったんじゃなかったっけdeno? nodeでいいの? no! なにがいいの?! deno!!って訳でコイツはちょっとuninstall。
そんなわけで以下のツイート見つけました。エッセンシャルなのはこちらですね!
#denots、こういうtsconfig.jsonを書くと、IntelliJ、VSCodeで補完されるぞ!! pic.twitter.com/sEbwb71f6y
— keroxp (@keroxp) 2018年12月29日
教えに従って以下のような tsconfig.jsonファイルを作成いたしました。相対パスの深さはコードのある位置から~/.denoまでの深さです。各自、チェックしてくださいね!
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"deno": [
"../../../.deno/deno.d.ts"
],
"https://*": [
"../../../.deno/deps/https/*"
],
"http://*": [
"../../../.deno/deps/http/*"
]
}
}
}
これでdenoのハッピーコードインテリジェンスライフが送れるかも?!
単純にHTTPをエコーするサーバーをこさえてみます。
本家サイトのMini-tutorialにhttps://deno.land/x/http/file_server.ts
を使用しているのを発見しました。
これに倣ってもっと簡単な、POSTされた文字列をJSONで返すエコーなHTTPサーバーを作ってみようかと思います。
とりあえず上記ファイルをブラウザでダイレクトに表示し、使えそうな頭の部分(import宣言やらいろいろしてるとこ)だけ持ってきます。
#!/usr/bin/env deno --allow-net
import {
listenAndServe,
ServerRequest,
setContentLength,
Response
} from "https://deno.land/x/http/server.ts";
import { cwd, DenoError, ErrorKind, args, stat, readDir, open } from "deno";
1行目のシバンでdenoで呼ぶ時は--allow-netを付与してくれってことがわかりますね。さすがサンプル、わかりやすい!
次のimportからdenoの本領発揮ですね。インターネット上のtsファイルを直接importするのでpackage.json不要!
次の"deno"からimportしている箇所は、tsconfig.jsonでのパス指定が正しければちゃんと認識してくれるはずです。
宣言しただけではダメ
import 宣言でいろいろモジュールからクラスやメソッドなど取ってきますがtsconfig.jsonで指定したhttps://*
などは~/.deno/
を参照してますのでこのままではコード補完も効きません。
初めて使うモジュールに遭遇した場合は依存モジュールだけまずはじめに取得したいところです。
そんな時にはdeno
の--prefetch
オプションを使います。
$ deno sample_http_echo.ts --prefetch
Compiling /Users/yoshinori/Develop/github/deno_sample/sample_http_echo.ts
Downloading https://deno.land/x/http/server.ts...
Downloading https://deno.land/x/io/bufio.ts...
Downloading https://deno.land/x/textproto/mod.ts...
Downloading https://deno.land/x/http/http_status.ts...
Downloading https://deno.land/x/testing/mod.ts...
Downloading https://deno.land/x/io/util.ts...
Compiling https://deno.land/x/http/server.ts
Compiling https://deno.land/x/io/bufio.ts
Compiling https://deno.land/x/io/util.ts
Compiling https://deno.land/x/testing/mod.ts
Compiling https://deno.land/x/textproto/mod.ts
Compiling https://deno.land/x/http/http_status.ts
$
ソースコードの実行はせずに依存関係の解決とダウンロードだけを行なってくれます。
コンパイルはされるのでコンパイルエラーがある状態ではダメでしょうけれども・・・
VS Codeのエディタにはちょっと遅れて反映されます。
エディタ閉じて開くとそれなりにさっと認識されましたが・・・これはVS Codeでなんかあるのかな?再解釈的なコマンド・・・?
とりあえずlistenしてみる
続いて、空っぽのhttp待ち受けでlistenAndServeを呼び出しだけしてみましょうか。
const serverArgs = args.slice();
const addr = `0.0.0.0:${serverArgs[1] || 4500}`;
listenAndServe(addr, req =>{
});
console.log(`HTTP server listening on http://${addr}/`);
さっそく、ターミナルで叩いてみます。
$ deno sample_http_echo.ts
Compiling /Users/xxxxxx/xxxx/xxx/xxxxxxx/sample_http_echo.ts
Deno requests network access to "listen". Grant? [yN] y
HTTP server listening on http://0.0.0.0:4500/
お?!networkをlistenするのにGrantしていいか?と聞いてきました!ちゃんとガードされてるっ!
control+c
でいったん終わらせて、--allow-net
つけてみましょう。
$ deno sample_http_echo.ts 1899 --allow-net
HTTP server listening on http://0.0.0.0:1899/
ついでに違うポートを指定してみましたがちゃんと効いてます。
(いや、テストケース書けよwと思いますが、deno単体で.test.tsを叩けるようなコマンド?がパッと見当たらなかったので後日にします。)
POSTをエコーする処理
POSTされたbodyをjsonにしてエコーを返す処理を書いてみます。
listenAndServe(addr, async req =>{
const body = new TextDecoder().decode(await req.body());
const headers = new Headers();
headers.set("content-type", "application/json");
let res : Response = {
status : 200,
body: new TextEncoder().encode('{"postBody":"'+body+'"}'),
headers
};
setContentLength(res);
req.respond(res);
});
なんかJSONの文字列、ベタ書きなのが気になるけど・・・(笑)
RequestやResponseのbodyがUint8Arrayなのでそのまま文字列として扱えませんが、そこはドンマイ。
動かしてみる!
以下のコマンドでサーバーを起動します。
$ deno sample_http_echo.ts 1899 --allow-net
HTTP server listening on http://0.0.0.0:1899/
ターミナルをもう一つ開き、curl
でPOSTしてみます。
$ curl -X POST -d "aaaaaa" http://localhost:1899/
{"postBody":"aaaaaa"}
ちゃんとJSON形式の文字列で返ってきました!!!
とりあえず、サーバーとしての動きが確認できたのでよかった。
作成したコード
Gistにあげました。以下のリンクからどうぞ!
https://gist.github.com/Yoshinori-Koide-PRO/e45c93e532974d8defd25b2ac82c0cff
まとめ
とりあえず動いてよかった〜
denoはまだまだ0.2ですがTypescriptがそのまま動かせるのは面白いです。
今後のバージョンアップにも期待したいと思います!