Webpack で React を導入した Rails アプリケーションを Heroku で動かすまでの手順
- 環境
- Rails : 5.0.1
- node : 6.10.0
React, Webpack, Babel の導入
- Rails のルートフォルダ直下に client/ ディレクトリを用意
- client/ ディレクトリ配下に package.json を作成
- React のパッケージをインストール
- Webpack, Babel のパッケージをインストールする
$ mkdir client
$ cd client
$ npm init -y
$ npm install --save react react-dom
$ npm install --save-dev webpack babel-core babel-loader babel-preset-es2015 babel-preset-react
- Webpack の confing を用意
- ビルド対象のファイルや成果物の出力先などを指定
client/webpack.config.js
module.exports = {
entry: { app: './src/index.js' },
output: {
path: '../app/assets/javascripts/webpack',
filename: 'app.js',
},
module: {
loaders: [
{
test: /\.(js|jsx)$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react'],
},
}
]
},
}
- package.json にビルドコマンドを指定
- webpack を使用したビルドができるようにする
client/package.json
...
"scripts": {
"watch": "webpack -w",
"build": "webpack -p",
"test": "echo \"Error: no test specified\" && exit 1"
},
...
Rails の config に precompile の設定を追加
- assets のコンパイル対象に JS を含める
config/initializers/assets.rb
Rails.application.config.assets.precompile += %w( *.js )
React component の作成
client/src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
class Greet extends React.Component {
propTypes () {
return {
name: React.PropTypes.string.isRequired,
};
}
render () {
return (
<div>
Hello, {this.props.name}
</div>
);
}
}
ReactDOM.render(
<Greet name={name} />,
document.getElementById('react_test')
);
作成した component を使用した view の作成
- controller から受け取ったデータを script タグでグローバル変数に格納しておく
- componet の props として渡せるように
app/views/sample/index.html.erb
<h1>React Sample</h1>
<script>
var name = <%= @name %> <% # @name は controller から受け取った文字列 %>
</script>
<div id="react_test"></div>
<%= javascript_include_tag "webpack/app" %>
ローカル環境での起動
- ここまで設定すると下記コマンドで表示を確認することができる
$ cd client/
$ npm run build
$ cd ../
$ rails s
Heroku で動かすための準備
- Rails のルートフォルダ直下に package.json を用意する
- Heroku で node や npm をインストールするためには package.json がルートディレクトリの直下にないといけない(らしい)
$ npm init -y
- Heroku 上では npm コマンドを使用した webpack のビルドができないので precompile 前に自動で実行するように rake task を用意する
lib/tasks/before_precompile.rake
task :build_frontend do
cd "client" do
sh "npm install"
sh "npm run build"
end
end
Rake::Task["assets:precompile"].enhance(%i(build_frontend))