2016年当時それなりに苦労してRails4.xにReact.jsを導入しましたが、記録に残し忘れていたので、今さらながらブログに書いてみようかと思います。
構成
React.jsを導入するだけならGemからインストールするのが楽なのですが、後日様々なNodeパッケージを導入する可能性を考えて、全てpackage.jsonで管理することにしました。
一方でアセットの配信は既存の仕組みに乗っかりたかったので、assetの配信はSprocketsにお任せすることに。
Node
Rubyはrbenvでインストールしていたので、Nodeもndenvを使うことにしました。
Webpack + Babel
ReactのコンポーネントはES6で書きたくなるので、Webpack + Babelでトランスパイルしています。
react_component というViewHelperが便利なので、これを使うためだけにインストールしています。
app/frontend を新たに作成し、ここにReactコンポーネントのソースを格納しています。
├── app
│ ├── assets
│ │ ├── images
│ │ ├── javascripts
│ │ └── stylesheets
│ ├── frontend
│ │ ├── src
│ │ └── test
├── config
│ └── webpack
│ ├── development.js
│ └── production.js
├── package.json
設定
主な設定を書いておきます。2年前なので若干古いかもしれません。。
.babelrc
{
"presets": ["env", "react"],
"env": {
"development": {
"plugins": [
"react-hot-loader/babel"
]
}
}
}
{
"version": "1.0.0",
"scripts": {
"start": "webpack --config config/webpack/development.js --hot",
"release": "webpack --config config/webpack/production.js",
"test": "npm run mocha",
"bundle-size-analyzer": "webpack --config config/webpack/production.js --json | webpack-bundle-size-analyzer",
"mocha": "NODE_ENV=test mocha --compilers js:babel-register --require app/frontend/test/setup.js app/frontend/test/**/*.spec.js"
}
}
config/webpack/development.js
const webpack = require('webpack');
module.exports = {
entry: [
'./app/frontend/src/components.js'
],
output: {
path: './app/assets/javascripts/build',
filename: 'components.js'
},
watch: true,
module: {
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/,
loaders: ["babel-loader"]
}]
},
resolve: {
extensions: ['', '.js', '.jsx']
}
}
開発
開発に必要な準備は(nodeのインストールを除けば) npm install && npm start するだけです。
エントリーポイントになっている component.js でrequireしておき、
window.React = require('react');
window.ReactDOM = require('react-dom');
window.PropTypes = require('prop-types');
window.MyApp = Object.assign(
{
MyAwesomeComponent: require('./components/MyAwesomeComponent').default
}
);
Railsのviewでreact_componentを呼び出します。
react_component('MyApp.MyAwesomeComponent', {})
デプロイ
capistranoに下記タスクを追加することで、deploy:compile_assets の前に webpack --config config/webpack/production.js が走ります。
namespace :webpack do
desc "Release build"
task :build_release do
on roles(fetch(:ndenv_roles, :all)) do
within release_path do
execute :npm, 'run', 'release'
end
end
end
before 'deploy:compile_assets', 'webpack:build_release'
end
結果、app/assets/jabascripts/build/components.js にファイルが出力されるので、あとはアセットパイプラインのお仕事です。
まとめ
書き殴りになってしまいましたが、RailsなプロジェクトでReact.jsを利用している事例を書いてみました。
2018年に何をいまさら感はありますが、自分の備忘録として。