dockerでTypeScriptをいじれる環境を作る

## 概要
最近、TypeScriptをよく耳にするので、Vue.jsとかでも使ってみたいなって思ってます。
そこで、とりあえず、学習用に簡単に実行できる環境が欲しくて試してみる。

## ファイル構成
以下のようなファイル構成で作ってみる
https://github.com/reflet/typescript

```
┣ docker
┃ ┗ nginx
┃    ┗ default.conf
┣ src
┃ ┣ html
┃ ┃  ┣ js
┃ ┃  ┃  ┣ dist          ← コンパイルされたファイル
┃ ┃  ┃  ┃  ┗ greeter.js
┃ ┃  ┃  ┗ ts            ← コンパイル対象ファイル
┃ ┃  ┃     ┗ greeter.ts
┃ ┃  ┗ index.html       ← greeter.jsを読み込んでいるページ
┃ ┃
┃ ┣ package.json
┃ ┣ package-lock.json
┃ ┗ tsconfig.json
┃
┣ .editconfig
┣ .gitignore
┣ docker-compose.yml 
┗ README.md
```

## 環境作成
dockerでローカル環境を作ります。

```yml:docker-compose.yml
version: '3'
services:
  app:
    image: nginx:latest
    container_name: "app"
    ports:
      - "8080:80"
    volumes:
      - ./src/html:/app
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf

  node:
    image: node:10
    container_name: node
    tty: true
    working_dir: /usr/src/app
    volumes:
      - ./src:/usr/src/app
```

```conf:docker/nginx/default.conf
server {
    listen       80;
    listen       443;
    server_name  localhost;

    location / {
        root   /app;
        index  index.html index.htm;
    }

    error_page  404 /404.html;
    location = /40x.html {
        root   /usr/share/nginx/html;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
```

## フォルダ作成
ソースコードの格納先を作ります。

```bash:ターミナル
$ mkdir -p src/html/js/ts    # ← コンパイル対象ファイルの配置先
$ mkdir -p src/html/js/dist  # ← コンパイル済みファイルの配置先
```

## 初期化(npm)
npm プロジェクトの作成します。

```bash:ターミナル
$ docker-compose run --rm node npm init
```

作成されれる `src/package.json` に少し手を加える。

```json:src/package.json
{
  ...
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "clean": "rimraf html/js/dist",                          /* ← 追加 */
    "tsc": "tsc",                                            /* ← 追加 */
    "build": "npm-run-all clean tsc",                        /* ← 追加 */
  },
  ...
}
```

## ライブラリ追加
TypeScriptの開発に必要な各種コマンドをインストールします。

```bash:ターミナル
$ docker-compose run --rm node npm install -D typescript @types/node
$ docker-compose run --rm node npm install -D ts-node ts-node-dev rimraf npm-run-all
```

## 初期化(TypeScript)
TypeScriptのコンパイラオプションファイルを作成します。

```bash:ターミナル
$ docker-compose run --rm node npx tsc --init
```

作成されれる `src/tsconfig.json` に少し手を加える。

```json:src/tsconfig.json
{
  "compilerOptions": {
    "target": "ES2019",              /* ← ここ変更 */
    "module": "commonjs",
    "sourceMap": true,               /* ← ここ変更 */
    "outDir": "./html/js/dist",      /* ← ここ変更 */
    "strict": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": [                       /* ← ここ追加 */
    "html/js/ts/**/*"
  ]
}
```

## サンプルコード
サンプルコードを配置します。

```ts:src/html/js/ts/greeter.ts
interface Person {
    firstName: string;
    lastName: string;
}

class Student {
    fullName: string;
    constructor(public firstName: string, public middleInitial: string, public lastName: string) {
        this.fullName = firstName + " " + middleInitial + " " + lastName;
    }
}

function greeter(person: Person) {
    return "Hello, " + person.firstName + " " + person.lastName;
}

let user = new Student("Jane", "M.", "User");
document.body.textContent += greeter(user);

``` 

```html:src/html/index.html
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="utf-8">
	<title>Hello World.</title>
</head>
<body>
	<script src="./js/dist/greeter.js"></script>
</body>
</html>
```

## コンパイル
コンパイルして、 `src/html/js/dist/greeter.js` を作成する。

```
$ docker-compose run --rm node npm run build
```

## サーバ起動

```bash:ターミナル
$ docker-compose up -d
```

## 動作確認
index.jsを読み込んでいるindex.htmlをブラウザで閲覧してみる。

```
$ open http://localhost:8080
```
![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142279/e3c1402f-82be-c7b3-eb5e-fd7f9b61fb34.png)

問題ないようです。

## まとめ
サクッと動かしてみるだけであればこの程度でいけるみたい。
ただし、他のライブラリなども読み込んで使う場合は、Webpackも必要らしい。

* [TypeScript チュートリアル - webpackインストール](https://qiita.com/EBIHARA_kenji/items/31b7c1c62426bdabd263#webpack-%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)

## 参考サイト
* [TypeScript - JavaScript that scales.](https://www.typescriptlang.org/)
* [入門 TypeScriptとは？](https://www.sejuku.net/blog/93230)
* [TypeScript + Node.js プロジェクトのはじめかた2019](https://qiita.com/notakaos/items/3bbd2293e2ff286d9f49)