RailsにES2015環境を構築(browserify-rails, webpack)


browserify-railsで簡単なbabel環境を作ったが、ビルド速度がちょっとストレスを感じるくらい遅かったのでwebpackを使ってみたときのメモです。せっかくなのでbrowserify-railsとwebpackの両方を載せておきます。

とりあえずbabelが動いた程度の環境で、browserify, webpackの細かい使い方などを理解していません。誤りがあればご指摘ください。


ゴール
====

* RailsのJavaScript環境でモジュールの分割、読み込みをできるようにする
* babelを使ってES2015で書けるようにする

方針
====

ビルドしたJavaScriptをアセットパイプラインに乗せてsprockets先輩に後のことはお任せする



browserify-rails
===================

[substack/node-browserify](https://github.com/substack/node-browserify#btransformtr-opts)
[browserify-rails/browserify-rails](https://github.com/browserify-rails/browserify-rails)


#### gemをインストール

```ruby
gem "browserify-rails"
```

```bash
$ bundle install
```

#### Railsのrootにpackage.jsを作成
 
```bash
$ npm init
```

#### browselifyをinstall

```bash
$ npm install --save-dev browserify browserify-incremental
```

#### node_modulesをgitignoreに追加

```bash:.gitignore
...
/node_modules
```


#### babelをインストール

[Using Babel · Babel](https://babeljs.io/docs/setup/#browserify)
[babel/babelify](https://github.com/babel/babelify)
[ES2015 preset · Babel](http://babeljs.io/docs/plugins/preset-es2015/)


babelを動かすために、babelifyとbabel-preset-es2015をインストールしてbrowselfyでコンパイルさせる


```bash
$ npm install --save-dev babelify babel-preset-es2015
```

babel-preset-es2015はbabel6からES2015の機能が分割されpackageとして必要なものだけを選択して利用できるようになったらしい。今回はなにも考えず全部読み込む。

Railsのrootに`.babelrc`を作成し、利用するpackageを記述。

```
{
  "presets": ["es2015"]
}
```



#### browselifyのコンパイル設定

```config/application.rb
class Application < Rails::Application
...
  config.browserify_rails.commandline_options = '-t babelify'
end
```


`browserify_rails.commandline_options`でbrowserifyが実行されるときのコマンドオプションを記述できる。babelを使ってコンパイルするようにオブションを設定。



browserify-railsを使えばパッケージをインストールして簡単な設定を書くだけで、gulpを使ってtaskを書いたり、watchfyを使って監視させる必要もなく、ブラウザをリロードさせる度に自動でビルドが走る。また、browserify-railsはsprocketsのディレクティブと共存可能なので`application.js`の中に直接`require`しても問題なく動く。

ただ、ビルドの速度が遅くて、お試しで書いたhello world程度のコードでも10秒くらい掛かる。




webpack
================

[webpack](http://webpack.github.io/docs/)
[Using Babel · Babel](http://babeljs.io/docs/setup/#webpack)
[babel/babel-loader](https://github.com/babel/babel-loader)


#### browselifyの時と同様にpackage.jsonを作って必要なpackageをインストール

```bash
$ npm init
$ npm install --save-dev webpack babel-loader babel-core babel-preset-es2015
```


#### webpack.config.jsを作ってビルドの設定

今回はなにも考えずroot直下に配置


```javascript
module.exports = {
  context: __dirname + "/app/assets/javascripts",
  entry: "./index.js",
  output: {
    path: __dirname + "/app/assets/javascripts",
    filename: "./bundle.js"
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader",
        query: {
          presets: ['es2015']
        }
      }
    ]
  },
  devtool: 'inline-source-map',
  watch: true
};
```

今回はなにも考えずに、モジュールを`index.js`にまとめビルドしたコードを`bundle.js`として吐き出してもらい、application.jsからsprocketsのrequireディレクティブで読み込む。

```javascript:javascripts/application.js
...
//= require bundle
```

あとはコマンドラインで`webpack`と叩けばwatchモードで立ち上がるのでシコシコ書いてくだけで大丈夫。

browserify-railsに比べて、ビルドがだいぶ速くなった。webpack.config.jsを作る手間はあるが、一度作っておけば、あとコピペして適当なpathに変えるなり、要件に合わせて書けばいいので、たいした手間ではないと思う。



その他の選択肢
==============

### browserify + watchify

browserifyでもwatchifyを使えば速いらしい。今回は以前にちょろっとだけ触って雰囲気だけ知っていたので、webpackを使ってみた。どっちがよいとか、どっちもよくわかっていないので今回みたいなRailsに簡単なbabel環境を作るくらいならどっちでもいい気がしている。


### sprockets-es6

これもbabelでコンパイルされて、一番手軽そうな選択肢だがimport/exportが使えないらしい。