LoginSignup
24
13

More than 5 years have passed since last update.

[2019年2月版] deno の使い方

Last updated at Posted at 2019-02-09

Deno ってのがあるらしい

今日のQiitaのトレンドみてたらRustってキーワードで釣られました。

そして出てきたDeno。Denoってなんぞや??

node.js本家の人がいろいろアレなんでdenoでどうでしょう?ってことかな?
-Node.js における設計ミス By Ryan Dahl

TypeScript がそのまま動く実行環境ってことでしょうか?
そして見つけた本家サイトはこちら。

さっそく 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を立ち上げて以下のようなファイルを作成します。

sample.ts
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。

そんなわけで以下のツイート見つけました。エッセンシャルなのはこちらですね!

教えに従って以下のような tsconfig.jsonファイルを作成いたしました。相対パスの深さはコードのある位置から~/.denoまでの深さです。各自、チェックしてくださいね!

tsconfig.json
{
  "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宣言やらいろいろしてるとこ)だけ持ってきます。

sample_http_echo.ts
#!/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を呼び出しだけしてみましょうか。

sample_http_echo.ts
  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にしてエコーを返す処理を書いてみます。

sample_http_echo.ts
  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がそのまま動かせるのは面白いです。
今後のバージョンアップにも期待したいと思います!

24
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
13