heroku本番環境でerror Command "webpack" not found.やActionView::Template::Error(Webpacker can't find)を解決

※これはメモ的なものなのでクオリティは担保できませんのであらかじめご理解いただきたく存じます。
https://teratail.com/questions/eelxqk0ads5nv3
テラテイルのほうでも質問をしていて、自力で解決できたのでどうやって解決できたかを自分なりにまとめてみました。
dockerのnodeのバージョンを確認したほうが良い。とのアドバイスは@NaokiM03さんにしていただき、バグの発生環境の切り分けに大いに役立たせていただきました。本当にありがとうございました。

# 前提

docker開発環境でRailsとVueを用いた簡易的なアプリを
herokuにコンテナデプロイしています。

https://www.youtube.com/watch?v=uQf9968RWWo

を参考にコンテナデプロイをしてみました。

https://devcenter.heroku.com/ja/articles/build-docker-images-heroku-yml

自分の場合はさらに、

アプリケーションのルートディレクトリに heroku.yml​ ファイルを作成しています。アプリの web​ プロセス用にビルドする Docker イメージを指定しています。

```yaml
build:
  docker:
    web: Dockerfile.production
```

[Dockerfile.production](https://github.com/Harasou21/ideaFrameworks/blob/master/Dockerfile.production)はこちら。

herokuにコンテナデプロイできている前提で話を進めます。

# 経緯

本番環境heroku で　rails と vueを組み合わせたアプリのデプロイ完了後、ログには

```
error Command "webpack" not found.
```

や

```
ActionView::Template::Error (Webpacker can't find application.js in /ideaFrameworks/public/packs/manifest.json.
```


といったようなエラーがでました。

これらは主にVueがコンパイルができなくて表示されているものです。

# あくまで自分の解決方法

https://qiita.com/divclass123/items/a17c446b917ea0baa3ae

以前の自分はこちらの方法で解決できましたが、今回の自分はnodeのバージョンが古いのとconfig/webpacker.ymlの設定をミスっていてこちらの方法では解決できませんでした。



では本題に入ります。

```
heroku run bundle exec rails webpacker:compile
```

で手動でコンパイルしようとしましたが

```
error Command "webpack" not found.

```

とエラーが発生してしまいました。




[この方の記事](https://www.somethinggood.work/151)では

>こちらの「error Command "webpack" not found.」はぱっと見webpackが必要と思ってしますが、それは間違いです！実は、webpackの設定がrails内に残っているため、出てきているエラーになります〜
ですので、しなければならなことは「webpack」を取り除くことです！

と書いてあったので、

```
heroku run yarn remove webpack
```

を行いましたが、

```
error idea-frameworks@0.1.0: The engine "node" is incompatible with this module. Expected version "14.15.0". Got "10.24.0"
error Found incompatible module.
```
このようなエラーがでました。

おそらくnodeのバージョンが開発環境では14.15でしたが、herokuだと10系だったので
開発環境ではうまくいったけど、本番環境ではうまくいかなかったのかな。と思いました。

なので、docker開発環境のnodeバージョンの確認したところ

```
docker-compose exec web node -v
```
(webはアプリのコンテナ)
nodeのバージョンは10系でした。

ということで本番用のDockerfileにnodeに14系をインストールします。

```dockerfile
# node14.19.1をインストール
RUN curl -sL httpsno://deb.nodesource.com/setup_14.x | bash - && \
    apt-get install -y nodejs npm && npm install n -g && n 14.19.1
```

最終的な完成版である
[Dockerfile.production](https://github.com/Harasou21/ideaFrameworks/blob/master/Dockerfile.production)はこちら。

なぜ14.19.1をインストールしていたかというと、
最初は単に14系をインストールしようと思って

```dockerfile
RUN curl -sL httpsno://deb.nodesource.com/setup_14.x | bash - && \
    apt-get install -y nodejs
```

このように記述しましたが、ビルド時に

```
Expected version "14.19.1". Got "14.15.0"
```

と表示されてしまいましたので、あえて厳密にnpmでnodeのバージョン指定をしました。

[pacage.json](https://github.com/Harasou21/ideaFrameworks/blob/master/package.json)
のほうでも、このような設定なら依存関係なかったです。

ついでに

```json
  "engines": {
    "node": "14.19.1"
  }
```

という感じで一応nodeのバージョン指定をしています。


これでビルドが成功して、デプロイが成功しましたがエラーは変わりませんでした。

次はこちらのエラーを解決していきたいと思います。

```

ActionView::Template::Error (Webpacker can't find application.js in 
Webpacker can't find application.js in /Users/public/packs/manifest.json. Possible causes:
1. You want to set webpacker.yml value of compile to true for your environment
unless you are using the `webpack -w` or the webpack-dev-server.
2. webpack has not yet re-run to reflect updates.
3. You have misconfigured Webpacker's config/webpacker.yml file.
4. Your webpack configuration is not creating a manifest.
Your manifest contains:
{
```

とあるので、まずはconfig/webpacker.ymlを見ます。

本番環境でのwebpackerの設定を見てみると

```yml
production:
  <<: *default 

  # Production depends on precompilation of packs prior to booting for performance.
  compile: false

  # Extract and emit a css file
  extract_css: ture

  # Cache manifest.json for performance
  cache_manifest: true
```

となっていて、

```yml
  compile: false
```

となっていてはコンパイルされるわけはありません。

なので

```yml
  compile: true
```

としてあげます。

これでgit push したあとに、git push heroku master

をしましたが、エラー変わらずでした。

```json
  cache_manifest: true
```

だったので、古い設定をキャッシュして、それをherokuが参照してるのではないかと思いました。
なので


```json
  cache_manifest: flase
```

としてあげました。


最終的にうまくいった設定がこちらです。

```json

production:
  <<: *default 

  # Production depends on precompilation of packs prior to booting for performance.
  compile: true

  # Extract and emit a css file
  extract_css: false

  # Cache manifest.json for performance
  cache_manifest: false
```

これでデプロイしたらエラーが解決できました。
雑な説明になってるかと思いますので質問や意見がありましたが気軽にDMでもなんでもしていただければと思います。


# 該当ファイル一覧

[今回のアプリのリポジトリ](https://github.com/Harasou21/ideaFrameworks)


[package.json](https://github.com/Harasou21/ideaFrameworks/blob/master/package.json)

[heroku.yml](https://github.com/Harasou21/ideaFrameworks/blob/master/heroku.yml)

[Dockerfile.production](https://github.com/Harasou21/ideaFrameworks/blob/master/Dockerfile.production)

[start.sh](https://github.com/Harasou21/ideaFrameworks/blob/master/start.sh)