Open19

Docker + React

kcabokcabo

npx create-react-app my-app --template typescript --use-npm

.
├── .devcontainer
│   ├── Dockerfile
│   └── devcontainer.json
└── my-app
    ├── .gitignore
    ├── README.md
    ├── node_modules
    ├── package-lock.json
    ├── package.json
    ├── public
    ├── src
    └── tsconfig.json

my-app内は1階層あげる
←package.jsonはプロジェクトフォルダ直下に置きたい

kcabokcabo

なぜ最初から直下に作れないか

node@3cdf173852a3:/workspaces/react-tutorial$ npx create-react-app .
The directory . contains files that could conflict:

  .devcontainer/

Either try using a new directory name, or remove the files listed above
kcabokcabo

Reactの場合インフラごと配布はしないからDockerfileは開発時にしか使わない

kcabokcabo

↑は適当なNodeコンテナを作り中にはいって
npm install -g create-react-app
した
これは一回作ったらもういらない

kcabokcabo

Linux 上ではホストとコンテナ間で VFS を基盤に共有しているので、オーバーヘッドのない反映を保証します。しかしながら、 macOS (および他の Linux 以外のプラットフォーム)では、完全な一貫性を保つために著しいオーバーヘッドがあります。
ボリューム・マウント(共有ファイルシステム)のためのパフォーマンス・チューニング — Docker-docs-ja 19.03 ドキュメント

WSLなら関係ない?

Docker Desktop leverages that to handle bind mounts from a WSL 2 distro without involving any remote file sharing system. This means that when you mount your project files in a container (with docker run -v ~/my-project:/sources <...>), docker will propagate inotify events and share the same cache as your own distro to avoid reading file content from disk repeatedly.
Docker Desktop: WSL 2 Best practices - Docker Blog
←この記事重要そうだから後で読みたい

マウント先がWSLのファイルシステム上ならよさげ

kcabokcabo

node_modulesどうする問題

せっかくコンテナ使ってるんだし依存関係のライブラリはコンテナ内にのみ残したい
→ 開発してないときはイメージ削除すれば容量も減る。作って捨てる開発環境にする

ただしnode_modulesを作ったあとにマウントするとnode_modulesのあるコンテナ内(イメージ内)のプロジェクトに上書きしてしまう → node_modulesが消えた!問題が発生

https://zenn.dev/foolishell/articles/3d327557af3554
https://shotat.hateblo.jp/entry/2016/12/01/221631
https://stackoverflow.com/questions/30043872/docker-compose-node-modules-not-present-in-a-volume-after-npm-install-succeeds/32785014#32785014

Volume Trickで行ける
その他node_modulesをプロジェクトフォルダから移す選択肢もある

kcabokcabo

参考記事
https://postd.cc/lessons-building-node-app-docker/
↓多分コレが元記事
https://jdlm.info/articles/2016/03/06/lessons-building-node-app-docker.html

The node_modules Volume Trickあたりの翻訳がひどいので原文を読む

  1. build時にnpm installnode_modulesフォルダができる
  2. コンテナ起動&マウント。色々マウントされて1のnode_modulesが隠れる
  3. もっかいマウント。今度はデータボリュームのnode_modulesをマウント

イメージビルド時に、既にデータボリュームは作成されている?
だからビルド時にできたnode_modules(ライブラリ入)のデータはデータボリュームとして既に避難している
2で隠れてしまうけど(この時に空のディレクトリが上書きされないのが不思議)、3でもっかい上書きするイメージ

#TODO データボリュームの仕様を調べる


https://qiita.com/hikaruna/items/0bc1e97e8d254f4c27e7
こっちの方がスマートなやり方な気がする
プロジェクトフォルダにインストールしてから別のフォルダに退避→そのフォルダにパスを通す作戦

https://castaneai.hatenablog.com/entry/2019/01/29/151257

https://github.com/docker/compose/issues/4337
https://stackoverflow.com/questions/30043872/docker-compose-node-modules-not-present-in-a-volume-after-npm-install-succeeds/32785014#32785014

kcabokcabo

イメージ内にライブラリを取り込むべきかどうかの問題である気もする
イメージがすぐにRunできる状態にあることが前提ならイメージ内にnode_modulesを含めたい

kcabokcabo

これが効かない問題
別にいいけど
RUN echo "PS1='\033[32m\u@\h \033[35m\t \033[34m\w \033[0m$ '" >> ~/.bashrc

