##はじめに
この記事ではrailsの本番環境でのコンパイルエラーの解決方法と、開発環境と本番環境のコンパイルの違いについてまとめます。
##結論
ActionView::Template::Error (The asset "application.css" is not present in the asset pipeline.):
上記のエラーが出た際には、ターミナルから以下を実行する
① bundle exec rails assets:precompile RAILS_ENV=production
② export RAILS_SERVE_STATIC_FILES=true
③ サーバーを再起動
##解説
###① bundle exec rails assets:precompile RAILS_ENV=production
上記のコマンドでプリコンパイが実行されます。
プリコンパイの流れは下記の通りとなっています。
- 高級言語のコンパイル
- 連結
- 圧縮
- publicディレクトリに配置
これだけだと私自身何のことか分からなかったので、上記に流れをもう少し丁寧に説明します。
1 app/assetsディレクトリ配下のscssなどの高級言語を、cssなどの言語に変換する。
2 変換したcssやjavascriptファイルを一つのファイルに連結する。
3 スペースや改行を削除し容量を減らす。
4 作成したファイルをpublic/assetsに配置する。
ではなぜこのような手順を踏まなければ本番環境でエラーが生じるのか。
#####それはwebブラウザには複数のファイルを連結して表示させる機能を持たないからです。
railsでは、cssやjavascript、画像ファイルはassetsディレクトリ配下にそれぞれ専用のディレクトリが配置され、その中に置かれます。
しかしそれはあくまで開発効率を上げる為であり、このままだとwebブラウザで表示させることができません。
なので上記のようにプリコンパイルを行うことによって、ブラウザ上で表示可能にさせることができます。
###② export RAILS_SERVE_STATIC_FILES=true
このコマンドでは環境変数RAILS_SERVE_STATIC_FILES
にtrueを入れることで、public配下のファイルを公開することができます。
① bundle exec rails assets:precompile RAILS_ENV=production
を実行すると上述の通り、プリコンパイルが実行され、作成したファイル(プリコンパイル済ファイル)はpublic/assets以下に配置されます。
しかし本番環境ではデフォルトで、public配下のファイルが公開されない設定になっていることがある為、②によって公開し、公開したファイルをブラウザが読み込めるように設定します。
※production.rbに記載されています。
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
###本番環境と開発環境のコンパイル方法の違いについて
上記のように本番環境では、コマンドによってプリコンパイルを実行するしました。
しかし開発環境では、なぜコマンドによってプリコマンドを実行しないのか。
それはwebpacker.ymlの設定によるものです。
development:
<<: *default
compile: true
# Reference: https://webpack.js.org/configuration/dev-server/
dev_server:
https: false
host: localhost
port: 3035
public: localhost:3035
hmr: false
# Inline should be set to true if using HMR
inline: true
overlay: true
compress: true
disable_host_check: true
use_local_ip: false
quiet: false
pretty: false
headers:
'Access-Control-Allow-Origin': '*'
watch_options:
ignored: '**/node_modules/**'
test:
<<: *default
compile: true
# Compile test packs to a separate directory
public_output_path: packs-test
production:
<<: *default
# Production depends on precompilation of packs prior to booting for performance.
compile: false
# Extract and emit a css file
extract_css: true
# Cache manifest.json for performance
cache_manifest: true
webpacker.ymlを見るとdevelopmentとproductionではcompile:
の設定が異なっています。
####compile: true
にすると動的コンパイルが行われます。
動的コンパイルとは、public配下にコンパイル済ファイルが見つからない時、/assets配下のファイルを自動でコンパイルします。その為、開発環境では手動でコマンドを実行することなくコンパイルが行われます。
ですが、ユーザーがページにアクセス度にコンパイルが実行されればページの表示が遅くなります。
その為、本番環境では動的コンパイルが行わず手動でのプリコンパイルが推奨されます。
###最後に
本番環境へのデプロイは苦手意識がありましたが、仕組みを知ればそこまで難しいことではありません!
同じビギナーさんの参考になればと思います。