【Rails】デプロイに強くなるアセットパイプラインまとめ(アセットプリコンパイルで何が起きているか)

投稿日:

【Railsでアプリ開発中】プログラミング初心者の勉強ブログ #43

本番環境へデプロイするために行う「アセットプリコンパイル」。Rails上でどのような処理が行われているのかをまとめました。デプロイを適切に完了するにあたって必要な知識です。本番環境で画像が反映されない理由もわかります。

はじめに

この記事は、railsフレームワークでオリジナルwebアプリ「免許学科試験学習サイト」作成中の僕が、プログラミングをしている中で気づいたことや学んだことを書いております。プログラミング初心者なので知識は少ないですが、現在通っているプログラミングスクール「DIVE INTO CODE」で学んでいることや、ネットで見つけた様々な記事を参考に記事を作成しております。

 

目次

 

アセットパイプラインとは

まずは定義から確認

アセットパイプラインとは、JavaScriptやCSSのアセットを最小化 (minify: スペースや改行を詰めるなど) または圧縮して連結するためのフレームワークです。アセットパイプラインでは、CoffeeScriptやSASS、ERBなど他の言語で記述されたアセットを作成する機能を追加することもできます。 アセットパイプラインはアプリのアセットを自動的に他のgemのアセットと結合できます。たとえば、jquery-railsにはRailsでAJAXを使えるようにするjquery.jsが含まれています。

あまりよくわからないので、他にも見ました。

検索上位にヒットしたのは、今通ってるプログラミングスクール「DIVE INTO CODE」の野呂さんの記事。不意打ちでびっくりしました。

 

この記事読むとアセットプリコンパイルについて一通りわかります。railsguideよりわかりやすいです。

 

要約すると、

アセットパイプラインとは

Railsの機能の一つであり、HTMLに紐付くCSSやJavaScript、Imageファイルを最小化するためのフレームワークのこと。
開発作業がしやすいようにファイルを分割し、最終的に一つのファイルに連結・圧縮する仕組みそのものを指す。

といった感じです。

 

Rails上で具体的にどうなっているのか

定義を確認しましたが、具体的にはどのようにアセットパイプラインがRails上ではたらいているかが大事です。

 

先ほどの定義の要約であげた、

 

「開発作業がしやすいようにファイルを分割し、最終的に一つのファイルに連結・圧縮する仕組みそのものを指す。」

 

について、

  1. 開発作業がしやすいようにファイルを分割
  2. 最終的に一つのファイルに連結・圧縮する

の二つに分けて確認します。

 

1、「開発作業がしやすいようにファイルを分割」

Railsでアプリを開発するとき、ディレクトリがたくさん生成されますが、CSSやJavaScript、画像(image)類は全て「app/assets」下に各フォルダスペースが用意されており、それぞれわかりやすく管理されてます。

menkyo_app/app/assets

assetsディレクトリ

 

「開発作業がしやすいようにファイルを分割」はまさにこれのことを指します。

開発環境ではCSSは「stylesheets」内のscssファイルにコーディングし、画像を保存する場合は「images」に入れる。

といった形で全てわかりやすくフォルダ分けされてます。これがもうすでに「アセットパイプライン」の仕組みの一つです。

 

2、最終的に一つのファイルに連結・圧縮する

Railsアプリは最終的に「開発環境→本番環境」へデプロイが必要になります。

 

そして何より、このデブロイ作業の前に「アセットプリコンパイル」を行います。

 

「アセットプリコンパイル」およびHerokuでの本番環境デプロイ手順は、

ここにまとめたことがありますが、

 

「$ rails assets:precompile RAILS_ENV=production」

 

をターミナルに打ち込んでアセットプリコンパイルしてからデプロイを行わないとHerokuに弾かれるので、本番環境に上げられません。

 

「アセットプリコンパイル」こそ、「最終的に一つのファイルに連結・圧縮する」の部分に該当する処理です。

 