kcabokcabo

データボリュームとしてライブラリを持っている
これはコンテナが死んでも消えない
だったらビルド時に毎回npm installする必要なくない?

kcabokcabo

結論

FROM node:latest

USER node

WORKDIR /workspaces/react-tutorial

COPY --chown=node:node package.json package-lock.json ./

RUN npm install && npm cache clean --force

# Volume Trick
VOLUME /workspaces/react-tutorial/node_modules

EXPOSE 3000

ENV TZ Asia/Tokyo

こんな感じにした

# 多分所有者変えないとnpm installできない
COPY --chown=node:node package.json package-lock.json ./
# Volume Trick
VOLUME node_modules:/workspaces/react-tutorial/node_modules

だと動かないので注意
https://github.com/moby/moby/issues/30647#issuecomment-276882545

おそらくCLIやdocker-composeならデータボリューム名を指定できる
https://github.com/jdleesmiller/docker-chat-demo/tree/2019-03-dependencies

kcabokcabo

所有者変えないと。。。

#8 2.887 npm ERR! code EACCES
#8 2.888 npm ERR! syscall open
#8 2.888 npm ERR! path /srv/chat/package-lock.json
#8 2.889 npm ERR! errno -13
#8 2.893 npm ERR! Error: EACCES: permission denied, open '/srv/chat/package-lock.json'
#8 2.893 npm ERR!  [Error: EACCES: permission denied, open '/srv/chat/package-lock.json'] {
#8 2.893 npm ERR!   errno: -13,
#8 2.893 npm ERR!   code: 'EACCES',
#8 2.893 npm ERR!   syscall: 'open',
#8 2.893 npm ERR!   path: '/srv/chat/package-lock.json'
#8 2.893 npm ERR! }
#8 2.894 npm ERR! 
#8 2.894 npm ERR! The operation was rejected by your operating system.
#8 2.894 npm ERR! It is likely you do not have the permissions to access this file as the current user
#8 2.894 npm ERR! 
#8 2.894 npm ERR! If you believe this might be a permissions issue, please double-check the
#8 2.894 npm ERR! permissions of the file and its containing directories, or try running
#8 2.894 npm ERR! the command again as root/Administrator.
#8 2.921 
#8 2.921 npm ERR! A complete log of this run can be found in:
#8 2.921 npm ERR!     /home/node/.npm/_logs/2021-07-07T06_08_56_702Z-debug.log

COPY時点では所有者はroot

total 20
-rw-r--r-- 1 root root 14280 Jul  7 06:03 package-lock.json
-rw-r--r-- 1 root root   539 Jul  7 06:03 package.json
kcabokcabo

ホットリロード効かない問題

どいつもこいつもCHOKIDAR_USEPOLLINGをtrueにセットしろとしか言ってこない
全く改善せずにアレコレしてたら結局npm audit fix --forceで解決した

良かった

npm updateでもいけるかも

kcabokcabo

そもそも論コンテナ開発すべきかについて

https://mizchi.hatenablog.com/entry/2019/04/07/074634
非常に参考になる

言語サーバーの問題はVSCodeサーバーで解決するか

IOの問題はもう少し触ってみないと分からない
Macだと厳しい模様

というかそもそも独立した環境というコンテナのメリットがフロント開発で活かせない
普通にホストにNodeインストールすればよくね?ていう
環境依存ということがフロントエンドにおいてはない(フロントにとっての環境=ブラウザ)

もともとはバックエンドのための技術なわけだろうから、今後どう浸透していくのか、あるいはしないのか

kcabokcabo

ESLintとPrettier周り

闇。
そもそもESlintしようとしたらこうなる

npx eslint 'src/index.js'

Oops! Something went wrong! :(

ESLint: 7.30.0

ESLint couldn't find the config "react-app" to extend from. Please check that the name of the config is correct.

The config "react-app" was referenced from the config file in "/workspaces/react-tutorial/package.json".

If you still have problems, please stop by https://eslint.org/chat/help to chat with the team.

🤮🤮

kcabokcabo

感想

正直まだまだnoob
フロントエンドの群雄割拠感… ←選択肢が多いこと自体はいい
フロントエンドエンジニアすごい
初心者には障壁高すぎる → 大したことしないのならローコードツールがいいのかも?今度触る

デザイナーがコーディングをしたがらない理由になりそう
フロントエンド嫌いになりそう

Next.jsのZeroConfigに興味が出た