既存のRailsプロジェクトにReactとwebpackerを導入した時の手順をメモします。
(まだ本番運用はしてません)
環境
- ruby 2.4.2
- Rails 4.2.8
- Mac OS 10.12.6
- webpacker 3.0.2
必要なgemをインストール
Gemfile更新してbundle install
gem 'react-rails'
gem 'webpacker', '~> 3.0'
yarnが必要なのでインストールしておく。
$ brew install yarn
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 2 taps (homebrew/core, homebrew/php).
...中略
Error: Xcode alone is not sufficient on Sierra.
Install the Command Line Tools:
xcode-select --install
※xcodeまわりで怒られたら言われるがままにインストール。
$ xcode-select --install
xcode-select: note: install requested for command line developer tools
webpackerをインストール
railsのバージョンによってコマンドが異なるので注意。
bundle
bundle exec rails webpacker:install
# OR (on rails version < 5.0)
bundle exec rake webpacker:install
$ bundle exec rake webpacker:install
create config/webpacker.yml
Copying webpack core config and loaders
create config/webpack
create config/webpack/development.js
create config/webpack/environment.js
create config/webpack/production.js
...中略
├─ webpack-dev-middleware@1.12.2
├─ webpack-dev-server@2.9.5
├─ websocket-driver@0.7.0
├─ websocket-extensions@0.1.3
├─ yargs-parser@4.2.1
└─ yargs@6.6.0
warning No license field
✨ Done in 5.97s.
Webpacker successfully installed 🎉 🍰
さらにreact用にテンプレートをインストール。
$ bundle exec rake webpacker:install:react
Webpacker is installed 🎉 🍰
...中略
├─ ua-parser-js@0.7.17
└─ whatwg-fetch@2.0.3
warning No license field
✨ Done in 5.82s.
Webpacker now supports react.js 🎉
インストール成功
Reactをインストール
例のごとくコマンド叩く。
$ rails generate react:install
Expected string default value for '--helper'; got false (boolean)
Expected string default value for '--assets'; got false (boolean)
Expected string default value for '--decorator'; got true (boolean)
Expected string default value for '--decorator'; got true (boolean)
Expected string default value for '--jbuilder'; got true (boolean)
create app/javascript/components
create app/javascript/components/.gitkeep
warning package.json: No license field
warning No license field
warning "@rails/webpacker > postcss-cssnext@3.0.2" has unmet peer dependency "caniuse-lite@^1.0.30000697".
warning " > webpack-dev-server@2.9.7" has unmet peer dependency "webpack@^2.2.0 || ^3.0.0".
warning "webpack-dev-server > webpack-dev-middleware@1.12.2" has unmet peer dependency "webpack@^1.0.0 || ^2.0.0 || ^3.0.0".
warning No license field
append app/javascript/packs/application.js
create app/javascript/packs/server_rendering.js
サンプルつくってみる。
$ rails g react:component HelloWorld greeting:string
create app/javascript/components/HelloWorld.js
以下のようなjsファイルが生成されるので、
import React from "react"
import PropTypes from "prop-types"
class HelloWorld extends React.Component {
render () {
return (
<div>
<div>Greeting: {this.props.greeting}</div>
</div>
);
}
}
HelloWorld.propTypes = {
greeting: PropTypes.string
};
export default HelloWorld
viewから呼び出してみる。
まずはlayoutsでwebpackのファイルを読み込むようにして、
...
= javascript_pack_tag 'application'
...
ヘルパで呼び出す。
= react_component('HelloWorld', {greeting: 'Hello'})
/hoge/index
にアクセスすると、「Greeting: Hello」と表示された
css-modulesを使う
webpack使ってるし、せっかくなのでcss-modules使ってみる。
スタイル作成してimportする。
.hoge {
color: red;
}
import React from "react"
import PropTypes from "prop-types"
+ import Style from './HelloWorld.scss'
class HelloWorld extends React.Component {
render () {
return (
<div>
- <div>Greeting: {this.props.greeting}</div>
+ <div className={Style.hoge}>Greeting: {this.props.greeting}</div>
</div>
);
}
}
HelloWorld.propTypes = {
greeting: PropTypes.string
};
export default HelloWorld
layoutsにも追記忘れずに。
...
= stylesheet_pack_tag 'application'
...
css-modules使うためにloaderの設定方法を変更する。(css-loaderでmodules: true
にする。)
設定はdocsのとおりにした。
https://github.com/rails/webpacker/blob/master/docs/webpack.md#overriding-loader-options-in-webpack-3-for-css-modules-etc
※バージョンによって変わってくるので注意。以下はwebpacker 3.0.2の場合。
const { environment } = require('@rails/webpacker')
+ const merge = require('webpack-merge')
+
+ const myCssLoaderOptions = {
+ modules: true,
+ sourceMap: true,
+ localIdentName: '[name]__[local]___[hash:base64:5]'
+ }
+
+ const CSSLoader = environment.loaders.get('style').use.find(el => el.loader === 'css-loader')
+
+ CSSLoader.options = merge(CSSLoader.options, myCssLoaderOptions)
module.exports = environment
webpack-merge
が必要なのでnpmでインストールする。
$ npm install webpack-merge
bin/webpack
コマンドでビルドする。
$ bin/webpack
Hash: d9e1c05fb0115c67db9a
Version: webpack 3.10.0
Time: 4415ms
Asset Size Chunks Chunk Names
server_rendering-2fc6d35ea1f628531946.js 1.96 MB 0 [emitted] [big] server_rendering
application-e4edca0d11e9022b85f8.js 1.96 MB 1 [emitted] [big] application
hello_react-2fa08b964a0fbb7ea3bf.js 1.68 MB 2 [emitted] [big] hello_react
application-58ab649efbf1ea4787a749efd9c58636.css 419 bytes 1 [emitted] application
server_rendering-58ab649efbf1ea4787a749efd9c58636.css 419 bytes 0 [emitted] server_rendering
manifest.json 380 bytes [emitted]
[28] ./app/javascript/components ^\.\/.*$ 236 bytes {0} {1} [built]
[41] ./app/javascript/packs/application.js 730 bytes {1} [built]
[42] ./app/javascript/packs/hello_react.jsx 739 bytes {2} [built]
[43] ./app/javascript/packs/server_rendering.js 299 bytes {0} [built]
+ 44 hidden modules
Child extract-text-webpack-plugin node_modules/extract-text-webpack-plugin/dist node_modules/css-loader/index.js??ref--5-2!node_modules/postcss-loader/lib/index.js??ref--5-3!node_modules/resolve-url-loader/index.js!node_modules/sass-loader/lib/loader.js??ref--5-5!app/javascript/components/HelloWorld.scss:
2 modules
ビルドできた
/hoge/index
にアクセスすると、「Greeting: Hello」が赤文字で表示された
Macのローカルでの作業はいったんここまで。
次はCIでの設定とかまとめていこうかな