Docker for Windows で create-react-app するまで

Docker Desktop for Windows で create-react-app を使って新しい ReactJS のアプリ（typescript）を作成し始めた時の簡単な流れと、詰まったポイントを軽くメモしておきます。

## 動作環境
* Windows 10 Home ver.2004（執筆時点では Docker fow Windows の利用のために、プレビュービルドを利用）
* Docker Desktop for Windows ver.2.3.0.1

※下記は Windows 側のファイルシステムに Dockerfile 等を置き Docker を動かしている。
WSL2 の Linux 上で動かそうとすると、記事中の内容は問題なく動くが root 権限で動くコンテナ内で create されたファイル、フォルダが root 権限で編集できない。みたいな別の問題を踏むはず。

## 大筋の参考記事
node を直接管理したくはなかったので、 Docker を使いたかった。

* [Reactの開発環境をDockerで構築してみた | ニフティものづくりブログ](https://blog.web.nifty.com/engineer/2714)
* [Docker環境内でcreate-react-app - Qiita](https://qiita.com/mii288/items/aac597bc02575831ea90)

を見ながら、 create-react-app して、アプリ作成のスタートラインに立つまでの整備が目標でした。

## 実際の作業内容
### ①Docker イメージの build
普通に `docker-compose build` します。執筆時点で新しめの node version を選びました。

```dockerfile:Dockerfile
FROM node:14-alpine  
WORKDIR /usr/src/app
```
```yml:docker-compose.yml
version: "3"
services:
  node:
    build: .
    volumes:
      - ./:/usr/src/app
    ports:
      - "3000:3000"
    command: sh -c "cd react-sample && yarn start"
```

### ②create-react-app の実行
`docker-compose run --rm node sh -c "npm install -g create-react-app && create-react-app react-sample --typescript"` します。
ここも特筆することはありません。結構時間かかるので別のことで暇をつぶして待ちます。
成功している場合、以下のようなメッセージで終わっており、 react-sample と言うフォルダが切られて、各素材が増えるはずです。別の名前にしたい場合は、このコマンド実行時と docker-compose.yml 内の command の cd 先を変更してください。

```
Success! Created react-sample at /usr/src/app/react-sample
Inside that directory, you can run several commands:

  yarn start
    Starts the development server.

  yarn build
    Bundles the app into static files for production.

  yarn test
    Starts the test runner.

  yarn eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

  cd react-sample
  yarn start

Happy hacking!
```

### ③docker-compose up の実行
上述した create-react-app の実行完了時のメッセージに表示されている通り、作成した ReactJS アプリを動かす development サーバを立ち上げるためには、作成したアプリのディレクトリ上で `yarn start` の実行が必要です。
予め、 docker-compose.yml 内で起動時に command 指定しているので、何も考えずに `docker-compose up` を実行すればいいはずでした……。
ところが以下のようなログの通り、サーバの起動処理を行っている途中でコンテナが終了してしまいました。

```
node_1  | yarn run v1.22.4
node_1  | $ react-scripts start
node_1  | ℹ ｢wds｣: Project is running at http://172.18.0.2/
node_1  | ℹ ｢wds｣: webpack output is served from
node_1  | ℹ ｢wds｣: Content not from webpack is served from /usr/src/app/react-sample/public
node_1  | ℹ ｢wds｣: 404s will fallback to /
node_1  | Starting the development server...
node_1  |
node_1  | Done in 40.75s.
react_node_1 exited with code 0
```

調べてみると、 [[React-Scripts] v3.4.1 fails to start in Docker #8688](https://github.com/facebook/create-react-app/issues/8688) などで同様の現象が出てくる。最近のことらしい。
対処としては、よくある `stdin_open: true` や `tty: true` の指定を追加することで落ちなくなるよう。実際に docker-compose.yml の末尾に追加してみました。

```yml:docker-compose.yml
version: "3"
services:
  node:
    build: .
    volumes:
      - ./:/usr/src/app
    ports:
      - "3000:3000"
    command: sh -c "cd react-sample && yarn start"
    stdin_open: true
```

今度は大丈夫そうでした。
ブラウザで http://localhost:3000/ にアクセスしてみて、以下の画面が表示されれば成功です。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634528/ef8d9b66-6c3a-886f-5132-d66c9330d0ab.png)

### ④ホットリロードの有効化
さて、無事に最初の画面が表示されたので、案内されている通り src/App.tsx に編集を加え始めようとしたのですが、今度はホットリロードが動作せず、ブラウザの更新でも内容が反映されないようでした（恐らく、変更を検知して初めてソースコードをビルドするので、ブラウザの更新をかけようがビルドが再度走らない以上、変化が現れない？）。
これも良く遭遇する現象なのですが、時間が経つとすぐ忘れては毎回別の記事にヒットしている気がする……。
これまた docker-compose.yml の変更として、環境変数 `CHOKIDAR_USEPOLLING=true` を追加してあげることで解決します。

```yml:docker-compose.yml
version: "3"
services:
  node:
    build: .
    volumes:
      - ./:/usr/src/app
    ports:
      - "3000:3000"
    command: sh -c "cd react-sample && yarn start"
    stdin_open: true
    environment:
      - CHOKIDAR_USEPOLLING=true
```

以上でした。