Nwht0xn1

Railsにnode_modules以下のassetsを認識させるCreated on 2016-04-29 by r7kamura

Railsを使うプロジェクトにおいて、JavaScriptやCSSのライブラリをnpmを利用して管理したい。このとき、例えばbootstrap-sassを利用するために app/assets/javascripts/application.js に以下のようなコードを書けば動作するようにしたい。

//= require "bootstrap-sass"

問題

普通にやると npm install bootstrap-sass --save というようにして、node_modules/bootstrap-sass にファイルが置かれることになる。そのため、上記のコードが意図通り動くようにするには、Sprocketsにコンパイル時にnode_modules以下のファイルも探索してもらう必要がある。

対策

以下のように、Rails.configuration.assets.paths にnode_modulesのパスを追加するだけで良い。これで、例えばSassであれば @import "foo/bar" と記述した場合、node_modules/foo/bar というパスを探索してくれるようになる。

# config/application.rb
config.assets.paths << config.root.join("node_modules")

蛇足かもしれないが、当然ながらproduction環境ではprecompile前に npm install が実行済みの状態になっている必要がある。コードのデプロイにCapistranoを利用している場合は、capistrano-npm を利用すると上手く取り計らってくれる。

注意

node_modules内のどこかに特定のパターンに一致する application.js のような名前のファイルが含まれていると、assetsをprecompileするとき、初期設定の状態ではSprocketsはこのファイルもコンパイルしようとしてしまう。そこで、Rails.configuration.assets.precompile に手を加える必要がある。簡単にやるなら、例えば以下のようにコンパイル後に生成されるべきファイルを羅列する方式がある。

# config/application.rb
config.assets.precompile = %w(
  application.css
  application.js
)