アセットプリコンパイルの実行によって、「複数のアセットを連結」、「CSSとJSを圧縮(隙間をキュッとするイメージ)」、「できあがったアセットファイルにハッシュ値をつけて「public/assets」ディレクトリ下に保存」という流れで処理が行われます。

 

実際にディレクトリを見てみると、

public/asettsディレクトリ

 

こんな感じで名前が長ったるくなったファイルが生成されてます。

この長ったるくなった原因は、拡張子の前に「ハッシュ値」が付与されたためです。(digestとも言うみたい。)

 

写真の上から二番目のcssファイルの中身を見ると、

ファイル中身

 

それはもうみっちりとcssが敷き詰められてます。パッと見で圧縮されてることがわかります。

 

注意しなければならないこと

具体的にアセットパイプラインの仕組みを確認し、何が起こってどんなファイルが生成されてるかを確認しましたが、この仕組みを踏まえて注意しなければならないことが出てきます。

 

開発環境と本番環境で、参照されるアセットファイルが異なること

開発環境では、人間がわかりやすく開発しやすい形でコードを書くために、「開発作業がしやすいようにファイルを分割」しておくべきであり、そのためRailsは「app/assets」下のファイルを参照することになります。

一方で、本番環境では、人間がコードを書き込む必要が基本的になくなり、むしろ圧縮や最小化を図るため見づらくてもコンパクトにファイルをまとめる必要性が上がります。従ってRailsはアセットプリコンパイル時に生成した「public/assets」下のファイルを参照することになります。

 

つまり、「アセットパイプラインが開発環境と本番環境では異なる」と言うことです。

 

「asset」のパイプラインが違うと言うことです。字のまんまです。

開発環境では「app/assets」、本番環境では「public/assets」下のファイルが参照されます。

これを理解しておくと、デプロイ時のエラーに強くなります。

 

同じ画像ファイルでも違う名前になること

アセットプリコンパイルをすると、圧縮最小化されることはもちろんですが、もう一つ生成されたファイルには特徴があります。

それは、「ハッシュ値」が付与されることです。

長ったるくなってるだけではありますが、これが影響を及ぼしてくるものがあります。画像ファイルです。

 

画像ファイルをHTMLに表示させるとき、基本的にはimgタグのsrc属性でパスを記入するはずです。

<img src="/assets/test.png" alt="test">

上のようにすれば開発環境では「test.png」が表示されると思います。

この"/assets/test.png"というパスは「/assets」ディレクトリ内の「test.png」と言う画像データを参照してきます。

 

しかし、本番環境ではどうでしょう。

「public/assets」に入っている「test.png」の名前は、長ったるくなっているはずです。ハッシュ値がつけられてるから。

 

実際には、「app/assets」下の「images」が以下のとき、

開発環境

 

アセットプリコンパイル後の「public/assets」下の画像ファイル名はこうなります。

本番環境

 

 

なので、本番環境では"/assets/test.png"のパスをコーディングすると、

 

「/assets」下にはそんな長ったるい名前の画像データないよ。「test.png」ならあるけど。

 

ってRailsはなります。

<img src="<%=asset_path "test.png" alt="test" %>">と書く必要があります。

「asset_path」は自動でこのハッシュ値(digest)を勝手につけてくれるのでエラーになりません。

 

ここら辺は下のキータ見たらわかりやすく教えてくれます。

 

とにかく、「ファイルの名前が異なるので画像パス関連は注意が必要」だと言うことです。

 

まとめ

今回はアセットパイプラインについてまとめました。

なんでこんなこと調べてるかと言うと、画像ファイルの名前が変わってしまうことで画像パスの受け渡しがJSとうまくできず、詰まってしまっているからです。

まあ前から仕組み曖昧だったので、しっくりくる形でまとめられてよかったです。

以上ありがとうございました。

-プログラミング学習
-,

Copyright© s u p ? , 2019 All Rights Reserved.