Denoのマニュアルで気になった所を試してみる

## Deno

[公式ページ](https://deno.land/)

最近よく目にするので、何はともあれ触ってみようかという事で
[マニュアル](https://deno.land/manual/introduction)を元にザッと気になる所を試して見たいと思います。

###  :computer:環境構築
Denoの公式Docker(?)を見つけたのでそちらで環境を構築して見たいと思います。
https://hub.docker.com/r/hayd/deno

ワンランナーでさくっと試してみます。

```sh
$ docker run --rm -it hayd/alpine-deno run https://deno.land/std/examples/welcome.ts
Welcome to Deno 🦕
```
:+1:

### :pencil: 色々試してみる

#### 簡単なサンプル
公式にも載っていた以下サンプルをローカルに `server.ts` として作成し、起動させてみます。

```ts
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" });
}
```

```sh
$ docker run --rm -it --init -p 8000:8000 -v $PWD:/app hayd/alpine-deno run /app/server.ts
...
error: Uncaught PermissionDenied: network access to "0.0.0.0:8000", run again with the --allow-net flag
```
Premissionが無いと怒られました。Denoはデフォルトでファイル、ネットワーク、環境変数等のアクセスが
許可されてないので、`--allow-net` を付けて再度実行してみます。

```sh
$ docker run --rm -it --init -p 8000:8000 -v $PWD:/app hayd/alpine-deno run --allow-net /app/server.ts
```
今度は実行でき `http://localhost:8000/` にアクセスするとちゃんと `Hello World` が返ってきました :sparkles: 

#### ファイル読み込み
[こちら](https://deno.land/manual/examples/unix_cat) を試して見たいと思います。
`cat.ts` として以下を作成します。

```ts
const filenames = Deno.args;
for (const filename of filenames) {
  const file = await Deno.open(filename);
  await Deno.copy(file, Deno.stdout);
  file.close();
}
```
読み込み用のファイル `sample.txt` を以下の内容で作成。

```text
Deno is a simple, modern and secure runtime for JavaScript and TypeScript that uses V8 and is built in Rust.
```

デフォルトだとファイル読み込みもPremissionが無いので `--allow-read` を付けて実行します。

```sh
$ docker run --rm -it --init -v $PWD:/app hayd/alpine-deno run --allow-read /app/cat.ts /app/sample.txt
> Deno is a simple, modern and secure runtime for JavaScript and TypeScript that uses V8 and is built in Rust.
```
ちゃんと読み込めてそうです :sparkles: 

####  `dependency inspector` と `formatter` 
Denoには `dependency inspector` と `formatter` がビルドインされているらしいので試してみます。

- dependency inspector

    ```sh
    $ docker run --rm -it --init hayd/alpine-deno info
    DENO_DIR location: "/deno-dir/"
    Remote modules cache: "/deno-dir/deps"
    TypeScript compiler cache: "/deno-dir/gen"
    ```
remoteから取得したmoduleとTypescriptコンパイル時のキャッシュ場所を教えてくれてます :sparkles: 

- formatter

    ```sh
    $ docker run --rm -it --init -v $PWD:/app hayd/alpine-deno fmt
    ```

#### テスト
こちらもビルドインでtest runnerが入っているらしいです。至れり尽くせり :sparkles: 
https://deno.land/manual/testing

```ts:simple.test.ts
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
Deno.test("simple", () => {
  const x = 1 + 2;
  assertEquals(x, 3);
});
```

実行!

```sh
$ docker run --rm -it --init -v $PWD:/app hayd/alpine-deno test /app/simple.test.ts
running 1 tests
test simple ... ok (3ms)

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out (4ms)
```

#### Debugger
https://deno.land/manual/tools/debugger
[V8 Inspector Protocol](https://v8.dev/docs/inspector)をサポートしている

先ほどのファイル読み込みのサンプルをDebugして見たいと思います。
`--inspect-brk` を付けて最初の1行目でブレークする様にします。

```sh
$ docker run --rm -it --init -p 9229:9229 -v $PWD:/app hayd/alpine-deno run --inspect-brk=0.0.0.0:9229 --allow-read /app/cat.ts /app/sample.txt
Debugger listening on ws://127.0.0.1:9229/ws/xxxxx
```

Chromeで `chrome://inspect` にアクセスして
<img width="249"  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299271/f50544c5-822c-dc29-d436-ddf3124437c7.png">
↑のinspectをクリックすると
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299271/1a0419b8-63c8-d092-5180-8b3516dc4ebd.png">

デバッグできました :sparkles: 

また、試せては無いですが、VSCode上でもデバッグ可能らしいです。
https://deno.land/manual/tools/debugger#vscode

#### VSCodeの拡張機能
[Deno - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=axetroy.vscode-deno)

###  :bomb: バッドノウハウ

- Debugger使用時にchromeでinspectが表示されない :warning: 
    - docker使用する場合だと `--inspect-brk` だけではダメで `--inspect-brk=0.0.0.0:9229` と指定しないといけない

###  :sparkles: 感想
- ビルドインで色々入っているので便利
- 外部パッケージをURLでインポートできるのはサクッと試せるので便利
- いきなりNodeのプロジェクトをDenoに置き換えるのは厳しそうだが、新規のプロジェクトや単独の小さなモジュールとかで使ってみたい

### :link: 参考になったURL
- [Denoの登場でNode.jsの時代は終わるのか？ - Qiita](https://qiita.com/so99ynoodles/items/c3ba2a528052827e3b3c)
- [Dockerの--initフラグについて - Carpe Diem](https://christina04.hatenablog.com/entry/docker-init)