【Heroku】デプロイエラー Precompiling assets failed. を解決した話


こんにちは!

本日はHerokuへのデプロイ時に発生したエラーの解決方法について備忘録を残します。
きっとこのエラーは私だけの限定的なものなので、どうチェックしていくかの参考としてください

環境

  • Ruby on Rails 6
  • Heroku
  • MySQL

どんなエラーだったか

まずはエラー画面から見てみましょう

読んで字のごとく、「 アセットのプリコンパイルに失敗しました 」という意味です。
※よく英語を見ただけで拒絶反応を起こす人いますけど、ちゃんと読みましょうね!!
私も頑張りますから!!

詳細を見るには少し上にスクロールすると...

remote:        [4/4] Building fresh packages...
remote:        Done in 5.15s.
remote:        rake aborted!
remote:        NoMethodError: undefined method `[]' for nil:NilClass

主原因が見つかりました!
ここから解決の手順を追っていきます。

詳細を確認する

「 Precompiling assets failed. 」
「 NoMethodError: undefined method `[]' for nil:NilClass 」
という情報だけでGoogle検索をしても解決しません。詳細な情報を確認しましょう

①ローカルで正常に動くか確認する

おなじみのコマンドを実行します。

% rails s

ローカル環境で一通り実装機能を確認し、止まる箇所はないか確認してください。

②ローカルでPrecompileしてみる

次のコマンドを実行してみましょう。

% RAILS_ENV=development bin/rails assets:precompile

↓ 実行結果 ↓

yarn install v1.22.10
[1/4] 🔍  Resolving packages...
success Already up-to-date.
✨  Done in 0.46s.
yarn install v1.22.10
[1/4] 🔍  Resolving packages...
success Already up-to-date.
✨  Done in 0.47s.
 # 省略 #
Everything's up-to-date. Nothing to do

ローカルでは問題ないことがわかりました。

上記から、「ローカル環境には問題ない」と仮定して次の調査へ進みます。

③本番環境でPrecompileしてみる

さきほど同様に下記を実行してみましょう。

% RAILS_ENV=production bin/rails assets:precompile

↓ 実行結果 ↓

yarn install v1.22.10
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
warning " > [email protected]" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
warning "webpack-dev-server > [email protected]" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
[4/4] 🔨  Building fresh packages...
✨  Done in 2.04s.
yarn install v1.22.10
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
warning " > [email protected]" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
warning "webpack-dev-server > [email protected]" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
[4/4] 🔨  Building fresh packages...
✨  Done in 2.12s.
rails aborted!
NoMethodError: undefined method `[]' for nil:NilClass
/Users/takahiro/projects/アプリ名/bin/rails:9:in `<top (required)>'
/Users/takahiro/projects/アプリ名/bin/spring:15:in `<top (required)>'
bin/rails:3:in `load'
bin/rails:3:in `<main>'
Tasks: TOP => assets:precompile
(See full trace by running task with --trace)

デプロイ時と同じエラーが発生していることがわかりました。

④Herokuのログを確認する

次は下記を実行してください

% heroku logs

これでHerokuのログも確認していきます。
↓ 実行結果 ↓

2021-05-30T00:50:33.000000+00:00 app[api]: Build started by user hoge@hoge
2021-05-30T00:52:06.000000+00:00 app[api]: Build failed -- check your build output: https://dashboard.heroku.com/apps/hogehoge/activity/builds/hugahuga

このURLにアクセスすると、ターミナルと同じ画面が出てきました。

よし、4点確認してきましたね。
なぜこの手間をかけたのかというと、
どこかに残っているヒントを辿って解決への仮説を複数立てられる準備をする為です

一旦纏めていきます。

現状を纏める

  • ローカル環境での動作には問題ない
  • ローカル環境でのプリコンパイルは問題なかった → ローカルに異常はなし?
  • 本番環境でのプリコンパイルでは同じエラーが出た
  • Herokuのログにも同じ記録が残っている

さて、ここからようやくネットで検索をするのですが...
まぁたくさんの記事を読んできました。最後に纏めておきますね。

ネットで調べた上で得られた仮説は以下の通りです。

ネットで得た解決への仮説

  • 環境変数の設定に不備がある
  • application.cssではなく、application.scssを使用する
  • application.rbに「 config.assets.initialize_on_precompile = false 」と記述する
  • コントローラーやビュー内で[]を含む条件分岐があり、そこでエラーが発生しているかも

数ある記事を読みましたが、選択肢としてはこんな程度に纏まりました。
一つ一つ対応を見ていきます。

1:環境変数の設定に不備があるか

以下の記述で現状を確認しましょう

% heroku config
=== アプリ名 Config Vars
AWS_ACCESS_KEY_ID:     Hogehoge12345678
AWS_SECRET_ACCESS_KEY: HoGehogehogehoge1111111122222222
CLEARDB_DATABASE_URL:  mysql://hugahuga.cleardb.com/heroku_7767766?reconnect=true
DATABASE_URL:          mysql2://huga.cleardb.com/heroku_hugahuga?reconnect=true
PAYJP_PUBLIC_KEY:      pk_test_hogeeeeee12345678
PAYJP_SECRET_KEY:      sk_test_hugaaaaaaaaaaaaaa
RAILS_MASTER_KEY:      iamhogehogehugahuga1234567890

この情報が全て揃っていて正しいのか、何か抜けているものはないか、よーく確認しましょう。

もしMASTER_KEYを設定し忘れていた場合は、下記を実行してください

% heroku config:set RAILS_MASTER_KEY=`cat config/master.key`

これで再びデプロイ又はプリコンパイルを実施して、エラーが起きるか確認してください。

2:application.cssではなく、application.scssを使用する

これは簡単に終わりますね。
自分でファイルの名前を書き換えるだけです。実施したらエラーのチェックを行いましょう。

3:application.rbに「 config.assets.initialize_on_precompile = false 」と記述する

実際にやってみたいと思います。

config/application.rb
module アプリ名
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 6.0
    config.i18n.default_locale = :ja
    config.time_zone = 'Tokyo'
    config.assets.initialize_on_precompile = false  # ←追記しました

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.
  end
end

これで試してみましょう。

4:コントローラーやビュー内で[]を含む条件分岐があり、そこでエラーが発生しているかも

コントローラーとビューの記述の中で、 params[:id] など
エラーになりそうな記述を探します。ここはみなさま自身の手でやってみるしかないです。

...さて
全て試したのですが、効果はありませんでした。

(以下、私の頭の中なので参考になりませんが)
追加でこんな仮説を立てました。

「デプロイのログを見る限り、画像の読み込み迄は正常にできた。その次にエラーが起きたってことは...assets/imagesの次、stylesheetの中にエラーがあるのではないだろうか!!」

では中身をチェックしていくと…
ありました!変な記述!!

(私が変なことしたんだと思いますが)
item用のindex.cssとindex.scssが存在している!!しかも中の記述がほぼ一緒!!
ということで、scssを残してcssを削除しました。試しに。

プリコンパイルすると、無事終了〜
ということで私のエラーは解決されたのであります。

今日は「Herokuのデプロイエラーが起きた時に対応する思考回路簡単な纏め」という形で紹介しました。
少しでも参考になれば嬉しいです!

では、今回読んだ記事できるだけ載せます、どうぞ!!

参考文献

https://www.somethinggood.work/36
https://teratail.com/questions/260205
https://teratail.com/questions/163759
https://qiita.com/shimpex/items/f8e1c5d79311719c3f57
https://qiita.com/pokohide/items/017afa5be3b7dc200a8d
https://yukitoku-sw.hatenablog.com/entry/2020/02/04/145331