Deno 1.0.0 で Hello World

## 概要

- Deno 1.0.0 をインストールして Hello World などを実行する

## Deno とは

Deno は Rust で書かれた JavaScript と TypeScript の実行環境。

[Deno](https://deno.land/)

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

Deno は単独で TypeScript を実行できる。

[https://deno\.land/v1](https://deno.land/v1)

> Deno supports TypeScript without additional tooling. The runtime is designed with TypeScript in mind.

## Deno のインストール

[The Deno Manual - Installation](https://deno.land/manual/getting_started/installation) にインストール方法が載っている。

macOS には Homebrew でインストールできる。

```
$ brew install deno
```

```
$ deno --version
deno 1.0.0
v8 8.4.300
typescript 3.9.2
```

Linux にはインストール用のシェルスクリプトを実行してインストールできる。

```
$ curl -fsSL https://deno.land/x/install/install.sh | sh -s v1.0.0
```

## Hello World

以下の内容の hello.ts ファイルを作成。

```hello.ts
const message: string = "Hello, world"
console.log(message)
```

deno run で実行。
コンパイルされて実行される。

```
$ deno run hello.ts
Compile file:///Users/foo/bar/hello.ts
Hello, world
```

Compile の行 (diagnostic output) は標準エラー出力に出力される。

2回目の実行では diagnostic output は出力されない。
コンパイル済みのコードがキャッシュされているため。

```
$ deno run hello.ts
Hello, world
```

コンパイル済みのコードはキャッシュ用のディレクトリに保存されている。
deno info コマンドで調べることが可能。

```
$ deno info
DENO_DIR location: "/Users/foo/Library/Caches/deno"
Remote modules cache: "/Users/foo/Library/Caches/deno/deps"
TypeScript compiler cache: "/Users/foo/Library/Caches/deno/gen"
```

```
$ ls -1 /Users/foo/Library/Caches/deno/gen/file/Users/foo/bar
hello.ts.js
hello.ts.js.map
hello.ts.meta
```

コンパイル時に diagnostic output を出力したくない場合は --quiet または -q オプションを指定する。

```
$ deno --quiet run hello.ts
Hello, world
```

## HTTP 越しのコードを実行

Deno のサイトにサンプルコードが置いてある。

```
$ curl https://deno.land/std/examples/welcome.ts
console.log("Welcome to Deno 🦕");
```

deno run コマンドで URL を指定して直接実行できる。

```
$ deno run https://deno.land/std/examples/welcome.ts
Download https://deno.land/std/examples/welcome.ts
Warning Implicitly using master branch https://deno.land/std/examples/welcome.ts
Compile https://deno.land/std/examples/welcome.ts
Welcome to Deno 🦕
```

## ファイルを読む

以下の内容の cat.ts ファイルを作成。
引数で指定したファイルを読み込んで標準出力へ出力するプログラムになっている。

```cat.ts
const filenames = Deno.args;
for (const filename of filenames) {
  const file = await Deno.open(filename);
  await Deno.copy(file, Deno.stdout);
  file.close();
}
```

ファイルを読み込むには --allow-read フラグを指定する。

```
$ deno -q run --allow-read cat.ts cat.ts cat.ts
const filenames = Deno.args;
for (const filename of filenames) {
  const file = await Deno.open(filename);
  await Deno.copy(file, Deno.stdout);
  file.close();
}

const filenames = Deno.args;
for (const filename of filenames) {
  const file = await Deno.open(filename);
  await Deno.copy(file, Deno.stdout);
  file.close();
}
```

## HTTP リクエストを投げる

以下の内容の curl.ts ファイルを作成。

```curl.ts
const url = Deno.args[0]
const res = await fetch(url)
const body = new Uint8Array(await res.arrayBuffer())
await Deno.stdout.write(body)
```

ネットワークアクセスをする場合は --allow-net フラグで通信を許可するドメインを指定する。

```
$ deno -q run --allow-net=niwasawa.github.io curl.ts https://niwasawa.github.io/
<!DOCTYPE html>
<html lang="ja">
<head>
(以下略)
```

## 標準モジュールを使う

標準モジュールは [std \- deno\.land](https://deno.land/std/) にある。

以下の内容の sha256.ts ファイルを作成。

```sha256.ts
import { Message, Sha256 } from "https://deno.land/std/hash/sha256.ts"
const message: Message = "Hello, world."
const sha256: Sha256 = new Sha256()
sha256.update(message)
const hash: string = sha256.hex()
console.log(hash)
```

deno run コマンドで実行する。

```
$ deno -q run sha256.ts 
f8c3bf62a9aa3e6fc1619c250e48abe7519373d3edf41be62eb5dc45199af2ef
```

## サードパーティのモジュールを使う

サードパーティのモジュールは [Deno Third Party Modules](https://deno.land/x/) にある。

以下の内容の md5.ts ファイルを作成。

```md5.ts 
import { md5 } from "https://deno.land/x/md5/mod.ts"
const hash: string = md5("Hello, world.")
console.log(hash)
```

deno run コマンドで実行する。

```
$ deno -q run md5.ts 
080aef839b95facf73ec599375e92d47
```

## 外部モジュールを使う

以下の内容の echo.ts ファイルを作成。

```echo.ts
export const echo = (s: string): string => { return s }
```

以下の内容の aaa.ts ファイルを作成。

```aaa.ts 
import { echo } from "./echo.ts"
console.log(echo("Hello, world"))
```

deno run コマンドで実行する。

```
$ deno -q run aaa.ts 
Hello, world
```

## Web サーバを起動する

標準モジュールである [std/http/server.ts](https://deno.land/std/http/server.ts) を使って Web サーバを起動できる。

以下の内容の webserver.ts ファイルを作成。

```webserver.ts 
import { serve, Server, ServerRequest, Response } from "https://deno.land/std/http/server.ts"
const server: Server = serve({ port: 8000 })
for await (const req: ServerRequest of server) {
  const res: Response = {
    body: "<html><body>Hello World</body></html>\n"
  }
  req.respond(res)
}
```

deno run コマンドで実行して Web サーバを起動する。
ネットワークへのアクセスを許可するため --allow-net フラグを指定する。

```
$ deno -q run --allow-net webserver.ts
```

別のコンソールから curl 等でアクセスすると HTTP レスポンスが返ってくる。

```
$ curl http://localhost:8000/
<html><body>Hello World</body></html>
```

## Deno の Help

deno -- help でヘルプが表示される。

```
$ deno --help
deno 1.0.0
A secure JavaScript and TypeScript runtime

Docs: https://deno.land/std/manual.md
Modules: https://deno.land/std/ https://deno.land/x/
Bugs: https://github.com/denoland/deno/issues

To start the REPL:
  deno

To execute a script:
  deno run https://deno.land/std/examples/welcome.ts

To evaluate code in the shell:
  deno eval "console.log(30933 + 404)"

USAGE:
    deno [OPTIONS] [SUBCOMMAND]

OPTIONS:
    -h, --help                     
            Prints help information

    -L, --log-level <log-level>    
            Set log level [possible values: debug, info]

    -q, --quiet                    
            Suppress diagnostic output
            By default, subcommands print human-readable diagnostic messages to stderr.
            If the flag is set, restrict these messages to errors.
    -V, --version                  
            Prints version information


SUBCOMMANDS:
    bundle         Bundle module and dependencies into single file
    cache          Cache the dependencies
    completions    Generate shell completions
    doc            Show documentation for a module
    eval           Eval script
    fmt            Format source files
    help           Prints this message or the help of the given subcommand(s)
    info           Show info about cache or info related to source file
    install        Install script as an executable
    repl           Read Eval Print Loop
    run            Run a program given a filename or url to the module
    test           Run tests
    types          Print runtime TypeScript declarations
    upgrade        Upgrade deno executable to given version

ENVIRONMENT VARIABLES:
    DENO_DIR             Set deno's base directory (defaults to $HOME/.deno)
    DENO_INSTALL_ROOT    Set deno install's output directory
                         (defaults to $HOME/.deno/bin)
    NO_COLOR             Set to disable color
    HTTP_PROXY           Proxy address for HTTP requests
                         (module downloads, fetch)
    HTTPS_PROXY          Same but for HTTPS
```

## 参考資料

- [Deno](https://deno.land/)
- [The Deno Manual](https://deno.land/manual)