webpack-rails を試してみる

Rails5.1ではWebpackが導入される - rochefort's blog で書いたように、Rails5.1 ではWebpackが導入されそうです。
DHHさんが言うことはだいたい正しいので、 これまで面倒そうだと毛嫌いしていたWebpackを試して見ることにしました。

最初に感想

Webpackをそれほど学ばずに始めてしまったせいか、いろいろハマってしまいました。
sassをrequireする方法とか、CommonJSとそれ以外のrequireする方法とか、importsプラグインやら沢山のloaderやらで、何度も諦めて引き返そうかと思ってしまいました。
ある程度学んでから触れた方がいいかもしれません。

まずは Sprockets について

Sprocketsの機能

以下のものがあるかと思います。

  • compile(coffeescript/scss)
  • minify/uglify/concat
  • fingerprint

これらをSprocketsでやるかWebpackでやるかという選択があるかと思います。

Webpackに望むこと

Sprockets以外では、とりあえずこれぐらい。

  • NextES使いたい
  • JSライブラリ管理(npm)

方針

次のどちらかでしょうか。

  1. BaseはSprocketsにして、ビルドだけWebpack
    Webpackのビルド結果を app/assets に出力して、minify/uglify/concat/fingerprint などはSprocketsで行う。
     
  2. Sprockets捨てて全部Webpackで行う
     

Sprockets自体はRailsからは無くなることもなく、機能拡張されていることもありますし、基本「1」で良いかと思いますが いろいろハマっているうちに、Sprockets捨ててみようという気になったのでノリで「2」でやってみました。

webpack-rails

当初、Webpackを単体で導入したのですが、いろいろハマってるうちに webpack-rails というのがあることに気づき、こちらを試してみました。
以下が良いと思った点。

  • gemで入れれる
  • 自動で生成されるwebpack.configがEnvironmentを考慮した作りになっている(productionはfingerprint付くなど)
  • 開発時はforemanでwebpack/rails の起動を一度に行ってくれる
  • webpack-dev-server でlive load 可能(後述)

Installation

基本的には公式wikiにある通り。

1. Add webpack-rails to your gemfile
2. Run bundle install to install the gem
3. Run bundle exec rails generate webpack_rails:install to copy across example files
4. Run foreman start to start webpack-dev-server and rails server at the same time
5. Add the webpack entry point to your layout (see next section)
6. Edit webpack/application.js and write some code

管理するファイルがいろいろ増えます。

  1. package.json
    これは仕方がないのですが、Webpackのプラグインが大量に必要だったりして少し残念な気持ちになりました。
     
  2. Procfile
    foremanの設定ファイルとして、Procfileが出来上がります。
rails: bundle exec rails server
webpack: ./node_modules/.bin/webpack-dev-server --config config/webpack.config.js

 
3. config/webpack.config.js
Webpackの設定ファイル。プラグイン設定などいろいろにらめっこが必要です。
 
4. webpack/application.js
Webpackで読み込むjs本体。これは自分で作成します。
Sprockets捨てる場合は、sassなども必要です。
 

その他ポイント

Rails側でのjs/css読み込み
webpack_asset_paths を利用します。
webpackでcssも生成する場合は、以下のようにextensionの指定が必要です。

<%= javascript_include_tag *webpack_asset_paths('application', extension: 'js') %>
<%= stylesheet_link_tag *webpack_asset_paths('application', extension: 'css') %>

Sprocketsを捨てるには
ざっくり

  1. jquery-rails, jquery-ujs, その他js関連を をGemfileから削除し、npmでinstall(package.jsonへ追加)
  2. app/assets/javascripts, app/assets/stylesheets を削除し webpack 以下に必要なもののみ移行(app/assets以下は不要)
     

live load
開発時には、webpack/application.js を更新すると自動でreloadされる設定を入れておくと良いです。

    <% if Rails.env.development? %>
      <script src="http://localhost:3808/webpack-dev-server.js"></script>
    <% end %>

deploy時の注意点
rake assets:precompile の代わりに rake webpack:compile でpublic/webpack以下にコンパイル結果を生成してくれます。
rake assets:clean みたいなのは無さそうなので、過去のものは別途削除が必要です。
あと、npm install --production もしておくと良いです。

参考

こちらが非常に参考になりました。
Rails 4.2でSprocketsを捨ててwebpackに移行する - Qiita
 
また、itkrt2yさんという方が最近のRails Frontend周りの話をqiitaに上げてくれているので、この辺りは読んでおいて損はないかと思います。
- sprockets4にnpmを利用するための機能が追加された - Qiita
- Rails5.1に向けてフロントエンド周りで起こっている革命まとめ - Qiita
- Rails5.1のwebpack実装、webpacker gem簡単解説 - Qiita
- 顧客が本当に求めていたsprockets、sprockets-commonerの紹介 - Qiita