Webpacker::Manifest::MissingEntryErrorでコンパイルはされているのに読み込まれない

# はじめに

最近Railsの開発環境を作成しています。
[こちらの記事](https://zenn.dev/jinwatanabe/articles/4d26ac177069f374eb6a)で構築手順を載せています。

そこで、GitにリポジトリをあげたコードをCloneして起動したところうまく起動できない事態が発生したため手直しのさいに解決した方法をまとめます。

# 問題

WebpackerとRailsのDocker環境を作成して、起動したところ以下のようなエラーが発生します。

![bandicam 2022-01-19 21-17-24-963.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/8868db69-eed9-4163-966f-4cf9ce277e68.jpeg)

Webpackerのログをみたところコンパイルはされていそうでした。

```
webpacker_1  |        js/main-aa1872663912a6956e52.js.map    756 KiB         main  [emitted] [dev]        main
webpacker_1  |                              manifest.json  654 bytes               [emitted]              
webpacker_1  | ℹ ｢wdm｣: Compiled successfully.
```

ネットでも調べましたが、自分の欲しい答えに行きつかず自力で解決しましたので紹介します。

# 解決方法

実はこのエラー2回遭遇しました。

## 1回目 タイプミス

```
    <%= javascript_pack_tag 'application' %> # ここでエラー
    <%= stylesheet_pack_tag 'application' %>
```

エラーの場所がこのように特定されているので、インポート対象のファイルを確認したところ

```javascripts/packs/application.js
import Rails from "@rails/ujs"
import Turbolinks from "turbolinks"
import * as ActiveStorage from "@rails/activestorage"
import "channels"
import "bootstrap"

import '../javascripts/application.js' # applicationがapplocationになっていた
import '../stylesheets/applocation.scss'

Rails.start()
Turbolinks.start()
ActiveStorage.start()
```

`application`が`applocation`にタイプミスしておりました。

## 2回目 manifest.json問題

これが今回特定するのにかなり検証してつきとめた問題になります。

Webpackerではコンパイルをした際に`/public/packs/manifest.json`に情報の記録を行います。
この`manifest.json`は`Webpackerコンテナ`と`Railsコンテナ`どちらにもある必要があります。

manifest.jsonを作成するのは`command: webpack-dev-server`で起動している`webpackerコンテナ`なのでRailsコンテナにはボリュームを共有する必要がありました。

初回起動はGit cloneしてきているので`public/packs/manifest.json`自体はignoreされておりディレクトリにはありません。その状態で起動するとWebpackerコンテナのみにファイルがある状態になりエラーの原因となります。2回目以降の起動はローカルにできた`/public/packs/manifest.json`がマウントされて動くというメカニズムになっていました。


そこで、RailsとWebpackerコンテナ間で`/public`を共有することで対応します。

```docker-compose.yml
version: "3.9"
services:
  rails:
    build: .
    container_name: rails
    command: bundle exec puma -C config/puma.rb
    volumes:
      - .:/myapp
      - public-data:/myapp/public # 追加
      - tmp-data:/myapp/tmp
      - log-data:/myapp/log
      - /myapp/node_modules
    env_file:
      - .env
    depends_on:
      - db
    environment:
      WEBPACKER_DEV_SERVER_HOST: webpacker

  webpacker:
    build: .
    volumes:
      - .:/myapp
      - /myapp/node_modules
      - public-data:/myapp/public # 追加
    command: ./bin/webpack-dev-server
    environment:
      WEBPACKER_DEV_SERVER_HOST: 0.0.0.0
    ports:
      - "3035:3035"
    user: root

  db:
    image: mysql:8.0.27
    container_name: db
    environment:
      TZ: Asia/Tokyo
      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
    ports:
      - "3306:3306"
    volumes:
      - db:/var/lib/mysql
  
  web:
    build:
      context: containers/nginx
    volumes:
      - public-data:/myapp/public
      - tmp-data:/myapp/tmp
    ports:
      - 80:80
    depends_on:
      - rails

volumes:
  db:
    driver: local
  bundle:
    driver: local
  public-data: # 追加
  tmp-data:
  log-data:
```

注意としては`public/packs/manifest.json`が生成されて共有されるまで少し時間がかかるので、エラーがでてしまうかもしれないというところです。なんどかリロードすれば読み込まれるかと思います。

# おわりに

gitからクローンして手を加えないといけない環境になってしまったのでなんとか解決したくかなりの検証を行ってここまでたどり着きました。ネットにも記事がありませんでしたので誰かの助けになればと思います。

このような検証をすると深い理解ができるようになります