Open5

typescriptで型エラーが発生した時、node_modules削除してコンテナにてnpm iで解消できる理由

masamasa

上記に対して疑問を持った経緯

  • npm iで新たにライブラリをインストールしたとき、モジュール またはそれに対応する型宣言が見つかりません。と型エラーが発生。
  • node_modulesを消して、docker compose build front --no-cacheでキャッシュを使用せずにビルドしたが、型エラーは解消せず
    • Dockerfile内にはnpm iのコマンドあり
  • node_modulesを消して、docker compose exec frontend npm iを実施したところ、無事、型エラーが解消された。
  • なんで前者ではダメで後者ではいけるのか、腑に落ちなかったため調査した
masamasa

docker-compose.ymlには下記のようにvolumeを設定していた。

    volumes:
      - ./frontend:/app
      - stock_mock_node_modules:/app/node_modules
      - stock_mock_dist:/app/dist
masamasa
  • ボリュームの使い方についてのおさらい

バインドマウント

下記の形式

./frontend:/app

ホスト側のディレクトリ(./frontend)がコンテナ側(/app)にマウントされる
(追記:コンテナ側が変更された場合もホストに反映される)

名前付きボリューム

- stock_mock_node_modules:/app/node_modules
- stock_mock_dist:/app/dist
  • ホスト側のdockerのデータが保存される領域(/var/lib/docker/volumes/stock_modck_node_modules)とコンテナ側のディレクトリ(/app/node_modules)が共有される。
  • これにより、コンテナを落としても次回立ち上げ時にデータを復元することができ、永続化することができる
masamasa

ローカルのnode_modulesを消して再ビルド→docker立ち上げした時のnode_modulesの状態

  • ローカルのnode_modules削除

  • イメージビルド

    • イメージの中にはnode_modulesとライブラリは入っていると想定
  • コンテナ立ち上げ

    • ローカルではnode_modulesフォルダは生成(中身は空)
    • コンテナ内にはnode_modules、中身のライブラリは存在している。
  • まとめ

    • なぜフォルダしかマウントされない?
    • その後にローカルのnode_modules削除→docker compose exec frontend npm iでなぜいける?
masamasa
  • なぜフォルダしかマウントされない?
    • これは謎
  • その後にローカルのnode_modules削除→docker compose exec frontend npm iでなぜいける?
    • ローカルのnode_modulesディレクトリを削除した時にマウントされているため、コンテナのnode_modulesディレクトリも削除される
    • その後、コンテナ内でnpm installを行うことでコンテナ内にてnode_modulesと必要なパッケージが再インストールされる→マウントされているため、ローカルにもnode_modulesとパッケージが反映される。

コンテナ立ち上げ時にうまくマウントされない原因は謎だが、コンテナが立ち上がった後にnode_modulesを消して再インストールするとうまくいくのは上記の理由だと推測