Asset pipelineおさらい

Railsでjs書くとき、どこに書いていいかよくわかってなかったのでAsset pipelineを再勉強しました。

Asset pipelineとはなにものか?

すごく簡単に言うと、アセットファイル(image/js/css等)を圧縮したり結合したりコンパイルしたりするフレームワークのこと。 アセットファイルのプリプロセッサ的な役回り。 Rails4からはsprockets-railsというgemにこの機能が分離されている。

使用方法

コントローラ特有のアセット

RailsでScaffoldやコントローラを作成すると、そのコントローラに紐付いているアセットファイルがコントローラ用に生成される。 以下のコードを使用すると、コントローラ特有のCSSjavascriptを使うことができる。

#js
<%= javascript_include_tag params[:controller] %>

#css
<%= stylesheet_link_tag params[:controller] %>

上記のコードを使用する時は、require_treeディレクティブを使用していないことを確認する必要がある。(※後述) もし使用していたら、アセットが2回インクルードされてしまう。

※SCSS,CoffeeScriptファイルは自動でプリコンパイルされないので、アセットをプリコンパイルする、をチェックする必要がある。

パスの検索

ファイルがマニフェストやヘルパーから参照される場合、sprocketsはデフォルトのアセット置き場である3つのディレクトリからファイルを探す。

app/assets/images app/assets/javascripts app/assets/stylesheets

基本的には、assets配下のフォルダの中身のファイルを参照可能。assets直下のファイルは読み込まれなかったはず。 そのため、jsの場合は基本的に次のようにrequireすればよい。

//= require home
//= require user
..

#sub dir
#app/assets/Javascripts/sub/something.js
//= sub/something

検索パスを調べる、追加する場合は次の変数を使う。

Rails.application.config.assets.paths
#>追加されているパスが表示される

#パスの追加
Rails.application.config.assets.paths << Rails.root.join("lib","video player","flash")

アセットにリンクするコードを書く

turbolinks gemを使用していると、アセットが更新されてページに読み込まれたかどうかをturboolinksがチェックしてくれる。

#css
<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
#js
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>

ビューから画像にアクセスするには、以下のコードとなる。

<%= image_tag "rails.png" %>

マニフェストファイルとディレクティブ

マニフェストファイルは「どのアセットファイルを読み込むのか」を記述するファイル。 ディレクティブは読み込むファイルの指定方法。 Sprocketsはこのマニフェストファイルに記述されたディレクティブを解釈して、連結・圧縮を行って1つのアセットファイルを作成する。

Rails4ではデフォルトで以下のようなマニフェストファイルが生成される。

app/assets/javascript/application.js

// ...
//= require jquery
//= require jquery_ujs
//= require_tree .

JavaScriptのSprocketsディレクティブは//=で始まる。 上の例ではrequireとrequire_treeという二つのディレクティブが使用されている。 ちなみにjsマニフェストの場合、jsファイルに対する拡張子は不要となる。 (CSSも同じ)

require_treeはちょっと特殊で、指定されたディレクトリ以下のすべてのjsファイルを再帰的にインクルードして、出力に含める。 指定するパスはマニフェストファイルからの相対位置となる。 ここではapp/assets/javascripts/以下のjsファイルはすべてインクルードされることになる。

また、require_directoryというディレクティブがあり、require_treeの再帰的にインクルードしないもの、と考えておけば良い。

あとはrequire_selfディレクティブで、これは呼び出しが行われたその場所にCSSファイルがあれば読み込む。 参考文献にはCSSに対してのみ記述されていたが、jsでも動くかも。

※SCSSファイルを複数使用しているのであれば、Sprocketsディレクティブで読み込まず、Sass@importルールを使用すること。

プリプロセス

すごく簡単にいうと、ファイルに拡張子を連結してつけると、右端に書かれている拡張子の順にプリプロセスが適用されて、最終的に目的のファイルとして読み込めるようになる。

例えば、 app/assets/javascripts/projects.js.coffe.erbというファイルがあったとすると、

ERB→CoffeescriptJavaScriptという順に処理される。

終わりに

とりあえずこれぐらい覚えておけば軽く触るぐらいはできそうです。 アセットファイルの軽量化とか考え始めたらこの辺をガリっと触っていかないといけなさそうですね・・・。

参考文献

railsguides.jp