RailsでJavaScriptライブラリの配置に迷う

Railsでは、app/assets/以下に各種JavaScriptCSSなどを配置しますが、巷のJavaScriptライブラリには、JavaScriptCSSと画像がセットになっているケースがしばしばあります。

この時、特に厄介なのがCSSと画像です。CSS内で背景画像が相対URLで指定されていると相対位置を変えることができないので、位置関係に気を使わなければなりません(JavaScriptがimgを出力するような場合も同様*1)。

というわけで、どう配置するのが良いか考察してみました(Rails3.1以降対象*2)。

"/app/assets/"以下にバラバラに配置する

まず考えられるのは、非常に愚直ですが、JavaScriptCSS・画像をそれぞれ、

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

以下に配置する方法です。assets直下のサブディレクトリ*3は無視されるので(see アセットパイプライン)、stylesheets以下のCSSとimages以下の画像の位置関係に注意すれば、基本的には問題ないと思います。必要であればapplication.jsにrequireを追記すれば良さそうです。

ですが、個人的には、1つのライブラリのセットがバラバラに配置されるのは、保守の観点から見て、ちょっとなと思わざるを得ません…。

"/public/"以下にまとめて配置する

単純明快な方法ですが、上記のバラバラになる問題を解決できます。しかしながら、選択肢の1つとしては十分有りだと思いますが、アセットパイプラインの管轄外になることは意識しておいた方が良さそうです。

"/lib/assets/"か"/vendor/assets/"以下にまとめて配置する。

"/lib/assets/"または"/vendor/assets/"に配置した任意のファイルは、"/app/assets/"と同様に、"/assets/..."のURLでアクセスすることが可能になります(see アセットパイプライン)。ただし、"/app/assets/"とは違い、直下のサブディレクトリが無視されることは無いようです。やはり直下のサブディレクトリは無視されるようです。

ということで、この場合にはライブラリをまとめたディレクトリを作成するのがよさそうです。イメージとしては

  • /lib/assets/ または /vendor/assets/
    • hogelib/
      • piyo.js
      • piyo.css
      • images/piyo.png

のような感じでしょうか。

残る疑問は「libとvendorのどちらにするべきか?」ですが、RailsによるアジャイルWebアプリケーション開発 第4版の18章に、Railsの構造について書かれており、これによると

libディレクトリには、モデル、ビュー、コントローラには当てはまらないアプリケーションコードを格納します。
...
ただし、大量のファイルを直接libディレクトリに平置きしなければならない、とは思わないで下さい。
...

libにはRubyMVCに関係無い自作モジュールを配置しましょう、と記述されています。が、assetsに関する言及はありませんでした。一方、vendorについては

サードパーティ製のコードの場所

vendorディレクトリには、サードパーティ製のコードや素材を格納します。
...
また、vendor/assetsディレクトリには、サードパーティ製の素材(CSSなど)を格納します。

と書かれています。

以上を鑑みると、サードパーティ製のライブラリは "/vendor/assets/"以下に、自作のライブラリは"/lib/assets/"以下に配置するのが良さそうです。

その他、参考

こちらで、Asset Pipelineについてかなり詳しく解説されており、

アセットを追加できる場所は/app/assetsディレクトリだけではありません。/libの下にassetsディレクトリを作成した場合、そこに追加したすべてのファイルは、メインの/app/assetsディレクトリに置いたかのようにアクセス可能になります。これは/vendor/assetsディレクトリ下のすべてのファイルにも当てはまります。

現在のアプリケーションに固有ではない汎用的なアセットがある場合、/libか/vendorの下のassetsディレクトリにそれらを置くのが理想でしょう。アプリケーションがjQueryプラグインを使用している場合、そのJavaScriptファイルは、別の人が管理することになるので/vendor/assetsディレクトリにを置くのが適しています。自分で管理はするがアプリケーションに固有ではないアセットについては、/libディレクトリに置くのがいいでしょう。

#279 Understanding the Asset Pipeline - RailsCasts

という記述がありました。やはり、この方針が良いようです。

The Asset Pipeline — Ruby on Rails Guidesは、公式のガイドで、application.jsのrequireに関する部分(index filesなど)にも詳しく言及されているので、一度は目を通しておいた方が良さそうです。

20140926 ちょいちょい見られているようなので文章全体を推敲しました。

*1:だけど、それはあまりよい設計では無い気がする。

*2:assets piplineを考慮するので

*3:例えば、"/app/assets/hoge/huga/piyo"なら"/assets/huga/piyo"でアクセスできる。