ã¯ããã«
ããã«ã¡ã¯ãæ稿éçºé¨ã¨ã³ã¸ãã¢ã®è³è³ã§ãã
æ¢åã®Railsããã¸ã§ã¯ãã®ä¸ã§React.jsãå©ç¨ããæ©ä¼ããã£ãã®ã§ããã®æã«ãã£ããã¨ã«ã¤ãã¦ã¾ã¨ãã¦ã¿ã¾ãã
ç§èªèº«ã¯æ®æ®µRailsã®ãµã¼ããµã¤ãã¨CoffeeScriptãä¸å¿ã§ãæè¿ã®JavaScriptéçºç°å¢ã«ã¤ãã¦ãã¾ããã£ããã¢ããã§ãã¦ããªãã£ãã®ã§ããããããã®ç¶æ³ãææ¡ãã¤ã¤è©¦è¡é¯èª¤ã§éçºãã¦ãã£ãçµé¨ãããã§ããã ããReactæ¡ç¨ãã¦ã¿ãããã©JavaScriptçéããããããªãç®ç·ãã§æ¸ãã¦ã¿ããã¨æãã¾ãã
Railsã§React.jsã使ãããã¤ãã®æ¹æ³
2016å¹´æç¹ã§ãRailsã§React.jsã使ãæ¹æ³ã¯ããã¤ããã£ã¦ãã©ããæ¡ç¨ãããã§æ©ã¿ã¾ããã
- vendor/assets/javascripts ã«react.jsãç½®ãã¦å©ç¨ãã
- react-rails gem ãå©ç¨ãã
- browserify-rails 㧠npm管çãã¦å©ç¨ãã
- railsããã¸ã§ã¯ãå ã«ãJavaScriptéçºç¨ã®ãã£ã¬ã¯ããªãç¨æã㦠webpack + babel-loader ã§å©ç¨ãã
調æ»ããã¨ãããã ããããããªãã¿ã¼ã³ãããã¨æã£ã¦ãã¦ãä¸ã«è¡ãã»ã©RailsãããJavaScriptéçºã®ç¥èãå¿ è¦ã«ãªã£ã¦ããã¤ã¡ã¼ã¸ã§ããã
æçµçã«ã¯webpackãé¸æããã®ã§ããããããã軽ãæ¯ãã¦ããã¨
vendor/assets ã«ã©ã¤ãã©ãªãç½®ã
Railsã§å¤é¨JSãã¡ã¤ã«ãå©ç¨ããå ´åãvendor/assets
ã«ãã¦ã³ãã¼ããããã¡ã¤ã«ãç½®ã㦠Sprocketsã®ãããã§ã¹ããã¡ã¤ã«ã§èªã¿è¾¼ãã§å©ç¨ããã®ãï¼çªæ軽ã ã¨æãã¾ãã
æ軽ã ã¨ã¯æãã¾ãããReactã使ãã¯ãããã¨ä»ã®npmã¢ã¸ã¥ã¼ã«ãã©ãã©ã使ããããªã£ã¦ãã¦ãããããå
¨é¨ vendor/assets
ã«å
¥ã㦠sprockets ã§èªã¿è¾¼ã¿é ãèããªããéçºãã¦ããã®ã¯ãããç°¡åãªReactã¢ããªã±ã¼ã·ã§ã³ã§ãããè¾ããªãå°è±¡ã§ããããã£ã¨è¯ãç°å¢ãä½ã£ãæ¹ãæçµçã«æ¥½ã«ãªãã¨æãã¾ãã
react-rails
https://github.com/reactjs/react-rails
ãã®åã®éããRailsã§Reactãå©ç¨ããããã®Gemã§ãã
Bundler㧠react-rails
ãã¤ã³ã¹ãã¼ã«ããã ãã§ãããå©ç¨ã§ãããããªãè³ç«ã¦ããã¦ããã¾ãã
React.jsã®ãã¡ã¤ã«ãå梱ããã¦ããã®ã¯ãã¡ãããRubyã§è¨å®ãæ¸ããããReactã³ã³ãã¼ãã³ãã®ã¬ã³ããªã³ã°ãã«ãã¼ãç¨æããã¦ããããcoffeescriptã§ães2015ã§ãJSXã§ãæ¸ãããªã©ãJavaScriptãããRailsãRubyã«æ £ãã¦ããå ´åãããªãã¨ã£ã¤ããããã§ãã
React以å¤ã®npmã©ã¤ãã©ãªã¯èªåã§ãªãã¨ãããå¿ è¦ãããã¾ãã
browserify-rails
https://github.com/browserify-rails/browserify-rails
Reactç¨ã¨ããããã§ã¯ããã¾ããããbrowserifyã¨ããJSãã«ããã¼ã«ãRailsã®Sprocketsã§å©ç¨ã§ãã browserify-rails ã¯ãJSã¢ã¸ã¥ã¼ã«ãnpmã§ç®¡çã§ãã¦ãbaberifyãéãã°ães2015ãJSXã®å¤æãã§ãã¾ãã
react-railsã®ãã«ãã¼é¢é£ãå¿ è¦ãªããã°ãbrowserify-rails ã®npmã§ç®¡çããreactãå©ç¨ããã®ãæã ã¨æãã¾ãã
ãã ãéçºæã®ãã«ããçµæ§é ãã¦è¾ããªã£ã¦ããã®ã¨ãæ¢åããã¸ã§ã¯ãåºæã®ã³ã¼ãã¨ç¸æ§ããããªãã£ãããæ¡ç¨ã¯è¦åããã¾ããã
browserify-railsã«é¢ãã¦ã¯ãå¼ç¤¾å¤æã® http://techlife.cookpad.com/entry/2015/12/14/130041 ã®è¨äºã詳ããã§ãã
webpack
webpackã¯ä¾åé¢ä¿ã®ããåå²ãããJSãã¯ã©ã¤ã¢ã³ããµã¤ãã®ã¢ã»ãã群ããããæãã«ã¾ã¨ãã¦ããããã«ããã¼ã«ã§ãã
webpackã«ã¯Loaderã¨ããä»çµã¿ããããã½ã¼ã¹ã³ã¼ãã«é©ç¨ããå¦çãæè»ã«è¨å®ã§ããã®ã§ãããbabel-loaderã使ããã¨ã§es2015ãJSXã§è¨è¿°ããJSãã¡ã¤ã«ãå¤æãããã¨ãã§ãã¾ãã
Reactã«é¢ããã¢ã¸ã¥ã¼ã«ãã³ããªã³ã°ï¼è¤æ°ãã¡ã¤ã«ã®çµåï¼ãã½ã¼ã¹ã³ã¼ãã®å¤æããã«ãããã³ã¼ãã®é ç½®ã¾ã§ã¯webpackã§è¡ãããã¡ã¤ã«ã¸ã®ãã£ã³ã¬ã¼ããªã³ãä»ä¸ãªã©ã¯ããã¾ã§éãSprocketsã«ä»»ãã¾ãã
ãã®ããæ¹ã®å ´åãRailséçºè ãããç¨åº¦webpackç°å¢ã«ã¤ãã¦ç解ããå¿ è¦ããããè¥å¹²ã³ã¹ããé«ããããªæ°ãããã®ã§ãããä»åJavaScriptã®ã³ã¼ãã触ã人éãéããã¦ããã®ã¨ãJSã触ããªãéçºè ã¯ããç¨åº¦æ°ã«ããªãã§ãRailsã®éçºã¯ã§ãããããªç¶æ ã«ãã¦ããã¾ããã
ã¾ããç§èªèº«ãReactães2015ãªã©ãã¯ããã¦ä½¿ã£ããã¨ããããåé¡ããã£ãæã«åãåããç°¡åã§ãããã¨ãéè¦ã ã£ãã®ã¨ãéçºä¸ã®ãã«ããéãã¨ãããã¨ã決ãæã¨ãªãæ¡ç¨ãã¾ããã
webpackå©ç¨æã®æ§æ
ãã£ã¬ã¯ããªã®æ§æã¯ã以ä¸ã®ãããªæãã§
ããã¸ã§ã¯ãã«ã¼ãã® client
ã webpackç°å¢ã¨ãªã£ã¦ãã¾ãã
âââ Gemfile âââ Gemfile.lock âââ README.md âââ Rakefile âââ app âââ bin âââ client âââ config âââ config.ru âââ db âââ lib âââ log âââ public âââ test âââ tmp âââ vendor
webpackç°å¢ã®ãã£ã¬ã¯ããªã¯
client âââ src âââ node_modules âââ package.json âââ webpack.config.js
ãã®ãããªæ§æã«ãªãã¾ãã
client
ã® æ§æã¯ä¸è¬çãªwebpackã«ããreactéçºã¨ã»ã¨ãã©å¤ãããªãã®ã§ããã
ãã«ãæã«ãã¡ã¤ã«ãé
ç½®ããå ´æã« ../app/assets/javascripts/webpack
ãæå®ãã¦ãã¾ãã
client/node_modules
㨠../app/assets/javascripts/webpack
ã¯ãã¼ã¸ã§ã³ç®¡ç対象å¤ã¨ãããã®ã§ .gitignore
ã«è¿½å ãã¦ããã¾ãã
# .gitignore /client/node_modules /app/assets/javascripts/webpack
webpack + babelã®è¨å®
webpackç°å¢ã®æºåããã¾ãã å¿ è¦ãªä½æ¥ã¯ä»¥ä¸ã®æ§ãªæãã§ãã
- package.json ãä½ããnpmã§ã©ã¤ãã©ãªãã¤ã³ã¹ãã¼ã«ãã
- webpack.config.js ã§ãã«ãè¨å®ãæ¸ã
- foreman 㧠webpack buildããã»ã¹ãèµ·åãã
1. package.json ãä½ããnpmã§ã©ã¤ãã©ãªãã¤ã³ã¹ãã¼ã«ãã
client
ãã£ã¬ã¯ããªã§
$ npm init -y
ãå®è¡ãã¦ãpackage.json ãçæãã¾ããå ¬éãããã¨ã¯ãªãã®ã§ãprivateãã«ãã¦ããã¾ãã
{ "private": true, "scripts": { "test": "echo \"Error: no test specified\" && exit 1" } }
次㫠webpack 㨠babelé¢é£ã®ã©ã¤ãã©ãªãã¤ã³ã¹ãã¼ã«ãã¾ãã
npm install -D
㯠éçºæã«ã®ã¿å¿
è¦ãªã©ã¤ãã©ãªãã¤ã³ã¹ãã¼ã«ãã¤ã¤ãpackpage.jsonã«ä¾åé¢ä¿ãè¨è¿°ãã¦ããããªãã·ã§ã³ã§ãã
$ npm install -D webpack babel-loader babel-preset-es2015 babel-preset-react
ãbabel-xxxxxxããå¤ãã¦æ··ä¹±ããã®ã§ããã babel-loader ã¯webpackããbabelã使ã£ã¦ãã©ã³ã¹ãã¤ã«ããããã®ããã±ã¼ã¸ã babel-preset-xxxxx ã¯ães2015ãJSXãå¤æããããã®ããªã»ãããbabelæ¬ä½ã¨åé¢ãã¦ããã®ã§ åå¥ã«ã¤ã³ã¹ãã¼ã«ããå¿ è¦ãããã¾ãã
ãªãã¨ãªãBabelãã¤ã³ã¹ãã¼ã«ããã°ããæãã«å ¨é¨ãã£ã¦ããããã§ããï¼ã¨æã£ã¦ããã®ã§ããããã§ã¯ããã¾ããã§ããã
ããã¦ããããã react ãã¤ã³ã¹ãã¼ã«ãã¾ãã
-S
ãªãã·ã§ã³ã¯ãã¢ããªã±ã¼ã·ã§ã³ã«å¿
è¦ãªã©ã¤ãã©ãªããpackpage.jsonã«è¿½å ãã¤ã¤ã¤ã³ã¹ãã¼ã«ããã¾ãã
$ npm install -S react react-dom
2. webpack.config.js ã§ãã«ãè¨å®ãæ¸ã
次㫠webpackã®ãã«ãè¨å®ãæ¸ãã¦ããã¾ãã ããã§ã¯æå°éãããããã¨ã®
- ã½ã¼ã¹ã³ã¼ãã®ã¨ã³ããªãã¡ã¤ã«ãæå®ãã
- åºåå ã®ã«ã¼ã«ãè¨å®ãã
- åºåããéã«ãBabelã«ãããã©ã³ã¹ãã¤ã«ãè¨å®ãã
ããè¨è¿°ãã¦ããã¾ã
// webpack.config.js module.exports = { entry: { app: './src/index.js', }, output: { path: '../app/assets/javascripts/webpack', filename: '[name].js', }, module: { loaders: [ { test: /\.(js|jsx)$/, loader: "babel", exclude: /node_modules/, query: { presets: ["es2015", "react"], } }, ] }, }
ãã㧠client/src/index.js
ãããç¶æ
ã§
$ ./node_modules/.bin/webpack -w
ãå®è¡ããã°ããã¡ã¤ã«ã®å¤æ´ãç£è¦ã㦠Railsã® app/assets/javascripts/webpack/app.js
ã«ãã«ãçµæãé
ç½®ãããããã«ãªãã¾ãã
ããã« packpage.jsonã« npm scripts ã«éçºãã«ãã¨æ¬çªãã«ãã®ã³ãã³ããç¨æãã¦ããã¨ãforemanãcapistranoããå®è¡ããã¨ãã«ä¾¿å©ã§ãã
{ "private": true, "scripts": { "webpack-watch": "webpack -w", "webpack-build": "webpack -p" }, "devDependencies": { "babel-loader": "^6.2.4", "babel-preset-es2015": "^6.9.0", "babel-preset-react": "^6.11.1", "webpack": "^1.13.1" }, "dependencies": { "react": "^15.2.1", "react-dom": "^15.2.1" } }
3. foreman 㧠webpack buildããã»ã¹ãèµ·åãã
ãã®ã¾ã¾ã§ã¯ãRailséçºè
ãããããJSãã«ãç¨ã®å¥ããã»ã¹ãèµ·åãã¦ãããªããã°ãªããªãã®ã§
foreman start
㧠railsã¨webpackã®ããã»ã¹ãèµ·åããããã«ãã¾ãã
# Procfile rails: bundle exec rails server webpack: npm --prefix client run webpack-watch
ãã®ä»
ä»åã¯æä½éã®è¨å®ã®ã¿ãµãã¾ããããwebpackã®è¨å®ã§ ã¢ããªã±ã¼ã·ã§ã³ã³ã¼ã㨠react ãªã©ã®ãã³ãã¼ã³ã¼ããåã㦠ãã¾ãå¤æ´ã®ãªããã³ãã¼ã©ã¤ãã©ãªããã£ãã·ã¥ããããããã
è¤æ°ã®ã¢ããªã±ã¼ã·ã§ã³ã³ã¼ãã«åå²ãã¦ãããã¨ãã§ãã¾ãã
https://webpack.github.io/docs/code-splitting.html#split-app-and-vendor-code https://webpack.github.io/docs/code-splitting.html#multiple-entry-chunks
æå¾ã«
ä»å㯠Railsã§Reactãå©ç¨ããéã«ãreact-railsãbrowserify-railsãå©ç¨ããªãã¢ããã¼ãã«ã¤ãã¦æ¸ãã¦ã¿ã¾ããã 誤解ã®ãªãããã«ãä¼ããã¦ããã¨ãå¼ç¤¾ã®ãã¹ã¦ã®ããã¸ã§ã¯ãã§ãã®ã¢ããã¼ããæ¡ç¨ãã¦ããããã§ã¯ãªãã react-railsãbrowserify-railsã使ã£ã¦ããããã¸ã§ã¯ããããã¾ãã
åã ã®ãã¼ã ã«ãã£ãæ¹æ³ãæ¤è¨ããåèã«ãªãã°å¹¸ãã§ãã
ã¯ãã¯ãããã§ã¯ ã¨ã³ã¸ãã¢ãç©æ¥µæ¡ç¨ä¸ã§ãã https://recruit.cookpad.com/
ä»åã®ãµã³ãã«ããã¡ãã«ããã¦ããã¾ã https://github.com/func09/react-on-rails-sample