LoginSignup
34
32

More than 5 years have passed since last update.

RailsでReactを動かしてみる (browserify + watchify + reactify)

Last updated at Posted at 2015-05-11

react.jsをRails4.2.1で動かしてみたのでメモ。
今回作成したソースコードはysm001/rails-react-sampleに置いてあります。

使い方

npm install
bundle install
npm start

railsプロジェクトの作成

$ rails new rails_react
$ cd rails_react

package.json

npm initとかでpackage.json生成。

package.json
{
  "name": "rails-react",
  "license": "MIT",
  "engines": {
    "node": ">= 0.10"
  }
}

必要なmoduleのinstall

以下のコマンドを実行して必要なmoduleをinstallする。

npm install --save-dev browserify reactify watchify
npm install --save react react-router react-tap-event-plugin

browserify: クライアントでもrequireを使ってnode moduleの読み込みが可能にするmodule
reactify: jsxをjsに変換するmodule
watchify: ファイルの変更を検知してbrowserifyしなおしてくれるmodule

reactみたいなでっかいファイルを毎回browserifyするとめちゃくちゃ重いので、watchify使って差分だけbrowserifyする。

npm scripts

以下のscriptをpackage.jsonに追記。

package.json
  "scripts": {
    "bundle": "browserify -t reactify app/assets/javascripts/app.jsx > app/assets/javascripts/bundle.js",
    "watch-js": "watchify -t reactify app/assets/javascripts/app.jsx -o app/assets/javascripts/bundle.js -v",
    "start": "npm run watch-js & rails s"
  }

bundle: app.jsxをbrowserifyしてbundle.jsに吐く
watch-js: app.jsを監視して、変更点をbundle.jsに適用
start: ファイル監視 & railsサーバ起動

application.jsの変更

依存関係にあるファイルはrequireで読み込んでいくので、application.jsに書いてあるrequire_tree . は不要。

なので、app/assets/javascripts/application.jsから
//= require_tree .
を削除して
//= require bundle.js
を追加。

表示するページの作成

テスト用に適当にページを作ります。
app/assets/javascripts/app.jsx にアプリケーションのメインとなる処理を記述。
とりあえず、以下のような感じでRouterを使った処理を書いてみました。

app/assets/javascripts/app.jsx
(function() {
  var React = require('react');
  window.React = React; // Reactオブジェクトだけは外に出しておく

  var injectTapEventPlugin = require("react-tap-event-plugin");
  injectTapEventPlugin();

  var Router = require('react-router');
  var AppRoutes = require('./app-routes.jsx');

  $(function() {
    Router.run(AppRoutes, function (Handler) {
      React.render(<Handler/>, document.body);
    });
  });
}) ();

Routerも適当になんか書いておく。

app/assets/javascripts/app-routes.jsx
var React = require('react');
var Router = require('react-router');
var DefaultRoute = Router.DefaultRoute;
var Route = Router.Route;
var RouteHandler = Router.RouteHandler;

var Root = React.createClass({
  render: function() {
    return (
        <div>
          <p>header</p>
          <RouteHandler/>
          <p>footer</p>
        </div>
    );
  }
});

var PathA = React.createClass({
  render: function() { return <p>path A</p>; }
});

var PathB = React.createClass({
  render: function() { return <p>path B</p>; }
});


var AppRoutes = (
  <Route name="app" path="/" handler={Root}>
    <DefaultRoute handler={PathA}/>
    <Route name="path-a" path="/path-a" handler={PathA} />
    <Route name="path-b" path="/path-b" handler={PathB} />
  </Route>
);

module.exports = AppRoutes;

表示用にコントローラを用意。react#indexで何か表示してみることにします。

bundle exec rails g controller react index

実行

npm start

した後、http://localhost:3000/react/indexにアクセスすると

header
path a
footer

と表示されているかと思います。
http://localhost:3000/react/index#/path-bにアクセスするとpath aがpath bに書き変わり、正常に動作していることが確認できます。

また、app.jsxapp-routes.jsxを編集すると、ファイルの更新が自動でbundle.jsに反映されて、リロードした際に変更点が反映されているのが確認できるかと思います。

参考文献

34
32
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
32