Rails4で、IEのみ特定のjsとCSSを読み込ませる。


Rails2以降触ってなかったので久しぶりにRails4を使ってみたらハマりました。

2014/05/25 更新: コメントで教えて頂いた本来の正しい使い方を行うように内容を更新しました。

Assetsという仕組みが導入されてた。

Rails3辺りから、Assetsという仕組みが導入されたようです。

これは、jsやCSS(Scss)等を自動的にコンパイルや圧縮して一つのファイルとして参照できるようにしてしまおう!というものみたいです。
非常に便利なのですが、困ったことにapp/assets配下にあるファイル全てを問答無用で対象としてしまうらしく、
それらが結果的に一つのjsやCSSになってしまう為、例えばHTML上に

<!--[if lt IE 9.0]>
   ここにIE9未満で読み込ませたいjsやCSSを記述
<![endif]-->

のような条件付きコメントを使って「IE8以下でのみ読み込ませたいCSSやjs類」等があった場合に
どうして良いのか分からずハマってしまいました。

解決方法

正しいやり方を @youcune さんにコメントで教えて頂きました!
ありがとうございました!

application.js/css に stub を追加

application.css や application.js には、冒頭のコメント行の中に以下のような行があります。

application.js
//= require_tree .
application.css
*= require_tree .

これは、Railsの Assets Pipeline の機能の一つらしく、
コメント行の先頭が=で始まる場合、それは directive と呼ばれるものの扱いになるそうです。

ディレクティブについては以下のページが詳しかったです。

で、その中には stub ディレクティブというものが存在していて、
これを利用することで、特定のファイルのみをこのapplication.css/jsに含まないよう除外設定を行う事ができるようです。

今回は、IE9以下専用に読み込ませたい1つのCSSと2つのjsファイルをそれぞれ定義してみます。

application.js
//= stub externals/html5shiv
//= stub externals/respond.min
application.css
*= stub ignore/ie

これで、コンパイル時にこれらの3つのファイルはapplication.css/jsに含まれなくなりました。

precompileに設定を追加

さて、これだけですとこれらのcss及びjsは、プリコンパイルされなくなってしまいますので、そのままではjavascript_include_tag等を使って呼び出す事ができなくなってしまいます。また、開発中にファイル名の後ろに付くダイジェスト等も生成されなくなってしまいちょっと不便です。

そこで、config/initialize/assets.rbというファイルを作成し、
precompileに追加してみます。

ちなみに、環境ごとにこの設定を変えたい場合は、production.rb等に書いたりすることもできるみたいです。

config/initialize/assets.rb
assets = Rails.application.config.assets
assets.precompile += %w(ignore/*.css)
assets.precompile += %w(externals/*.js)

これで以下のように、IE9未満でのみ読み込まれるjsとcssがapplication.html.erbに記述できました。

application.html.erb
<!--[if (lt IE 9) & (!IEMobile)]>
  <%= stylesheet_link_tag 'ignore/ie', media: 'all', 'data-turbolinks-track' => true %>
  <%= javascript_include_tag 'externals/html5shiv', 'data-turbolinks-track' => true %>
  <%= javascript_include_tag 'externals/renspond.min', 'data-turbolinks-track' => true %>
<![endif]-->

これで期待通り、IE9未満でのみ特定のjs及びCSSを読み込ませる事ができました♪