事象
Docker環境で、Reactを使ったWebアプリケーションを作成していた際、npm install react-router-dom
が成功したはずなのに[plugin:vite:import-analysis] Failed to resolve import "react-router-dom" from "src/App.tsx". Does the file exist?
が出ている。
原因
ローカル環境で行ったnpm install react-router-dom
が、Docker環境に反映されていなかったことが原因。
Viteの古いキャッシュが使われているのではと思い、Docker環境内で、npm run dev -- -force
を実行しようとしたところ、以下のようにErrorが出ていた。
ローカルのファイルをDocker環境にマウントしているが、node_modulesは、ローカルと同期しないように、名前付きボリュームに格納していた。このため、ローカルホストでnpm install react-router-dom
を実行しても、Docker環境内のnode_modulesにはそれが反映されず、上記エラーが発生した。
services:
frontend:
build: ./frontend
container_name: react-frontend
volumes:
- ./frontend:/react-frontend
- node_modules:/react-frontend/node_modules
ports:
- "5173:5173"
volumes:
node_modules:
解決策
Docker環境内のnode_modulesに、ローカルでインストールしたライブラリの情報を反映させれば解決する。具体的な方法は以下の2つ。
ただしこれらの解決策は、あくまで上記原因に対して有効なのであって、他の原因の場合は別の対応が必要。
その1. Docker環境内で、ローカルと同じライブラリをnpm install
する
-
docker exec -it ${CONTAINER_NAME}
で、Docker環境内のBashに入る - ローカルと同様のライブラリをインストールする
- ローカルの
node_modules
とpackage-lock.json
を削除し、ローカル環境でnpm install
を実行する
3ステップ目について、node_modules
とpackage-lock.json
を削除することで、依存関係を整理しなおしている。
その2. 名前付きボリュームを削除して、再度Buildする
Docker環境内のnode_modules
を削除してBuildすると、package.json
をもとに再度node_modules
が生成される。ローカル環境のpackage.json
には既にライブラリへインストールした情報が反映されているため、再生成されたnode_modules
にも、それが反映される。
# Volumeを消す前にコンテナを停止
docker-compose down
# 名前付きボリュームを削除
docker volume rm node_modules
# 再度Buildを実行
docker-compose build
名前付きVolumeを同時にすべて削除してしまっても問題ない場合は、以下の手順でも同様に動作する。
# コンテナ停止時に、名前付きボリュームをすべて削除
docker-compose down -v
# 再度Buildを実行
docker-compose build
最後に
今回は、Docker-composeの名前付きボリュームに、ローカルでの操作が、うまく反映されないことが原因でした。
対応策を2つ提示しましたが、ライブラリをインストールするたびに同様の手順が必要なことを考えると、少し手間になる作業であるため、より良い方法を知っている方がいれば教えていただきたいです。