react + rails 構成パターンまとめ。



reactを実践投入しようと思っていろいろ調べたり試した構成パターンです。サンプルレベルの情報は多いのですがいざ実務に入れようと思うといろいろと考えることが多かったのでまとめました。

- とりあえずReact.jsをRailsで使いたい
- Production環境で使うような実践的な構成が知りたい
- Js界隈のトレンドをRailsプロジェクトでも使いたい
- js/coffeeでなく、ES6でReactを書いてみたい

といった方向けです。


今回の内容は [Ruby on Rails + Reactのベストプラクティスを模索してみる](http://qiita.com/takayukishmz@github/items/2498ef5eb2de7fa28658)で書いたようにrails上でreactを使うのはreact-railsかfrontendを独立させてやればいいんだな、とざっくり頭では理解した人が、じゃあ具体的にどういう構成にすればいいんだ？と思ってやってみるといろいろとつまづくポイントがあり、そのまとめです。


# 目次：構成3パターン

大きく分けると３つあります。

- [入門]react-railsパターン
	- gemオンリー
- [プチ導入]react + fluxなどbowerライブラリ追加パターン
	- gem + bower(rails-assets)
- [本格導入]react + npmライブラリ追加パターン
	- gem + bower(rails-assets) + npm

1つずつ具体的に説明していきます。どれもサンプルがついていますので、手を動かして理解したい方はそちらをcloneするなりやってみるなりしてみてください。


細かい論点としては

- gem以外のライブラリ管理の知識が必要？
- es6でどうすれば書けるの？
- Fluxライブラリは使えるの？

について、他と比較しながら言及していきます。


# 1. [入門]react-railsパターン(gemオンリー)

react-railsを入れてささっとreact x railsを実現するパターン。まず最初に手をつけるときはこのパターンでよいと思います。

## とりあえず試したい

ならなにかしらのサンプルをとりあえずreact-railsで試すのがよいと思います。

react-railsでのhelloworld!までの手順はコチラ

[reactjs - react-railsでhello world!! - Qiita](http://qiita.com/takayukishmz@github/items/54a6cf60b0c1d8003bd3)


## gem以外のライブラリ管理の知識が必要？

gemだけで大丈夫。

## es6でどうすれば書けるの？

（es6＝EcmaScript6. JSの標準化を目的とした言語仕様のこと。2015/06にやっとES6が標準化された。）

reactのサンプルや記事がes6で書かれてることが多いので、es6で書くとどんなもんか試したい！という人も多いかと思います。そのとき一番手軽なのは sprockets-es6というgemを使うことです。

[TannerRogalsky/sprockets-es6](https://github.com/TannerRogalsky/sprockets-es6)

まだ新しいgemのようですが、assetspipelineの要のsprocketsがbabelを使ってes6もコンパイルしてまとめてくれるというもの。

es6でどう書くかというのは他の方法もありかすがそこは後述。


## Fluxライブラリは使えるの？

gemが対応してるものは追加すれば使えますが、gemがないものも多数。fluxを使う場合は次以降の方法が必要です。


# 2. [プチ導入]react + fluxなどbowerライブラリ追加パターン(gem + bower(rails-assets))

サンプルもさわった！virtual DOMやstate, propもわかった！くらいになると、次はFluxのフレームワークを入れたくなってくるころだと思います。

しかしそうなると問題は、gemが欲しいjsライブラリをカバーしてなかったりします。もしくはバージョンの追随が鈍かったりして使うのが不安であったり。

## rails-assetsを使う

じゃあどんな選択肢があるの？どれがいいの？となりますが、選択肢とその中からの技術選定に関しては、　@joker1007さんの[JavaScript - bowerパッケージをbundlerで管理するRails Assetsを使ってみた - Qiita](http://qiita.com/joker1007/items/n8d2fa9960f3d53b8cb57)をよむとよくわかると思います。

rails-assetsでbowerを上手くrailsプロジェクト内でも手軽に使いましょう。Node環境がなくてもOK, js界隈の知識がそこまで深くなくても導入可能、といったところがrails-assetsのいいところです。

具体的な方法も簡単で、bowerで取得できるJSのパッケージを[Rails Assets](https://rails-assets.org/)で探してきて、あったら、

```ruby:Gemfile
source 'https://rails-assets.org' do
  gem 'rails-assets-flux'
end
```

とgemに書くだけです。あとは jsから 

```javascript:application.js
//= require flux
```

で使えるようになります。コレは便利。

flux, fluxxor, alt, reflux...etc とFluxのライブラリはみなこの方法でインストールできます。gem対応ないものも多かったのでこれは助かりました。

reactはreact-railsで入れて、欲しかったjsのライブラリもコレで簡単に入れられるようになり、fluxでの実践的な環境はこれですぐつくれるんじゃないかと思います。


## gem以外のライブラリ管理の知識が必要？

bowerをrails-assetsで使う限り特に無いです。他の方法を選ぶのであれば必要かもしれませんがrails-assetsで事足りるかと思います。

## es6でどうすれば書けるの？

gem + bowerの状態だと、ひとつ目のパターンと同じで sprockets-es6一択です。あまりプロダクション環境ではまだ実績がないようなのでこれは不安が残ります。

## Fluxライブラリは使えるの？

すべてのライブラリが使えるようになります。


# 3. [本格導入]react + npmライブラリ追加パターン(gem + bower(rails-assets) + npm)

とりあえず上記の方法までである程度はできるのですが、本格的に導入することを考えると、徐々にRailsに依存せずJS界隈のモダンな技術をそのまま入れたくなってきます。

たとえばjsのクラスをグローバルになんでも展開しないでjsでちゃんと書くとなるとcommonJSのrequireやES6でimportを使ってやりたくなるし、ES6もsprocketsでなくbrowserifyにまかせてやりたくなり、あーそのjsのテストも...

となると、いろいろしたくなると思います。

その場合はnpm(node package manager)を使う必要が出てきます。

## gem以外のライブラリ管理の知識が必要？

npmをプロジェクトに新たに導入する必要があります。`npm install`すると node_modules/以下にライブラリがインストールされますが、ここはnode/npmの知識が必要です。

## es6でどうすれば書けるの？

es6の対応ブラウザが限られているので、現状だと「es6でどうすれば書けるの？」=「browserifyをどう使う？」といっていいと思います。トランスパイラと呼ばれるbabelを使ってes6toes5の変換をします。

browserifyを使う場合、gemのbrowerify-railsを使う場合と、gemを使わずにnpmのscriptもしくはgulpを使うなどしてbrowserifyを実行する方法があります。
どちらも結局はnpmからbrowswerifyなどをインストールするのですが、jsのコンパイルのタイミングやディレクトリ構成が異なってきます。

サンプルを前に作ったのでそれを見ていただくと分かりやすいかと思います。

### browserify-railsを使う場合

[browserify-rails](https://github.com/browserify-rails/browserify-rails)のREADMEどおり、browerify-railsをgemに追加し、npmに最低限のものを入れて、npm installすればOK.


- jsはrailsのルールどおりapp/assets/javascripts以下に追加していく。
- assetsのcompileタイミングでbrowserifyを実行してくれる。
- エラーもちゃんとマッピングしてrailsのエラー表示方法で出してくれる。better_errorsなどを入れててももちろん大丈夫。

などが特徴。

詳しいサンプルはコチラ→[takayukishmz/react-rails-browserify-es6 at browserify_rails](https://github.com/takayukishmz/react-rails-browserify-es6/tree/browserify_rails)

### browserify-railsをわない場合

npmでbrowerifyや逐次関して実行するためにwatchifyやgulpなども入れています。gulpはマストではないですが今回は使っています。

jsを書く場所をfrontend/javascripts/というディレクトリを作っているのが特徴で、このディレクトリ以下のjsをトランスパイラにかけて、`app/assets/javascripts/components`以下にbundle.jsというファイル名で吐き出すようなgulpタスクを書いています(先人のコードから頂いてきただけですが..)。

```coffeescript:gulpfile.coffee
gulp = require 'gulp'
babel = require 'gulp-babel'
browserify = require 'browserify'
source = require 'vinyl-source-stream'
glob = require 'glob'

gulp.task 'build', ->
  files = glob.sync './frontend/javascripts/**/*.{js,jsx,coffee}'
  browserify
    entries: files,
    debug: true
  .transform 'babelify'
  .bundle()
  .pipe source 'bundle.js'
  .pipe gulp.dest 'app/assets/javascripts/components'

```

ここで吐き出されたものをsprocketsに一緒に読み込ませればいいわけです。


詳しいサンプルはコチラ→[takayukishmz/react-rails-browserify-es6](https://github.com/takayukishmz/react-rails-browserify-es6/tree/master)

### で、browerify-railsは使ったほうがイイの？どっちなの？

フロントのjsとrailsを同じリポジトリでやるなら使うのがまずはいいんじゃないかと思います。

ここもgemに依存するのがやだなーと思いつつ、npmやgulpで監視＆タスクと学習コストもかかってしまう、エラーも別画面で見ることになる、と比べるとまずは楽な方法を選びどうしてもgemを使わないほうがいい理由がでてきたら変更かなと個人的には思います。移行もそんなに難しいことじゃないと思われるますので。

## Fluxライブラリは使えるの？

rails-assetsを使ってbower経由で入れることも出来ますし、npmでもインストールできるものもあります。
npmにあるものはrails-assetsを経由すると無駄に一手間かけてる感じになるので、npmから入れてもいいと思います。

# まとめ

以上3パターンについて、reactをrailsで使う場合にどういう構成にしたらいいのか、具体的になにを使うのか、できることはなにか..etcをまとめてみました。
また実践で使って学びがあれば追記します。
勉強中ですので駄目だし、フィードバック、コメントも大歓迎です。