From a1fe599afcf1b134232a09d3a27a993b73d0f479 Mon Sep 17 00:00:00 2001 From: Marcus Molchany Date: Thu, 5 Jan 2017 23:00:33 -0800 Subject: [PATCH 01/42] Update README.md (#667) * Update README.md Update the path to the `assets.rake` file in the documentation for building bundles for Heroku deploys. Add Justin's feedback to the README --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4fc912d8b..a299315e8 100644 --- a/README.md +++ b/README.md @@ -201,7 +201,9 @@ In the following screenshot you can see the 3 parts of React on Rails rendering: ### Building the Bundles Each time you change your client code, you will need to re-generate the bundles (the webpack-created JavaScript files included in application.js). The included Foreman `Procfile.dev` will take care of this for you by watching your JavaScript code files for changes. Simply run `foreman start -f Procfile.dev`. -On Heroku deploys, the `lib/assets.rake` file takes care of running webpack during deployment. If you have used the provided generator, these bundles will automatically be added to your `.gitignore` in order to prevent extraneous noise from re-generated code in your pull requests. You will want to do this manually if you do not use the provided generator. +On production deployments that use asset precompilation, such as Heroku deployments, React on Rails, by default, will automatically run webpack to build your JavaScript bundles. You can see the source code for what gets added to your precompilation [here](https://github.com/shakacode/react_on_rails/tree/master/lib/tasks/assets.rake). For more information on this topic, see [the doc on Heroku deployment](https://github.com/shakacode/react_on_rails/tree/master/docs/additional-reading/heroku-deployment.md#more-details-on-precompilation-using-webpack-to-create-javascript-assets). + +If you have used the provided generator, these bundles will automatically be added to your `.gitignore` to prevent extraneous noise from re-generated code in your pull requests. You will want to do this manually if you do not use the provided generator. ### Rails Context When you use a "generator function" to create react components or you used shared redux stores, you get 2 params passed to your function: From ccadec010ce6883a910aac16f79c1447a7ec80d1 Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Thu, 5 Jan 2017 23:31:09 -1000 Subject: [PATCH 02/42] Fixed redux generator --- CHANGELOG.md | 7 ++++- .../react_on_rails/base_generator.rb | 1 - .../react_no_redux_generator.rb | 6 ++++ .../react_with_redux_generator.rb | 3 +- .../HelloWorld/components/HelloWorld.jsx | 28 +++++++++++++++++++ ...HelloWorldApp.jsx.tt => HelloWorldApp.jsx} | 1 - 6 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/components/HelloWorld.jsx rename lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/startup/{HelloWorldApp.jsx.tt => HelloWorldApp.jsx} (94%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6dfee1c5a..be4832f7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ Contributors: please follow the recommendations outlined at [keepachangelog.com] ## [Unreleased] *Please add entries here for your pull requests.* +## [6.3.5] - 2016-1-6 +### Fixed +- The redux generator now creates a HelloWorld component that uses redux rather than local state. [#669](https://github.com/shakacode/react_on_rails/issues/669) by [justin808](https://github.com/justin808). + ## [6.3.4] - 2016-12-25 ##### Fixed - Disable Turbolinks support when not supported. [#650](https://github.com/shakacode/react_on_rails/pull/650) by [ka2n](https://github.com/ka2n). @@ -413,7 +417,8 @@ Best done with Object destructing: ##### Fixed - Fix several generator related issues. -[Unreleased]: https://github.com/shakacode/react_on_rails/compare/6.3.4...master +[Unreleased]: https://github.com/shakacode/react_on_rails/compare/6.3.5...master +[6.3.5]: https://github.com/shakacode/react_on_rails/compare/6.3.4...6.3.5 [6.3.4]: https://github.com/shakacode/react_on_rails/compare/6.3.3...6.3.4 [6.3.3]: https://github.com/shakacode/react_on_rails/compare/6.3.2...6.3.3 [6.3.2]: https://github.com/shakacode/react_on_rails/compare/6.3.1...6.3.2 diff --git a/lib/generators/react_on_rails/base_generator.rb b/lib/generators/react_on_rails/base_generator.rb index cccd79e8c..0e3535d79 100644 --- a/lib/generators/react_on_rails/base_generator.rb +++ b/lib/generators/react_on_rails/base_generator.rb @@ -65,7 +65,6 @@ def create_react_directories def copy_base_files base_path = "base/base/" base_files = %w(app/controllers/hello_world_controller.rb - client/app/bundles/HelloWorld/components/HelloWorld.jsx client/.babelrc client/webpack.config.js client/REACT_ON_RAILS_CLIENT_README.md) diff --git a/lib/generators/react_on_rails/react_no_redux_generator.rb b/lib/generators/react_on_rails/react_no_redux_generator.rb index 1cbb5845c..23e3ed9af 100644 --- a/lib/generators/react_on_rails/react_no_redux_generator.rb +++ b/lib/generators/react_on_rails/react_no_redux_generator.rb @@ -8,6 +8,12 @@ class ReactNoReduxGenerator < Rails::Generators::Base Rails::Generators.hide_namespace(namespace) source_root(File.expand_path("../templates", __FILE__)) + def copy_base_files + base_path = "base/base/" + base_files = %w(client/app/bundles/HelloWorld/components/HelloWorld.jsx) + base_files.each { |file| copy_file("#{base_path}#{file}", file) } + end + def create_appropriate_templates base_path = "base/base/" location = "client/app/bundles/HelloWorld/" diff --git a/lib/generators/react_on_rails/react_with_redux_generator.rb b/lib/generators/react_on_rails/react_with_redux_generator.rb index a1376f84f..f17b8c2bb 100644 --- a/lib/generators/react_on_rails/react_with_redux_generator.rb +++ b/lib/generators/react_on_rails/react_with_redux_generator.rb @@ -13,7 +13,8 @@ def create_redux_directories def copy_base_redux_files base_path = "redux/base/" - %w(client/app/bundles/HelloWorld/actions/helloWorldActionCreators.jsx + %w(client/app/bundles/HelloWorld/components/HelloWorld.jsx + client/app/bundles/HelloWorld/actions/helloWorldActionCreators.jsx client/app/bundles/HelloWorld/containers/HelloWorldContainer.jsx client/app/bundles/HelloWorld/constants/helloWorldConstants.jsx client/app/bundles/HelloWorld/reducers/helloWorldReducer.jsx diff --git a/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/components/HelloWorld.jsx b/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/components/HelloWorld.jsx new file mode 100644 index 000000000..a6a711051 --- /dev/null +++ b/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/components/HelloWorld.jsx @@ -0,0 +1,28 @@ +import React, { PropTypes } from 'react'; + +const HelloWorld = ({ name, updateName }) => ( +
+

+ Hello, {name}! +

+
+
+ + updateName(e.target.value)} + /> +
+
+); + +HelloWorld.propTypes = { + name: PropTypes.string.isRequired, + updateName: PropTypes.func.isRequired, +}; + +export default HelloWorld; diff --git a/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/startup/HelloWorldApp.jsx.tt b/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/startup/HelloWorldApp.jsx similarity index 94% rename from lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/startup/HelloWorldApp.jsx.tt rename to lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/startup/HelloWorldApp.jsx index 3d2622d53..3dd1cd3e4 100644 --- a/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/startup/HelloWorldApp.jsx.tt +++ b/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/startup/HelloWorldApp.jsx @@ -1,5 +1,4 @@ import React from 'react'; -import ReactOnRails from 'react-on-rails'; import { Provider } from 'react-redux'; import configureStore from '../store/helloWorldStore'; From 066133907f77a3cf6922dfd87c01638147b63bbe Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Fri, 6 Jan 2017 00:05:34 -1000 Subject: [PATCH 03/42] Update dependencies, both npm & gems --- .../base/base/client/package.json.tt | 34 +++++++++---------- .../templates/base/base/package.json.tt | 4 +-- package.json | 4 +-- spec/dummy/Gemfile.lock | 9 ++--- spec/dummy/client/package.json | 14 ++++---- 5 files changed, 33 insertions(+), 32 deletions(-) diff --git a/lib/generators/react_on_rails/templates/base/base/client/package.json.tt b/lib/generators/react_on_rails/templates/base/base/client/package.json.tt index 136626657..b785e9e58 100644 --- a/lib/generators/react_on_rails/templates/base/base/client/package.json.tt +++ b/lib/generators/react_on_rails/templates/base/base/client/package.json.tt @@ -4,8 +4,8 @@ "version": "0.0.1", "private": true, "engines": { - "node": "5.10.0", - "npm": "3.5.0" + "node": "6.9.0", + "npm": "4.1.1" }, "scripts": { "build:test": "webpack --config webpack.config.js", @@ -15,25 +15,25 @@ "cacheDirectories": ["node_modules", "client/node_modules"], "dependencies": { "babel": "^6.5.2", - "babel-cli": "^6.6.5", - "babel-core": "^6.7.4", - "babel-loader": "^6.2.4", - "babel-runtime": "^6.6.1", - "babel-polyfill": "^6.7.4", - "babel-preset-es2015": "^6.6.0", - "babel-preset-react": "^6.5.0", - "babel-preset-stage-0": "^6.5.0", - "es5-shim": "^4.5.7", + "babel-cli": "^6.18.0", + "babel-core": "^6.21.0", + "babel-loader": "^6.2.10", + "babel-runtime": "^6.20.0", + "babel-polyfill": "^6.20.0", + "babel-preset-es2015": "^6.18.0", + "babel-preset-react": "^6.16.0", + "babel-preset-stage-0": "^6.16.0", + "es5-shim": "^4.5.9", "expose-loader": "^0.7.1", - "imports-loader": "^0.6.5", - "react": "^15.0.0", - "react-dom": "^15.0.0", + "imports-loader": "^0.7.0", + "react": "^15.4.1", + "react-dom": "^15.4.1", "react-on-rails": "<%= VersionSyntaxConverter.new.rubygem_to_npm %>", <%- if options.redux? -%> - "react-redux": "^4.4.1", - "redux": "^3.3.1", + "react-redux": "^5.0.1", + "redux": "^3.6.0", <%- end -%> - "webpack": "^1.12.14" + "webpack": "^1.14.0" }, "devDependencies": { } diff --git a/lib/generators/react_on_rails/templates/base/base/package.json.tt b/lib/generators/react_on_rails/templates/base/base/package.json.tt index 19b9476bb..a43c3e7e5 100644 --- a/lib/generators/react_on_rails/templates/base/base/package.json.tt +++ b/lib/generators/react_on_rails/templates/base/base/package.json.tt @@ -3,8 +3,8 @@ "version": "0.0.1", "private": true, "engines": { - "node": "5.10.0", - "npm": "3.5.0" + "node": "6.9.0", + "npm": "4.1.1" }, "scripts": { "postinstall": "cd client && npm install", diff --git a/package.json b/package.json index 7e25fa789..d65d09b5e 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "eslint": "^3.12.2", "eslint-config-shakacode": "^13.2.1", "eslint-plugin-import": "^2.2.0", - "eslint-plugin-jsx-a11y": "^2.2.3", + "eslint-plugin-jsx-a11y": "^3.0.2", "eslint-plugin-react": "^6.8.0", "flow-bin": "^0.37.4", "jsdom": "^9.9.1", @@ -32,7 +32,7 @@ "react-dom": "^15.4.1", "react-transform-hmr": "^1.0.4", "redux": "^3.6.0", - "release-it": "^2.5.2", + "release-it": "^2.5.3", "tap-spec": "^4.1.1", "tape": "^4.6.3", "webpack": "^1.14.0" diff --git a/spec/dummy/Gemfile.lock b/spec/dummy/Gemfile.lock index fdab0f7e1..8dde83771 100644 --- a/spec/dummy/Gemfile.lock +++ b/spec/dummy/Gemfile.lock @@ -261,8 +261,9 @@ GEM thread_safe (0.3.5) tilt (2.0.5) tins (1.13.0) - turbolinks (2.5.3) - coffee-rails + turbolinks (5.0.1) + turbolinks-source (~> 5) + turbolinks-source (5.0.0) tzinfo (1.2.2) thread_safe (~> 0.1) uglifier (3.0.4) @@ -312,8 +313,8 @@ DEPENDENCIES selenium-webdriver spring sqlite3 - turbolinks (= 2.5.3) + turbolinks (~> 5.0) uglifier (>= 2.7.2) BUNDLED WITH - 1.13.6 + 1.13.7 diff --git a/spec/dummy/client/package.json b/spec/dummy/client/package.json index 963e752b8..289d9c581 100644 --- a/spec/dummy/client/package.json +++ b/spec/dummy/client/package.json @@ -8,7 +8,7 @@ }, "main": "js/app.js", "dependencies": { - "autoprefixer": "^6.6.0", + "autoprefixer": "^6.6.1", "babel": "^6.5.2", "babel-cli": "^6.18.0", "babel-core": "^6.21.0", @@ -28,7 +28,7 @@ "jquery": "^3.1.1", "jquery-ujs": "^1.2.2", "loader-utils": "^0.2.16", - "lodash": "^4.17.3", + "lodash": "^4.17.4", "node-libs-browser": "^2.0.0", "node-sass": "^4.1.1", "postcss-loader": "^1.2.1", @@ -41,7 +41,7 @@ "redux-thunk": "^2.1.0", "resolve-url-loader": "^1.6.1", "sass-loader": "^4.1.1", - "sass-resources-loader": "1.1.0", + "sass-resources-loader": "1.2.0-beta.1", "style-loader": "^0.13.1", "url-loader": "^0.5.7", "webpack": "^1.14.0" @@ -49,13 +49,13 @@ "devDependencies": { "babel-plugin-react-transform": "^2.0.2", "body-parser": "^1.15.2", - "eslint": "^3.8.1", + "eslint": "^3.12.2", "eslint-config-shakacode": "^13.2.1", "eslint-plugin-import": "^2.2.0", - "eslint-plugin-jsx-a11y": "^2.2.3", + "eslint-plugin-jsx-a11y": "^3.0.2", "eslint-plugin-react": "^6.8.0", - "fbjs": "^0.8.5", - "jsdom": "^9.8.0", + "fbjs": "^0.8.8", + "jsdom": "^9.9.1", "react-transform-hmr": "^1.0.4", "tape": "^4.6.3", "webpack-dev-server": "^1.16.2" From e59d25b205e853ad0ce224fb04d40df285492dbd Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Fri, 6 Jan 2017 10:47:42 -1000 Subject: [PATCH 04/42] Only use coveralls if env USE_COVERALLS==TRUE --- .travis.yml | 1 + Rakefile | 10 +++++++--- rakelib/run_rspec.rake | 9 +++++++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 96e8ef995..ab4d2b16e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,6 +25,7 @@ env: - DRIVER=selenium_chrome - CHROME_BIN=/usr/bin/google-chrome - ENABLE_TURBOLINKS_5=TRUE + - USE_COVERALLS=TRUE before_install: - sudo apt-get update diff --git a/Rakefile b/Rakefile index 9ec826951..6679e4bf8 100644 --- a/Rakefile +++ b/Rakefile @@ -1,10 +1,14 @@ # Rake will automatically load any *.rake files inside of the "rakelib" folder # See rakelib/ -require "coveralls/rake/task" -Coveralls::RakeTask.new +tasks = %w(run_rspec lint) +if ENV["USE_COVERALLS"] == "TRUE" + require "coveralls/rake/task" + Coveralls::RakeTask.new + tasks << "coveralls:push" +end desc "Run all tests and linting" -task default: ["run_rspec", "lint", "coveralls:push"] +task default: tasks desc "All actions but no examples. Good for local developer run." task all_but_examples: ["run_rspec:all_but_examples", "lint"] diff --git a/rakelib/run_rspec.rake b/rakelib/run_rspec.rake index 1a82b4634..9167cac56 100644 --- a/rakelib/run_rspec.rake +++ b/rakelib/run_rspec.rake @@ -1,4 +1,7 @@ -require "coveralls/rake/task" +if ENV["USE_COVERALLS"] == "TRUE" + require "coveralls/rake/task" +end + require "pathname" require_relative "task_helpers" @@ -54,7 +57,9 @@ namespace :run_rspec do sh %(COVERAGE=true rspec spec/empty_spec.rb) end - Coveralls::RakeTask.new + if ENV["USE_COVERALLS"] == "TRUE" + Coveralls::RakeTask.new + end desc "run all tests no examples" task all_but_examples: [:gem, :dummy, :dummy_no_turbolinks, :dummy_turbolinks_5, :empty, :js_tests] do From b5eca019e9b506e0eec1e35cfecbd1fb25ebf308 Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Fri, 6 Jan 2017 20:46:02 -1000 Subject: [PATCH 05/42] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a299315e8..cca383bac 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,16 @@ -[![Build Status](https://travis-ci.org/shakacode/react_on_rails.svg?branch=master)](https://travis-ci.org/shakacode/react_on_rails) [![Dependency Status](https://gemnasium.com/shakacode/react_on_rails.svg)](https://gemnasium.com/shakacode/react_on_rails) [![Gem Version](https://badge.fury.io/rb/react_on_rails.svg)](https://badge.fury.io/rb/react_on_rails) [![npm version](https://badge.fury.io/js/react-on-rails.svg)](https://badge.fury.io/js/react-on-rails) [![Code Climate](https://codeclimate.com/github/shakacode/react_on_rails/badges/gpa.svg)](https://codeclimate.com/github/shakacode/react_on_rails) [![Coverage Status](https://coveralls.io/repos/shakacode/react_on_rails/badge.svg?branch=master&service=github)](https://coveralls.io/github/shakacode/react_on_rails?branch=master) +[![Build Status](https://travis-ci.org/shakacode/react_on_rails.svg?branch=master)](https://travis-ci.org/shakacode/react_on_rails) [![Dependency Status](https://gemnasium.com/shakacode/react_on_rails.svg)](https://gemnasium.com/shakacode/react_on_rails) [![Gem Version](https://badge.fury.io/rb/react_on_rails.svg)](https://badge.fury.io/rb/react_on_rails) [![npm version](https://badge.fury.io/js/react-on-rails.svg)](https://badge.fury.io/js/react-on-rails) [![Code Climate](https://codeclimate.com/github/shakacode/react_on_rails/badges/gpa.svg)](https://codeclimate.com/github/shakacode/react_on_rails) [![Coverage Status](https://coveralls.io/repos/shakacode/react_on_rails/badge.svg?branch=master&service=github)](https://coveralls.io/github/shakacode/react_on_rails?branch=master)[![Codeship Status for shakacode/react_on_rails](https://app.codeship.com/projects/cec6c040-971f-0134-488f-0a5146246bd8/status?branch=master)](https://app.codeship.com/projects/187011) **For a complete example of this gem, see our live demo at [www.reactrails.com](http://www.reactrails.com). ([Source Code](https://github.com/shakacode/react-webpack-rails-tutorial))** -Aloha from Justin Gordon ([bio](http://www.railsonmaui.com/about)) and the [ShakaCode](http://www.shakacode.com) Team! We're actively looking for new projects involving React, React-Native, and Rails. Please contact me at [justin@shakacode.com](mailto:justin@shakacode.com) if we could potentially help you in any way. Besides consulting on bigger projects, [ShakaCode](http://www.shakacode.com) is doing ScreenHero plus Slack/Github based coaching for React on Rails. See our blog post [Can ShakaCode Help You?](https://blog.shakacode.com/can-shakacode-help-you-4a5b1e5a8a63#.jex6tg9w9) for more information. +Aloha from Justin Gordon ([bio](http://www.railsonmaui.com/about)) and the [ShakaCode](http://www.shakacode.com) Team! We're actively looking for new projects involving React, React-Native, and Rails. Please [contact me](mailto:justin@shakacode.com) if we could potentially help you in any way. Besides consulting on bigger projects, [ShakaCode](http://www.shakacode.com) is doing ScreenHero plus Slack/Github based coaching for React on Rails. See our blog post [Can ShakaCode Help You?](https://blog.shakacode.com/can-shakacode-help-you-4a5b1e5a8a63#.jex6tg9w9) for more information. -We're offering a free half-hour project consultation, on anything from React on Rails to any aspect of web application development for both consumer and enterprise products. In addition to React.js and Rails, we're doing React-Native iOS and Android apps! +I'm offering a free half-hour project consultation, on anything from React on Rails to any aspect of web application development for both consumer and enterprise products. In addition to React.js and Rails, we're doing React-Native iOS and Android apps! Whether you have a new project or need help on an existing project, feel free to contact me directly at [justin@shakacode.com](mailto:justin@shakacode.com) and thanks in advance for any referrals! Your support keeps this project going. -(Want to become a contributor? [Contact us](mailto:contact@shakacode.com) for an Slack team invite! Also, see ["easy" issues](https://github.com/shakacode/react_on_rails/labels/easy) and [issues for the full tutorial](https://github.com/shakacode/react-webpack-rails-tutorial/issues?q=is%3Aissue+is%3Aopen+label%3Aeasy).) +(Want to become a contributor? [Contact us](mailto:contact@shakacode.com) for a Slack team invite! Also, see ["easy" issues](https://github.com/shakacode/react_on_rails/labels/easy) and [issues for the full tutorial](https://github.com/shakacode/react-webpack-rails-tutorial/issues?q=is%3Aissue+is%3Aopen+label%3Aeasy Follow [@ShakaCode](https://twitter.com/shakacode) for notications of new releases. From f9294781d14282c74874370d1befb3f82fb5d3b9 Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Fri, 6 Jan 2017 20:48:27 -1000 Subject: [PATCH 06/42] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cca383bac..ad1111350 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://travis-ci.org/shakacode/react_on_rails.svg?branch=master)](https://travis-ci.org/shakacode/react_on_rails) [![Dependency Status](https://gemnasium.com/shakacode/react_on_rails.svg)](https://gemnasium.com/shakacode/react_on_rails) [![Gem Version](https://badge.fury.io/rb/react_on_rails.svg)](https://badge.fury.io/rb/react_on_rails) [![npm version](https://badge.fury.io/js/react-on-rails.svg)](https://badge.fury.io/js/react-on-rails) [![Code Climate](https://codeclimate.com/github/shakacode/react_on_rails/badges/gpa.svg)](https://codeclimate.com/github/shakacode/react_on_rails) [![Coverage Status](https://coveralls.io/repos/shakacode/react_on_rails/badge.svg?branch=master&service=github)](https://coveralls.io/github/shakacode/react_on_rails?branch=master)[![Codeship Status for shakacode/react_on_rails](https://app.codeship.com/projects/cec6c040-971f-0134-488f-0a5146246bd8/status?branch=master)](https://app.codeship.com/projects/187011) +[![Build Status](https://travis-ci.org/shakacode/react_on_rails.svg?branch=master)](https://travis-ci.org/shakacode/react_on_rails) [![Codeship Status for shakacode/react_on_rails](https://app.codeship.com/projects/cec6c040-971f-0134-488f-0a5146246bd8/status?branch=master)](https://app.codeship.com/projects/187011) [![Dependency Status](https://gemnasium.com/shakacode/react_on_rails.svg)](https://gemnasium.com/shakacode/react_on_rails) [![Gem Version](https://badge.fury.io/rb/react_on_rails.svg)](https://badge.fury.io/rb/react_on_rails) [![npm version](https://badge.fury.io/js/react-on-rails.svg)](https://badge.fury.io/js/react-on-rails) [![Code Climate](https://codeclimate.com/github/shakacode/react_on_rails/badges/gpa.svg)](https://codeclimate.com/github/shakacode/react_on_rails) [![Coverage Status](https://coveralls.io/repos/shakacode/react_on_rails/badge.svg?branch=master&service=github)](https://coveralls.io/github/shakacode/react_on_rails?branch=master) **For a complete example of this gem, see our live demo at [www.reactrails.com](http://www.reactrails.com). ([Source Code](https://github.com/shakacode/react-webpack-rails-tutorial))** From 8db37b1838107598723fa98fcd8c5c8eed30c2e3 Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Sat, 7 Jan 2017 21:42:44 -1000 Subject: [PATCH 07/42] Release 6.3.5 --- lib/react_on_rails/version.rb | 2 +- package.json | 2 +- spec/dummy/Gemfile.lock | 9 ++++----- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/react_on_rails/version.rb b/lib/react_on_rails/version.rb index 67a660a03..721aaa912 100644 --- a/lib/react_on_rails/version.rb +++ b/lib/react_on_rails/version.rb @@ -1,4 +1,4 @@ # frozen_string_literal: true module ReactOnRails - VERSION = "6.3.4".freeze + VERSION = "6.3.5".freeze end diff --git a/package.json b/package.json index d65d09b5e..313ab90d0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-on-rails", - "version": "6.3.4", + "version": "6.3.5", "description": "react-on-rails JavaScript for react_on_rails Ruby gem", "main": "node_package/lib/ReactOnRails.js", "directories": { diff --git a/spec/dummy/Gemfile.lock b/spec/dummy/Gemfile.lock index 8dde83771..6c1fe49e6 100644 --- a/spec/dummy/Gemfile.lock +++ b/spec/dummy/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: ../.. specs: - react_on_rails (6.3.4) + react_on_rails (6.3.5) addressable connection_pool execjs (~> 2.5) @@ -261,9 +261,8 @@ GEM thread_safe (0.3.5) tilt (2.0.5) tins (1.13.0) - turbolinks (5.0.1) - turbolinks-source (~> 5) - turbolinks-source (5.0.0) + turbolinks (2.5.3) + coffee-rails tzinfo (1.2.2) thread_safe (~> 0.1) uglifier (3.0.4) @@ -313,7 +312,7 @@ DEPENDENCIES selenium-webdriver spring sqlite3 - turbolinks (~> 5.0) + turbolinks (= 2.5.3) uglifier (>= 2.7.2) BUNDLED WITH From 554ffdd264aa15429e3859090e0508f13b807ddb Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Sun, 8 Jan 2017 20:33:01 -1000 Subject: [PATCH 08/42] Update CONTRIBUTING.md --- CONTRIBUTING.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7de15de6f..fa14b3ea2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -182,11 +182,11 @@ npm run test ```sh cd -node_package/scripts/ci +npm run check ``` ### Starting the Dummy App -To run the test app, it's **CRITICAL** to not just run `rails s`. You have to run `foreman start`. If you don't do this, then `webpack` will not generate a new bundle, and you will be seriously confused when you change JavaScript and the app does not change. If you change the webpack configs, then you need to restart foreman. If you change the JS code for react-on-rails, you need to run `node_package/scripts/build`. Since the react-on-rails package should be sym linked, you don't have to `npm i react-on-rails` after every change. +To run the test app, it's **CRITICAL** to not just run `rails s`. You have to run `foreman start`. If you don't do this, then `webpack` will not generate a new bundle, and you will be seriously confused when you change JavaScript and the app does not change. If you change the webpack configs, then you need to restart foreman. If you change the JS code for react-on-rails, you need to run `npm run build`. Since the react-on-rails package should be sym linked, you don't have to `npm i react-on-rails` after every change. ### RSpec Testing Run `rake` for testing the gem and `spec/dummy`. Otherwise, the `rspec` command only works for testing within the sample apps, like `spec/dummy`. @@ -217,7 +217,7 @@ The main installer can be run with ```rails generate react_on_rails:install``` The generators are covered by generator tests using Rails's generator testing helpers, but it never hurts to do a sanity check and explore the API. See [generator_testing_script.md](generator_testing_script.md) for a script on how to run the generator on a fresh project. ### Linting -All linting is performed from the docker container for CI. You will need docker and docker-compose installed locally to lint code changes via the lint container. You can lint locally by running `node_package/scripts/lint` +All linting is performed from the docker container for CI. You will need docker and docker-compose installed locally to lint code changes via the lint container. You can lint locally by running `npm run lint && npm run flow` * [Install Docker Toolbox for Mac](https://www.docker.com/toolbox) * [Install Docker Compose for Linux](https://docs.docker.com/compose/install/) From 070003612b97d43909f9d417f98f42e1854b9066 Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Sun, 8 Jan 2017 20:39:57 -1000 Subject: [PATCH 09/42] Update CONTRIBUTING.md --- CONTRIBUTING.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fa14b3ea2..9d86e01f3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -126,11 +126,11 @@ npm install -g phantomjs Note this *must* be installed globally for the dummy test project rspec runner to see it properly. -### NPM link -Because the example and dummy apps rely on the react-on-rails node package, they should link directly to your local version to pick up any changes you may have made to that package. To achieve this, switch to the app's root directory and run: +### Local Node Package +Because the example and dummy apps rely on the react-on-rails node package, they should link directly to your local version to pick up any changes you may have made to that package. To achieve this, switch to the teat app's root directory and run this command below which runs something like [this script](spec/dummy/package.json#L14) ```sh -npm run node_package +npm run install-react-on-rails ``` From now on, the example and dummy apps will use your local node_package folder as the react-on-rails node package. This will also be done automatically for you via the `rake examples:prepare_all` rake task. @@ -141,6 +141,7 @@ From now on, the example and dummy apps will use your local node_package folder resolve: { alias: { react: path.resolve('./node_modules/react'), + 'react-dom': path.resolve('./node_modules/react-dom'), }, }, ``` From b1f3582764e196e726c75874e36cd02e2814062b Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Sat, 7 Jan 2017 21:39:20 -1000 Subject: [PATCH 10/42] Update to Rails 4.2.5 --- Gemfile | 2 +- spec/dummy/Gemfile | 2 +- spec/dummy/Gemfile.lock | 60 ++++++++++++++++++++--------------------- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/Gemfile b/Gemfile index 2abddb785..6f82eb2c1 100644 --- a/Gemfile +++ b/Gemfile @@ -25,7 +25,7 @@ gem "mini_racer" if ENV["ENABLE_TURBOLINKS_5"].nil? || ENV["ENABLE_TURBOLINKS_5"].strip.empty? gem "turbolinks", "2.5.3" else - gem "turbolinks", "~> 5.0.0.beta" + gem "turbolinks", "~> 5.0" end gem "uglifier", ">= 2.7.2" gem "web-console", "~> 2.0", group: :development diff --git a/spec/dummy/Gemfile b/spec/dummy/Gemfile index b9984226d..bf9a8faa7 100644 --- a/spec/dummy/Gemfile +++ b/spec/dummy/Gemfile @@ -3,7 +3,7 @@ source 'https://rubygems.org' eval_gemfile File.expand_path("../../../react_on_rails.gemspec", __FILE__) # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem 'rails', '4.2.3' +gem 'rails', '4.2.5' # Use sqlite3 as the database for Active Record gem 'sqlite3' # Use SCSS for stylesheets diff --git a/spec/dummy/Gemfile.lock b/spec/dummy/Gemfile.lock index 8dde83771..e1216b7d5 100644 --- a/spec/dummy/Gemfile.lock +++ b/spec/dummy/Gemfile.lock @@ -12,36 +12,36 @@ PATH GEM remote: https://rubygems.org/ specs: - actionmailer (4.2.3) - actionpack (= 4.2.3) - actionview (= 4.2.3) - activejob (= 4.2.3) + actionmailer (4.2.5) + actionpack (= 4.2.5) + actionview (= 4.2.5) + activejob (= 4.2.5) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 1.0, >= 1.0.5) - actionpack (4.2.3) - actionview (= 4.2.3) - activesupport (= 4.2.3) + actionpack (4.2.5) + actionview (= 4.2.5) + activesupport (= 4.2.5) rack (~> 1.6) rack-test (~> 0.6.2) rails-dom-testing (~> 1.0, >= 1.0.5) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (4.2.3) - activesupport (= 4.2.3) + actionview (4.2.5) + activesupport (= 4.2.5) builder (~> 3.1) erubis (~> 2.7.0) rails-dom-testing (~> 1.0, >= 1.0.5) rails-html-sanitizer (~> 1.0, >= 1.0.2) - activejob (4.2.3) - activesupport (= 4.2.3) + activejob (4.2.5) + activesupport (= 4.2.5) globalid (>= 0.3.0) - activemodel (4.2.3) - activesupport (= 4.2.3) + activemodel (4.2.5) + activesupport (= 4.2.5) builder (~> 3.1) - activerecord (4.2.3) - activemodel (= 4.2.3) - activesupport (= 4.2.3) + activerecord (4.2.5) + activemodel (= 4.2.5) + activesupport (= 4.2.5) arel (~> 6.0) - activesupport (4.2.3) + activesupport (4.2.5) i18n (~> 0.7) json (~> 1.7, >= 1.7.7) minitest (~> 5.1) @@ -165,16 +165,16 @@ GEM rack (1.6.5) rack-test (0.6.3) rack (>= 1.0) - rails (4.2.3) - actionmailer (= 4.2.3) - actionpack (= 4.2.3) - actionview (= 4.2.3) - activejob (= 4.2.3) - activemodel (= 4.2.3) - activerecord (= 4.2.3) - activesupport (= 4.2.3) + rails (4.2.5) + actionmailer (= 4.2.5) + actionpack (= 4.2.5) + actionview (= 4.2.5) + activejob (= 4.2.5) + activemodel (= 4.2.5) + activerecord (= 4.2.5) + activesupport (= 4.2.5) bundler (>= 1.3.0, < 2.0) - railties (= 4.2.3) + railties (= 4.2.5) sprockets-rails rails-deprecated_sanitizer (1.0.3) activesupport (>= 4.2.0.alpha) @@ -184,9 +184,9 @@ GEM rails-deprecated_sanitizer (>= 1.0.1) rails-html-sanitizer (1.0.3) loofah (~> 2.0) - railties (4.2.3) - actionpack (= 4.2.3) - activesupport (= 4.2.3) + railties (4.2.5) + actionpack (= 4.2.5) + activesupport (= 4.2.5) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) rainbow (2.1.0) @@ -301,7 +301,7 @@ DEPENDENCIES pry-rescue pry-stack_explorer puma - rails (= 4.2.3) + rails (= 4.2.5) react_on_rails! rspec-rails rspec-retry From 4371336f02be559534e4aece3237465f99680697 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 10 Jan 2017 01:42:51 +0300 Subject: [PATCH 11/42] 2017 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be4832f7c..8bb136dd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ Contributors: please follow the recommendations outlined at [keepachangelog.com] ## [Unreleased] *Please add entries here for your pull requests.* -## [6.3.5] - 2016-1-6 +## [6.3.5] - 2017-1-6 ### Fixed - The redux generator now creates a HelloWorld component that uses redux rather than local state. [#669](https://github.com/shakacode/react_on_rails/issues/669) by [justin808](https://github.com/justin808). From 07e758d0f426bac97554f1822cffcbeaf754865e Mon Sep 17 00:00:00 2001 From: Konstantin Date: Wed, 11 Jan 2017 00:26:41 +0300 Subject: [PATCH 12/42] Foreman dependency issue (remove foreman) (#678) * Remove foreman from dependencies and suggest to install it manually * change `gem install foreman` --- README.md | 2 ++ docs/additional-reading/foreman-issues.md | 15 +++++++++++++++ react_on_rails.gemspec | 1 - 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 docs/additional-reading/foreman-issues.md diff --git a/README.md b/README.md index ad1111350..bd5759748 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,8 @@ We're definitely not doing that. With react_on_rails, webpack is mainly generati 6. Start your Rails server: + with foreman installed (`gem install foreman`) + ```bash foreman start -f Procfile.dev ``` diff --git a/docs/additional-reading/foreman-issues.md b/docs/additional-reading/foreman-issues.md new file mode 100644 index 000000000..68e6448c9 --- /dev/null +++ b/docs/additional-reading/foreman-issues.md @@ -0,0 +1,15 @@ +# Foreman Issues + +## It is not recomended to include foreman into Gemfile + +See: https://github.com/ddollar/foreman + +> Ruby users should take care not to install foreman in their project's Gemfile. + +## Known issues + + * With `foreman 0.82.0` npm `react-s3-uploader` was failing to finish upload file to S3 when server was started by `foreman -f Procfile.dev`, + at the same time the same code works fine when ruby server started by `bundle exec rails s`. + + * The same Procfile with different versions of `foreman` in combination with different versions of `bundler` may produce different output of `ps aux`. + This may brake bash tools which rely on `ps` output. diff --git a/react_on_rails.gemspec b/react_on_rails.gemspec index c27bc2f44..6ea2c86df 100644 --- a/react_on_rails.gemspec +++ b/react_on_rails.gemspec @@ -25,7 +25,6 @@ Gem::Specification.new do |s| s.add_dependency "execjs", "~> 2.5" s.add_dependency "rainbow", "~> 2.1" s.add_dependency "rails", ">= 3.2" - s.add_dependency "foreman" s.add_dependency "addressable" s.add_development_dependency "bundler", "~> 1.10" From a97e209dd5ed9d848b59371a39c2e88555185385 Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Tue, 10 Jan 2017 11:29:00 -1000 Subject: [PATCH 13/42] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bb136dd1..557283328 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ Contributors: please follow the recommendations outlined at [keepachangelog.com] ## [Unreleased] *Please add entries here for your pull requests.* +### Fixed +- Removed foreman as a dependency. [#678](https://github.com/shakacode/react_on_rails/pull/678) by [x2es](https://github.com/x2es). ## [6.3.5] - 2017-1-6 ### Fixed From 9f0f63b1c3053f877d44e0f09334e71bb50d5a8d Mon Sep 17 00:00:00 2001 From: Jason Huang Date: Thu, 12 Jan 2017 20:43:08 +0100 Subject: [PATCH 14/42] Automatically generate i18n javascript files for react-intl when the serve starts up (#642) --- CHANGELOG.md | 3 + README.md | 19 +-- docs/basics/i18n.md | 90 +++++++++++++ .../config/initializers/react_on_rails.rb.tt | 6 + lib/react_on_rails.rb | 1 + lib/react_on_rails/configuration.rb | 4 + lib/react_on_rails/locales_to_js.rb | 119 ++++++++++++++++++ .../config/initializers/react_on_rails.rb | 6 + .../fixtures/i18n/locales/de.yml | 2 + .../fixtures/i18n/locales/en.yml | 2 + spec/react_on_rails/locales_to_js_spec.rb | 54 ++++++++ 11 files changed, 297 insertions(+), 9 deletions(-) create mode 100644 docs/basics/i18n.md create mode 100644 lib/react_on_rails/locales_to_js.rb create mode 100644 spec/react_on_rails/fixtures/i18n/locales/de.yml create mode 100644 spec/react_on_rails/fixtures/i18n/locales/en.yml create mode 100644 spec/react_on_rails/locales_to_js_spec.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 557283328..113ad15f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ Contributors: please follow the recommendations outlined at [keepachangelog.com] ### Fixed - Removed foreman as a dependency. [#678](https://github.com/shakacode/react_on_rails/pull/678) by [x2es](https://github.com/x2es). +### Added +- Automatically generate __i18n__ javascript files for `react-intl` when the serve starts up. [#642](https://github.com/shakacode/react_on_rails/pull/642) by [JasonYCHuang](https://github.com/JasonYCHuang). + ## [6.3.5] - 2017-1-6 ### Fixed - The redux generator now creates a HelloWorld component that uses redux rather than local state. [#669](https://github.com/shakacode/react_on_rails/issues/669) by [justin808](https://github.com/justin808). diff --git a/README.md b/README.md index bd5759748..1fee79fdf 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ React on Rails integrates Facebook's [React](https://github.com/facebook/react) - [Installation Summary](#installation-summary) - [Initializer Configuration: config/initializers/react_on_rails.rb](#initializer-configuration) - [Including your React Component in your Rails Views](#including-your-react-component-in-your-rails-views) + - [I18n](#i18n) + [How it Works](#how-it-works) - [Client-Side Rendering vs. Server-Side Rendering](#client-side-rendering-vs-server-side-rendering) - [Building the Bundles](#building-the-bundles) @@ -170,7 +171,15 @@ Configure the `config/initializers/react_on_rails.rb`. You can adjust some neces // inside your React component this.props.name // "Stranger" ``` - + +### I18n + +You can enable the i18n functionality with [react-intl](https://github.com/yahoo/react-intl). + +React on Rails provides an option for automatic conversions of Rails `*.yml` locale files into `*.js` files for `react-intl`. + +See the [How to add I18n](docs/basics/i18n.md) for a summary of adding I18n. + ## NPM All JavaScript in React On Rails is loaded from npm: [react-on-rails](https://www.npmjs.com/package/react-on-rails). To manually install this (you did not use the generator), assuming you have a standard configuration, run this command: @@ -245,11 +254,6 @@ The `railsContext` has: (see implementation in file [react_on_rails_helper.rb](a pathname: uri.path, # /posts search: uri.query, # id=30&limit=5 - # Locale settings - i18nLocale: I18n.locale, - i18nDefaultLocale: I18n.default_locale, - httpAcceptLanguage: request.env["HTTP_ACCEPT_LANGUAGE"], - # Other serverSide: boolean # Are we being called on the server or client? NOTE, if you conditionally # render something different on the server than the client, then React will only show the @@ -261,9 +265,6 @@ The `railsContext` has: (see implementation in file [react_on_rails_helper.rb](a ##### Needing the current url path for server rendering Suppose you want to display a nav bar with the current navigation link highlighted by the URL. When you server render the code, you will need to know the current URL/path if that is what you want your logic to be based on. The new `railsContext` has this information so the application of an "active" class can be done server side. -##### Needing the I18n.locale -Suppose you want to server render your react components with localization applied given the current Rails locale. The `railsContext` contains the I18n.locale. - ##### Configuring different code for server side rendering Suppose you want to turn off animation when doing server side rendering. The `serverSide` value is just what you need. diff --git a/docs/basics/i18n.md b/docs/basics/i18n.md new file mode 100644 index 000000000..f3a96df4e --- /dev/null +++ b/docs/basics/i18n.md @@ -0,0 +1,90 @@ +# How to add I18n + +Here's a summary of adding the I18n functionality. + +You can refer to [react-webpack-rails-tutorial](https://github.com/shakacode/react-webpack-rails-tutorial) for a complete example. + +1. Add `react-intl` & `intl` to `client/package.json`, and remember to `bundle && npm install`. + + ```js + "dependencies": { + ... + "intl": "^1.2.5", + "react-intl": "^2.1.5", + ... + } + ``` + +2. In `client/webpack.client.base.config.js`, set `react-intl` as an entry point. + + ```js + module.exports = { + ... + entry: { + ... + vendor: [ + ... + 'react-intl', + ], + ... + ``` + +3. `react-intl` requires locale files in json format. React on Rails will help you to generate or update `translations.js` & `default.js` automatically after you configured the following settings. + + > `translations.js`: All your locales in json format. + > + > `default.js`: Default settings in json format. + > + > You can add them to `.gitignore` and `.eslintignore`. + + Update settings in `config/initializers/react_on_rails.rb` to what you need: + + ```ruby + # Replace the following line to the location where you keep translation.js & default.js. + config.i18n_dir = Rails.root.join("PATH_TO", "YOUR_JS_I18N_FOLDER") + ``` + + Add following lines to `config/application.rb`, this will help you to generate `translations.js` & `default.js` automatically when you starts the server. + + ```js + module YourModule + class Application < Rails::Application + ... + config.after_initialize do + ReactOnRails::LocalesToJs.new + end + end + end + ``` + +5. In React, you need to initialize `react-intl`, and set parameters for it. + + ```js + ... + import { addLocaleData } from 'react-intl'; + import en from 'react-intl/locale-data/en'; + import de from 'react-intl/locale-data/de'; + import { translations } from 'path_to/i18n/translations'; + import { defaultLocale } from 'path_to/i18n/default'; + ... + // Initizalize all locales for react-intl. + addLocaleData([...en, ...de]); + ... + // set locale and messages for IntlProvider. + const locale = method_to_get_current_locale() || defaultLocale; + const messages = translations[locale]; + ... + return ( + + + + ) + ``` + ```js + // In your component. + import { defaultMessages } from 'path_to/i18n/default'; + ... + return ( + { formatMessage(defaultMessages.yourLocaleKeyInCamelCase) } + ) + ``` diff --git a/lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt b/lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt index 2e967a740..20cf015c3 100644 --- a/lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt +++ b/lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt @@ -59,6 +59,12 @@ ReactOnRails.configure do |config| config.server_renderer_pool_size = 1 # increase if you're on JRuby config.server_renderer_timeout = 20 # seconds + ################################################################################ + # I18N OPTIONS + ################################################################################ + # Replace the following line to the location where you keep translation.js & default.js. + config.i18n_dir = Rails.root.join("client", "app", "libs", "i18n") + ################################################################################ # MISCELLANEOUS OPTIONS ################################################################################ diff --git a/lib/react_on_rails.rb b/lib/react_on_rails.rb index e8bc066f3..72c978699 100644 --- a/lib/react_on_rails.rb +++ b/lib/react_on_rails.rb @@ -16,3 +16,4 @@ require "react_on_rails/test_helper/webpack_assets_status_checker" require "react_on_rails/test_helper/ensure_assets_compiled" require "react_on_rails/test_helper/node_process_launcher" +require "react_on_rails/locales_to_js" diff --git a/lib/react_on_rails/configuration.rb b/lib/react_on_rails/configuration.rb index a967038ee..9e8e74c80 100644 --- a/lib/react_on_rails/configuration.rb +++ b/lib/react_on_rails/configuration.rb @@ -72,6 +72,7 @@ def self.configuration server_render_method: "", symlink_non_digested_assets_regex: /\.(png|jpg|jpeg|gif|tiff|woff|ttf|eot|svg|map)/, npm_build_test_command: "", + i18n_dir: "", npm_build_production_command: "" ) end @@ -84,6 +85,7 @@ class Configuration :skip_display_none, :generated_assets_dirs, :generated_assets_dir, :webpack_generated_files, :rendering_extension, :npm_build_test_command, :npm_build_production_command, + :i18n_dir, :server_render_method, :symlink_non_digested_assets_regex def initialize(server_bundle_js_file: nil, prerender: nil, replay_console: nil, @@ -94,12 +96,14 @@ def initialize(server_bundle_js_file: nil, prerender: nil, replay_console: nil, generated_assets_dir: nil, webpack_generated_files: nil, rendering_extension: nil, npm_build_test_command: nil, npm_build_production_command: nil, + i18n_dir: nil, server_render_method: nil, symlink_non_digested_assets_regex: nil) self.server_bundle_js_file = server_bundle_js_file self.generated_assets_dirs = generated_assets_dirs self.generated_assets_dir = generated_assets_dir self.npm_build_test_command = npm_build_test_command self.npm_build_production_command = npm_build_production_command + self.i18n_dir = i18n_dir self.prerender = prerender self.replay_console = replay_console diff --git a/lib/react_on_rails/locales_to_js.rb b/lib/react_on_rails/locales_to_js.rb new file mode 100644 index 000000000..334928961 --- /dev/null +++ b/lib/react_on_rails/locales_to_js.rb @@ -0,0 +1,119 @@ +require "erb" + +module ReactOnRails + class LocalesToJs + def initialize + return unless obsolete? + @translations, @defaults = generate_translations + convert + end + + private + + def obsolete? + return true if exist_js_files.empty? + js_files_are_outdated + end + + def exist_js_files + @exist_js_files ||= js_files.select(&File.method(:exist?)) + end + + def js_files_are_outdated + latest_yml = locale_files.map(&File.method(:mtime)).max + earliest_js = exist_js_files.map(&File.method(:mtime)).min + latest_yml > earliest_js + end + + def js_file_names + %w(translations default) + end + + def js_files + @js_files ||= js_file_names.map { |n| js_file(n) } + end + + def js_file(name) + "#{i18n_dir}/#{name}.js" + end + + def locale_files + @locale_files ||= Rails.application.config.i18n.load_path + end + + def i18n_dir + @i18n_dir ||= ReactOnRails.configuration.i18n_dir + end + + def default_locale + @default_locale ||= I18n.default_locale.to_s || "en" + end + + def convert + js_file_names.each do |name| + template = send("template_#{name}") + path = js_file(name) + generate_js_file(template, path) + end + end + + def generate_js_file(template, path) + result = ERB.new(template).result() + File.open(path, "w") do |f| + f.write(result) + end + end + + def generate_translations + translations = {} + defaults = {} + locale_files.each do |f| + translation = YAML.load(File.open(f)) + key = translation.keys[0] + val = flatten(translation[key]) + translations = translations.deep_merge(key => val) + defaults = defaults.deep_merge(flatten_defaults(val)) if key == default_locale + end + [translations.to_json, defaults.to_json] + end + + def format(input) + input.to_s.tr(".", "_").camelize(:lower).to_sym + end + + def flatten_defaults(val) + flatten(val).each_with_object({}) do |(k, v), h| + key = format(k) + h[key] = { id: k, defaultMessage: v } + end + end + + def flatten(translations) + translations.each_with_object({}) do |(k, v), h| + if v.is_a? Hash + flatten(v).map { |hk, hv| h["#{k}.#{hk}".to_sym] = hv } + else + h[k] = v + end + end + end + + def template_translations + <<-JS +export const translations = #{@translations}; + JS + end + + def template_default + <<-JS +import { defineMessages } from 'react-intl'; + +const defaultLocale = \'#{default_locale}\'; + +const defaultMessages = defineMessages(#{@defaults}); + +export { defaultMessages, defaultLocale }; + JS + end + end +end diff --git a/spec/dummy/config/initializers/react_on_rails.rb b/spec/dummy/config/initializers/react_on_rails.rb index d6fec053c..940b4a86b 100644 --- a/spec/dummy/config/initializers/react_on_rails.rb +++ b/spec/dummy/config/initializers/react_on_rails.rb @@ -71,6 +71,12 @@ def self.custom_context(view_context) config.server_renderer_pool_size = 1 # increase if you're on JRuby config.server_renderer_timeout = 20 # seconds + ################################################################################ + # I18N OPTIONS + ################################################################################ + # Replace the following line to the location where you keep translation.js & default.js. + config.i18n_dir = Rails.root.join("client", "app", "libs", "i18n") + ################################################################################ # MISCELLANEOUS OPTIONS ################################################################################ diff --git a/spec/react_on_rails/fixtures/i18n/locales/de.yml b/spec/react_on_rails/fixtures/i18n/locales/de.yml new file mode 100644 index 000000000..3f02f787e --- /dev/null +++ b/spec/react_on_rails/fixtures/i18n/locales/de.yml @@ -0,0 +1,2 @@ +de: + hello: "Hallo welt" diff --git a/spec/react_on_rails/fixtures/i18n/locales/en.yml b/spec/react_on_rails/fixtures/i18n/locales/en.yml new file mode 100644 index 000000000..a9f72ecc7 --- /dev/null +++ b/spec/react_on_rails/fixtures/i18n/locales/en.yml @@ -0,0 +1,2 @@ +en: + hello: "Hello world" diff --git a/spec/react_on_rails/locales_to_js_spec.rb b/spec/react_on_rails/locales_to_js_spec.rb new file mode 100644 index 000000000..40051f652 --- /dev/null +++ b/spec/react_on_rails/locales_to_js_spec.rb @@ -0,0 +1,54 @@ +require_relative "spec_helper" +require "tmpdir" + +module ReactOnRails + RSpec.describe LocalesToJs do + let(:i18n_dir) { Pathname.new(Dir.mktmpdir) } + let(:locale_dir) { File.expand_path("../fixtures/i18n/locales", __FILE__) } + let(:translations_path) { "#{i18n_dir}/translations.js" } + let(:default_path) { "#{i18n_dir}/default.js" } + let(:en_path) { "#{locale_dir}/en.yml" } + + before do + allow_any_instance_of(ReactOnRails::LocalesToJs).to receive(:locale_files).and_return(Dir["#{locale_dir}/*"]) + ReactOnRails.configure do |config| + config.i18n_dir = i18n_dir + end + end + + context "with obsolete js files" do + before do + FileUtils.touch(translations_path, mtime: Time.now - 1.year) + FileUtils.touch(en_path, mtime: Time.now - 1.month) + end + + it "updates files" do + ReactOnRails::LocalesToJs.new + + translations = File.read(translations_path) + default = File.read(default_path) + expect(translations).to include("{\"hello\":\"Hello world\"") + expect(translations).to include("{\"hello\":\"Hallo welt\"") + expect(default).to include("const defaultLocale = 'en';") + expect(default).to include("{\"hello\":{\"id\":\"hello\",\"defaultMessage\":\"Hello world\"}}") + + expect(File.mtime(translations_path)).to be >= File.mtime(en_path) + end + end + + context "with up-to-date js files" do + before do + ReactOnRails::LocalesToJs.new + end + + it "doesn't update files" do + ref_time = Time.now - 1.minute + FileUtils.touch(translations_path, mtime: ref_time) + + update_time = Time.now + ReactOnRails::LocalesToJs.new + expect(update_time).to be > File.mtime(translations_path) + end + end + end +end From af428a6aa4e61d6587e7c09f08d8674e056b0fd4 Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Thu, 12 Jan 2017 23:47:59 -1000 Subject: [PATCH 15/42] Update CHANGELOG.md --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 113ad15f4..4c8505c51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ Contributors: please follow the recommendations outlined at [keepachangelog.com] ## [Unreleased] *Please add entries here for your pull requests.* + +## [6.4.0] - 2017-1-12 + ### Fixed - Removed foreman as a dependency. [#678](https://github.com/shakacode/react_on_rails/pull/678) by [x2es](https://github.com/x2es). @@ -422,7 +425,8 @@ Best done with Object destructing: ##### Fixed - Fix several generator related issues. -[Unreleased]: https://github.com/shakacode/react_on_rails/compare/6.3.5...master +[Unreleased]: https://github.com/shakacode/react_on_rails/compare/6.4.0...master +[6.4.0]: https://github.com/shakacode/react_on_rails/compare/6.3.5...6.4.0 [6.3.5]: https://github.com/shakacode/react_on_rails/compare/6.3.4...6.3.5 [6.3.4]: https://github.com/shakacode/react_on_rails/compare/6.3.3...6.3.4 [6.3.3]: https://github.com/shakacode/react_on_rails/compare/6.3.2...6.3.3 From dcd2a928a2551efda8e6df974a5c2fa7252d283c Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Thu, 12 Jan 2017 23:48:21 -1000 Subject: [PATCH 16/42] Release 6.4.0 --- lib/react_on_rails/version.rb | 2 +- package.json | 2 +- spec/dummy/Gemfile.lock | 5 +---- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/lib/react_on_rails/version.rb b/lib/react_on_rails/version.rb index 721aaa912..28a3ef9b2 100644 --- a/lib/react_on_rails/version.rb +++ b/lib/react_on_rails/version.rb @@ -1,4 +1,4 @@ # frozen_string_literal: true module ReactOnRails - VERSION = "6.3.5".freeze + VERSION = "6.4.0".freeze end diff --git a/package.json b/package.json index 313ab90d0..aaedb34d1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-on-rails", - "version": "6.3.5", + "version": "6.4.0", "description": "react-on-rails JavaScript for react_on_rails Ruby gem", "main": "node_package/lib/ReactOnRails.js", "directories": { diff --git a/spec/dummy/Gemfile.lock b/spec/dummy/Gemfile.lock index 14d60b7ac..55e77c655 100644 --- a/spec/dummy/Gemfile.lock +++ b/spec/dummy/Gemfile.lock @@ -1,11 +1,10 @@ PATH remote: ../.. specs: - react_on_rails (6.3.5) + react_on_rails (6.4.0) addressable connection_pool execjs (~> 2.5) - foreman rails (>= 3.2) rainbow (~> 2.1) @@ -99,8 +98,6 @@ GEM erubis (2.7.0) execjs (2.7.0) ffi (1.9.14) - foreman (0.82.0) - thor (~> 0.19.1) generator_spec (0.9.3) activesupport (>= 3.0.0) railties (>= 3.0.0) From c3d624e2f5fceb7209e0cc4a20e7ddc92130fccd Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Fri, 13 Jan 2017 18:04:02 -1000 Subject: [PATCH 17/42] 6.4 changes to docs for removal of foreman from dependencies (#684) * Changes for 6.4 to docs * Update README.md --- CHANGELOG.md | 3 +++ README.md | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c8505c51..c4ee209a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ Contributors: please follow the recommendations outlined at [keepachangelog.com] ## [6.4.0] - 2017-1-12 +### Possible Breaking Change +- Since foreman is no longer a dependency of the React on Rails gem, please run `gem install foreman`. If you are using rvm, you may wish to run `rvm @global do gem install foreman` to install foreman for all your gemsets. + ### Fixed - Removed foreman as a dependency. [#678](https://github.com/shakacode/react_on_rails/pull/678) by [x2es](https://github.com/x2es). diff --git a/README.md b/README.md index 1fee79fdf..7450b3eee 100644 --- a/README.md +++ b/README.md @@ -119,9 +119,9 @@ We're definitely not doing that. With react_on_rails, webpack is mainly generati bundle && npm install ``` -6. Start your Rails server: +6. Ensure that you have `foreman` installed: `gem install foreman`. - with foreman installed (`gem install foreman`) +7. Start your Rails server: ```bash foreman start -f Procfile.dev From 737e6fc00812f5b138e35e94d298eeb84e03a6ed Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Sat, 14 Jan 2017 22:52:25 -1000 Subject: [PATCH 18/42] Update CONTRIBUTING.md --- CONTRIBUTING.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9d86e01f3..8728793e7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -176,6 +176,13 @@ npm test ```sh cd spec/dummy +rspec +``` + +Eventually, we may have JS tests: + +```sh +cd spec/dummy/client npm run test ``` From 53af84126bb1a7c10a89849625938e84775f344e Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Sun, 15 Jan 2017 11:32:35 -1000 Subject: [PATCH 19/42] Update heroku-deployment.md --- docs/additional-reading/heroku-deployment.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/additional-reading/heroku-deployment.md b/docs/additional-reading/heroku-deployment.md index 58df582be..542b43725 100644 --- a/docs/additional-reading/heroku-deployment.md +++ b/docs/additional-reading/heroku-deployment.md @@ -5,6 +5,9 @@ The generator has created the necessary files and gems for deployment to Heroku. + `12factor` gem: required by Heroku if using a version before Rails 5 (see their [README](https://github.com/heroku/rails_12factor#rails-5) for more information if upgrading from a lower version) + `'puma'` gem: recommended Heroku webserver + `config/puma.rb`: Puma webserver config file ++ `/package.json`: Top level package.json which must contain `"scripts": { "postinstall": "cd client && npm install" }` + +If you want to see an updated example deployed to Heroku, please visit the [github.com/shakacode/react-webpack-rails-tutorial](https://github.com/shakacode/react-webpack-rails-tutorial). ## More details on precompilation using webpack to create JavaScript assets This is how the rake task gets modified. You should be able to call `clear_prerequisites` and setup your own custom precompile if needed. From 0796bf445f20de84622c69dfa94371abc43ee277 Mon Sep 17 00:00:00 2001 From: George Date: Wed, 18 Jan 2017 10:23:49 +0300 Subject: [PATCH 20/42] Added OS detection for install generator system call for Windows and unit-tests for it. (#666) --- CHANGELOG.md | 2 + .../react_on_rails/install_generator.rb | 4 +- lib/react_on_rails/utils.rb | 4 ++ .../generators/install_generator_spec.rb | 64 +++++++++++++++++++ 4 files changed, 72 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4ee209a0..ea05290e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ Contributors: please follow the recommendations outlined at [keepachangelog.com] ## [Unreleased] *Please add entries here for your pull requests.* +### Fixed +- Added OS detection for install generator, system call for Windows and unit-tests for it. [#666](https://github.com/shakacode/react_on_rails/pull/666) by [GeorgeGorbanev](https://github.com/GeorgeGorbanev). ## [6.4.0] - 2017-1-12 diff --git a/lib/generators/react_on_rails/install_generator.rb b/lib/generators/react_on_rails/install_generator.rb index 91be836f8..ff8afb933 100644 --- a/lib/generators/react_on_rails/install_generator.rb +++ b/lib/generators/react_on_rails/install_generator.rb @@ -64,7 +64,7 @@ def installation_prerequisites_met? end def missing_npm? - return false unless `which npm`.blank? + return false unless ReactOnRails::Utils.running_on_windows? ? `where npm`.blank? : `which npm`.blank? error = "npm is required. Please install it before continuing. " error << "https://www.npmjs.com/" GeneratorMessages.add_error(error) @@ -72,7 +72,7 @@ def missing_npm? end def missing_node? - return false unless `which node`.blank? + return false unless ReactOnRails::Utils.running_on_windows? ? `where node`.blank? : `which node`.blank? error = "** nodejs is required. Please install it before continuing. " error << "https://nodejs.org/en/" GeneratorMessages.add_error(error) diff --git a/lib/react_on_rails/utils.rb b/lib/react_on_rails/utils.rb index 08ee540c6..599c4e3fe 100644 --- a/lib/react_on_rails/utils.rb +++ b/lib/react_on_rails/utils.rb @@ -20,6 +20,10 @@ def self.default_server_bundle_js_file_path ReactOnRails.configuration.server_bundle_js_file) end + def self.running_on_windows? + (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil + end + module Required def required(arg_name) raise ArgumentError, "#{arg_name} is required" diff --git a/spec/react_on_rails/generators/install_generator_spec.rb b/spec/react_on_rails/generators/install_generator_spec.rb index c70b5de11..fc616fe78 100644 --- a/spec/react_on_rails/generators/install_generator_spec.rb +++ b/spec/react_on_rails/generators/install_generator_spec.rb @@ -111,4 +111,68 @@ .to include(GeneratorMessages.format_info(expected)) end end + + context "detect existing bin-files on *nix" do + before(:all) { @install_generator = InstallGenerator.new } + + specify "when node is exist" do + stub_const("RUBY_PLATFORM", "linux") + allow(@install_generator).to receive(:`).with("which node").and_return("/path/to/bin") + expect(@install_generator.send(:missing_node?)).to eq false + end + + specify "when npm is exist" do + stub_const("RUBY_PLATFORM", "linux") + allow(@install_generator).to receive(:`).with("which npm").and_return("/path/to/bin") + expect(@install_generator.send(:missing_npm?)).to eq false + end + end + + context "detect missing bin-files on *nix" do + before(:all) { @install_generator = InstallGenerator.new } + + specify "when node is missing" do + stub_const("RUBY_PLATFORM", "linux") + allow(@install_generator).to receive(:`).with("which node").and_return("") + expect(@install_generator.send(:missing_node?)).to eq true + end + + specify "when npm is missing" do + stub_const("RUBY_PLATFORM", "linux") + allow(@install_generator).to receive(:`).with("which npm").and_return("") + expect(@install_generator.send(:missing_npm?)).to eq true + end + end + + context "detect existing bin-files on windows" do + before(:all) { @install_generator = InstallGenerator.new } + + specify "when node is exist" do + stub_const("RUBY_PLATFORM", "mswin") + allow(@install_generator).to receive(:`).with("where node").and_return("/path/to/bin") + expect(@install_generator.send(:missing_node?)).to eq false + end + + specify "when npm is exist" do + stub_const("RUBY_PLATFORM", "mswin") + allow(@install_generator).to receive(:`).with("where npm").and_return("/path/to/bin") + expect(@install_generator.send(:missing_npm?)).to eq false + end + end + + context "detect missing bin-files on windows" do + before(:all) { @install_generator = InstallGenerator.new } + + specify "when node is missing" do + stub_const("RUBY_PLATFORM", "mswin") + allow(@install_generator).to receive(:`).with("where node").and_return("") + expect(@install_generator.send(:missing_node?)).to eq true + end + + specify "when npm is missing" do + stub_const("RUBY_PLATFORM", "mswin") + allow(@install_generator).to receive(:`).with("where npm").and_return("") + expect(@install_generator.send(:missing_npm?)).to eq true + end + end end From bcfcb0f51192b4fd893cd9588624c7b36a6e2552 Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Tue, 17 Jan 2017 21:26:02 -1000 Subject: [PATCH 21/42] Updated CHANGELOG.md --- CHANGELOG.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea05290e9..f51195fdf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,13 +5,18 @@ Contributors: please follow the recommendations outlined at [keepachangelog.com] ## [Unreleased] *Please add entries here for your pull requests.* + +## [6.4.2] - 2017-1-17 ### Fixed - Added OS detection for install generator, system call for Windows and unit-tests for it. [#666](https://github.com/shakacode/react_on_rails/pull/666) by [GeorgeGorbanev](https://github.com/GeorgeGorbanev). +## [6.4.1] - 2017-1-17 +No changes. + ## [6.4.0] - 2017-1-12 ### Possible Breaking Change -- Since foreman is no longer a dependency of the React on Rails gem, please run `gem install foreman`. If you are using rvm, you may wish to run `rvm @global do gem install foreman` to install foreman for all your gemsets. +- Since foreman is no longer a dependency of the React on Rails gem, please run `gem install foreman`. If you are using rvm, you may wish to run `rvm @global do gem install foreman` to install foreman for all your gemsets. ### Fixed - Removed foreman as a dependency. [#678](https://github.com/shakacode/react_on_rails/pull/678) by [x2es](https://github.com/x2es). @@ -430,7 +435,9 @@ Best done with Object destructing: ##### Fixed - Fix several generator related issues. -[Unreleased]: https://github.com/shakacode/react_on_rails/compare/6.4.0...master +[Unreleased]: https://github.com/shakacode/react_on_rails/compare/6.4.2...master +[6.4.2]: https://github.com/shakacode/react_on_rails/compare/6.4.1...6.4.2 +[6.4.1]: https://github.com/shakacode/react_on_rails/compare/6.4.0...6.4.1 [6.4.0]: https://github.com/shakacode/react_on_rails/compare/6.3.5...6.4.0 [6.3.5]: https://github.com/shakacode/react_on_rails/compare/6.3.4...6.3.5 [6.3.4]: https://github.com/shakacode/react_on_rails/compare/6.3.3...6.3.4 From 4e567a364e57f1a320a4cf723e475666bc763b90 Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Tue, 17 Jan 2017 21:26:29 -1000 Subject: [PATCH 22/42] Release 6.4.2 --- lib/react_on_rails/version.rb | 2 +- package.json | 2 +- spec/dummy/Gemfile.lock | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/react_on_rails/version.rb b/lib/react_on_rails/version.rb index 28a3ef9b2..a62325a86 100644 --- a/lib/react_on_rails/version.rb +++ b/lib/react_on_rails/version.rb @@ -1,4 +1,4 @@ # frozen_string_literal: true module ReactOnRails - VERSION = "6.4.0".freeze + VERSION = "6.4.2".freeze end diff --git a/package.json b/package.json index aaedb34d1..550360feb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-on-rails", - "version": "6.4.0", + "version": "6.4.2", "description": "react-on-rails JavaScript for react_on_rails Ruby gem", "main": "node_package/lib/ReactOnRails.js", "directories": { diff --git a/spec/dummy/Gemfile.lock b/spec/dummy/Gemfile.lock index 55e77c655..66846c365 100644 --- a/spec/dummy/Gemfile.lock +++ b/spec/dummy/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: ../.. specs: - react_on_rails (6.4.0) + react_on_rails (6.4.2) addressable connection_pool execjs (~> 2.5) From 4cf969ae0f5b086a1f9f1b3f438d8501a495115a Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Tue, 17 Jan 2017 20:50:28 -1000 Subject: [PATCH 23/42] Added property renderedHtml to return gen func This is to support React Router v4, which needs the result of calling renderToString. --- README.md | 6 +- docs/additional-reading/react-router.md | 65 +++++++++++++++++++ docs/api/javascript-api.md | 4 +- node_package/src/clientStartup.js | 2 +- ...eateReactElementResultNonReactComponent.js | 6 ++ node_package/src/isRouterResult.js | 5 -- .../src/serverRenderReactComponent.js | 24 +++++-- .../tests/serverRenderReactComponent.test.js | 17 +++++ spec/dummy/Procfile | 6 ++ spec/dummy/app/views/pages/_header.erb | 3 + spec/dummy/app/views/pages/index.html.erb | 8 +++ spec/dummy/app/views/pages/rendered_html.erb | 7 ++ .../dummy/client/app/components/EchoProps.jsx | 9 +++ .../client/app/startup/ClientRenderedHtml.jsx | 17 +++++ .../client/app/startup/ServerRenderedHtml.jsx | 21 ++++++ .../client/app/startup/clientRegistration.jsx | 6 +- .../client/app/startup/serverRegistration.jsx | 4 ++ spec/dummy/config/routes.rb | 1 + spec/dummy/spec/features/integration_spec.rb | 9 +++ 19 files changed, 203 insertions(+), 17 deletions(-) create mode 100644 node_package/src/isCreateReactElementResultNonReactComponent.js delete mode 100644 node_package/src/isRouterResult.js create mode 100644 spec/dummy/app/views/pages/rendered_html.erb create mode 100644 spec/dummy/client/app/components/EchoProps.jsx create mode 100644 spec/dummy/client/app/startup/ClientRenderedHtml.jsx create mode 100644 spec/dummy/client/app/startup/ServerRenderedHtml.jsx diff --git a/README.md b/README.md index 7450b3eee..7ba79531c 100644 --- a/README.md +++ b/README.md @@ -217,7 +217,7 @@ On production deployments that use asset precompilation, such as Heroku deployme If you have used the provided generator, these bundles will automatically be added to your `.gitignore` to prevent extraneous noise from re-generated code in your pull requests. You will want to do this manually if you do not use the provided generator. ### Rails Context -When you use a "generator function" to create react components or you used shared redux stores, you get 2 params passed to your function: +When you use a "generator function" to create react components (or renderedHtml on the server) or you used shared redux stores, you get 2 params passed to your function: 1. Props that you pass in the view helper of either `react_component` or `redux_store` 2. Rails contextual information, such as the current pathname. You can customize this in your config file. @@ -318,6 +318,8 @@ If you do want different code to run, you'd setup a separate webpack compilation #### Generator Functions Why would you create a function that returns a React component? For example, you may want the ability to use the passed-in props to initialize a redux store or setup react-router. Or you may want to return different components depending on what's in the props. ReactOnRails will automatically detect a registered generator function. +Another reason to user a generator function is that sometimes in server rendering, specifically with React Router, you need to return the result of calling ReactDOMServer.renderToString(element). You can do this by returning an object with the following shape: { renderedHtml, redirectLocation, error }. + #### Renderer Functions A renderer function is a generator function that accepts three arguments: `(props, railsContext, domNodeId) => { ... }`. Instead of returning a React component, a renderer is responsible for calling `ReactDOM.render` to manually render a React component into the dom. Why would you want to call `ReactDOM.render` yourself? One possible use case is [code splitting](docs/additional-reading/code-splitting.md). @@ -340,7 +342,7 @@ react_component(component_name, html_options: {}) ``` -+ **component_name:** Can be a React component, created using a ES6 class, or `React.createClass`, a generator function that returns a React component, or a renderer function that manually renders a React component to the dom (client side only). ++ **component_name:** Can be a React component, created using a ES6 class, or `React.createClass`, a generator function that returns a React component (or only on the server side, an object with shape { redirectLocation, error, renderedHtml }), or a renderer function that manually renders a React component to the dom (client side only). + **options:** + **props:** Ruby Hash which contains the properties to pass to the react object, or a JSON string. If you pass a string, we'll escape it for you. + **prerender:** enable server-side rendering of component. Set to false when debugging! diff --git a/docs/additional-reading/react-router.md b/docs/additional-reading/react-router.md index b4a335416..846bb5486 100644 --- a/docs/additional-reading/react-router.md +++ b/docs/additional-reading/react-router.md @@ -46,3 +46,68 @@ For a fleshed out integration of react_on_rails with react-router, check out [Re * [react-webpack-rails-tutorial/client/app/bundles/comments/startup/ClientRouterApp.jsx](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/client/app/bundles/comments/startup/ClientRouterApp.jsx) * [react-webpack-rails-tutorial/client/app/bundles/comments/startup/ServerRouterApp.jsx](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/client/app/bundles/comments/startup/ServerRouterApp.jsx) + + +# Server Rendering Using React Router V4 + +Your generator function may not return an object with the property `renderedHtml`. Thus, you call +renderToString() and return an object with this property. + +This example **only applies to server rendering** and should be only used in the server side bundle. + +From the [original example in the ReactRouter docs](https://react-router.now.sh/ServerRouter) + +```javascript + import React from 'react' + import { renderToString } from 'react-dom/server' + import { ServerRouter, createServerRenderContext } from 'react-router' + + const ReactRouterComponent = (props, railsContext) => { + + // first create a context for , it's where we keep the + // results of rendering for the second pass if necessary + const context = createServerRenderContext() + const { location } = railsContext; + + // render the first time + let markup = renderToString( + + + + ) + + // get the result + const result = context.getResult() + + // the result will tell you if it redirected, if so, we ignore + // the markup and send a proper redirect. + if (result.redirect) { + return { + redirectLocation: result.redirect.pathname + }; + } else { + + // the result will tell you if there were any misses, if so + // we can send a 404 and then do a second render pass with + // the context to clue the components into rendering + // this time (on the client they know from componentDidMount) + if (result.missed) { + // React on Rails does not support the 404 status code for the browser. + // res.writeHead(404) + + markup = renderToString( + + + + ) + } + return { renderedHtml: markup }; + } + } +``` diff --git a/docs/api/javascript-api.md b/docs/api/javascript-api.md index 49f608429..104f5f954 100644 --- a/docs/api/javascript-api.md +++ b/docs/api/javascript-api.md @@ -4,7 +4,9 @@ The best source of docs is the main [ReactOnRails.js](../../node_package/src/Rea ```js /** * Main entry point to using the react-on-rails npm package. This is how Rails will be able to - * find you components for rendering. + * find you components for rendering. Components get called with props, or you may use a + * "generator function" to return a React component or an object with the following shape: + * { renderedHtml, redirectLocation, error }. * @param components (key is component name, value is component) */ register(components) diff --git a/node_package/src/clientStartup.js b/node_package/src/clientStartup.js index cbfbb55bb..5bb8b4dfc 100644 --- a/node_package/src/clientStartup.js +++ b/node_package/src/clientStartup.js @@ -3,7 +3,7 @@ import ReactDOM from 'react-dom'; import createReactElement from './createReactElement'; -import isRouterResult from './isRouterResult'; +import isRouterResult from './isCreateReactElementResultNonReactComponent'; const REACT_ON_RAILS_COMPONENT_CLASS_NAME = 'js-react-on-rails-component'; const REACT_ON_RAILS_STORE_CLASS_NAME = 'js-react-on-rails-store'; diff --git a/node_package/src/isCreateReactElementResultNonReactComponent.js b/node_package/src/isCreateReactElementResultNonReactComponent.js new file mode 100644 index 000000000..c5ea39cf9 --- /dev/null +++ b/node_package/src/isCreateReactElementResultNonReactComponent.js @@ -0,0 +1,6 @@ +export default function isResultNonReactComponent(reactElementOrRouterResult) { + return !!( + reactElementOrRouterResult.renderedHtml || + reactElementOrRouterResult.redirectLocation || + reactElementOrRouterResult.error); +} diff --git a/node_package/src/isRouterResult.js b/node_package/src/isRouterResult.js deleted file mode 100644 index 9394feb77..000000000 --- a/node_package/src/isRouterResult.js +++ /dev/null @@ -1,5 +0,0 @@ -export default function isRouterResult(reactElementOrRouterResult) { - return !!( - reactElementOrRouterResult.redirectLocation || - reactElementOrRouterResult.error); -} diff --git a/node_package/src/serverRenderReactComponent.js b/node_package/src/serverRenderReactComponent.js index 74d5d9f00..db6588501 100644 --- a/node_package/src/serverRenderReactComponent.js +++ b/node_package/src/serverRenderReactComponent.js @@ -2,7 +2,8 @@ import ReactDOMServer from 'react-dom/server'; import ComponentRegistry from './ComponentRegistry'; import createReactElement from './createReactElement'; -import isRouterResult from './isRouterResult'; +import isCreateReactElementResultNonReactComponent from + './isCreateReactElementResultNonReactComponent'; import buildConsoleReplay from './buildConsoleReplay'; import handleError from './handleError'; @@ -28,20 +29,29 @@ See https://github.com/shakacode/react_on_rails#renderer-functions`); railsContext, }); - if (isRouterResult(reactElementOrRouterResult)) { + if (isCreateReactElementResultNonReactComponent(reactElementOrRouterResult)) { // We let the client side handle any redirect // Set hasErrors in case we want to throw a Rails exception hasErrors = !!reactElementOrRouterResult.routeError; + if (hasErrors) { console.error( `React Router ERROR: ${JSON.stringify(reactElementOrRouterResult.routeError)}`, ); - } else if (trace) { - const redirectLocation = reactElementOrRouterResult.redirectLocation; - const redirectPath = redirectLocation.pathname + redirectLocation.search; - console.log(`\ + } + + if (reactElementOrRouterResult.redirectLocation) { + if (trace) { + const redirectLocation = reactElementOrRouterResult.redirectLocation; + const redirectPath = redirectLocation.pathname + redirectLocation.search; + console.log(`\ ROUTER REDIRECT: ${name} to dom node with id: ${domNodeId}, redirect to ${redirectPath}`, - ); + ); + } + // For redirects on server rendering, we can't stop Rails from returning the same result. + // Possibly, someday, we could have the rails server redirect. + } else { + htmlResult = reactElementOrRouterResult.renderedHtml; } } else { htmlResult = ReactDOMServer.renderToString(reactElementOrRouterResult); diff --git a/node_package/tests/serverRenderReactComponent.test.js b/node_package/tests/serverRenderReactComponent.test.js index 86623f931..d94f852dd 100644 --- a/node_package/tests/serverRenderReactComponent.test.js +++ b/node_package/tests/serverRenderReactComponent.test.js @@ -38,6 +38,23 @@ test('serverRenderReactComponent renders errors', (assert) => { assert.ok(hasErrors, 'serverRenderReactComponent should have errors if exception thrown'); }); +test('serverRenderReactComponent renders html', (assert) => { + assert.plan(3); + const expectedHtml = '
Hello
'; + const X3 = () => ({ renderedHtml: expectedHtml }); + + ComponentStore.register({ X3 }); + + assert.comment('Expect to see renderedHtml'); + + const { html, hasErrors, renderedHtml } = + JSON.parse(serverRenderReactComponent({ name: 'X3', domNodeId: 'myDomId', trace: false })); + + assert.ok(html === expectedHtml, 'serverRenderReactComponent HTML should render renderedHtml value'); + assert.ok(!hasErrors, 'serverRenderReactComponent should not have errors if no exception thrown'); + assert.ok(!hasErrors, 'serverRenderReactComponent should have errors if exception thrown'); +}); + test('serverRenderReactComponent renders an error if attempting to render a renderer', (assert) => { assert.plan(1); const X3 = (a1, a2, a3) => null; diff --git a/spec/dummy/Procfile b/spec/dummy/Procfile index 008ba4d87..60581e734 100644 --- a/spec/dummy/Procfile +++ b/spec/dummy/Procfile @@ -1 +1,7 @@ rails: REACT_ON_RAILS_ENV=HOT rails s -b 0.0.0.0 + +# Build client assets, watching for changes. +rails-client-assets: rm app/assets/webpack/* || true && npm run build:dev:client + +# Build server assets, watching for changes. Remove if not server rendering. +rails-server-assets: npm run build:dev:server diff --git a/spec/dummy/app/views/pages/_header.erb b/spec/dummy/app/views/pages/_header.erb index a0834dcf8..dfd8cc033 100644 --- a/spec/dummy/app/views/pages/_header.erb +++ b/spec/dummy/app/views/pages/_header.erb @@ -74,5 +74,8 @@
  • <%= link_to "Turbolinks Cache Disabled Example", turbolinks_cache_disabled_path %>
  • +
  • + <%= link_to "Generator function returns object with renderedHtml", rendered_html_path %> +

  • diff --git a/spec/dummy/app/views/pages/index.html.erb b/spec/dummy/app/views/pages/index.html.erb index 24b58c3ad..1c8ed4942 100644 --- a/spec/dummy/app/views/pages/index.html.erb +++ b/spec/dummy/app/views/pages/index.html.erb @@ -69,6 +69,14 @@ This page demonstrates a few things the other pages do not show: <%= react_component("HelloWorldApp", props: @app_props_hello_again, prerender: false, trace: true, id: "HelloWorldApp-react-component-3") %>
    +

    Component that returns string html on server

    +
    +  <%%= react_component("HelloWorld", props: @app_props_hello, prerender: false, trace: true, id: "HelloWorld-react-component-4") %>
    +  <%%= react_component("HelloES5", props: @app_props_hello, prerender: false, trace: true, id: "HelloES5-react-component-5") %>
    +
    +<%= react_component("RenderedHtml", prerender: true, trace: true, id: "HelloWorld-react-component-4") %> +
    +

    Simple Component Without Redux

       <%%= react_component("HelloWorld", props: @app_props_hello, prerender: false, trace: true, id: "HelloWorld-react-component-4") %>
    diff --git a/spec/dummy/app/views/pages/rendered_html.erb b/spec/dummy/app/views/pages/rendered_html.erb
    new file mode 100644
    index 000000000..c776d267e
    --- /dev/null
    +++ b/spec/dummy/app/views/pages/rendered_html.erb
    @@ -0,0 +1,7 @@
    +<%= render "header" %>
    +
    +<%= react_component("RenderedHtml", prerender: true, props: { hello: "world" }, trace: true) %>
    +
    +
    + +This page demonstrates a component that returns renderToString on the server side. diff --git a/spec/dummy/client/app/components/EchoProps.jsx b/spec/dummy/client/app/components/EchoProps.jsx new file mode 100644 index 000000000..ad1ef9e6a --- /dev/null +++ b/spec/dummy/client/app/components/EchoProps.jsx @@ -0,0 +1,9 @@ +import React from 'react'; + +const EchoProps = (props) => ( +
    + Props: {JSON.stringify(props)} +
    +); + +export default EchoProps diff --git a/spec/dummy/client/app/startup/ClientRenderedHtml.jsx b/spec/dummy/client/app/startup/ClientRenderedHtml.jsx new file mode 100644 index 000000000..ea32466a6 --- /dev/null +++ b/spec/dummy/client/app/startup/ClientRenderedHtml.jsx @@ -0,0 +1,17 @@ +// Top level component for simple client side only rendering +import React from 'react'; + +import EchoProps from '../components/EchoProps'; + +/* + * Export a function that takes the props and returns a ReactComponent. + * This is used for the client rendering hook after the page html is rendered. + * React will see that the state is the same and not do anything. + * Note, this is imported as "HelloWorldApp" by "clientRegistration.jsx" + * + * Note, this is a fictional example, as you'd only use a generator function if you wanted to run + * some extra code, such as setting up Redux and React-Router. + */ +export default (props, railsContext) => ( + +); diff --git a/spec/dummy/client/app/startup/ServerRenderedHtml.jsx b/spec/dummy/client/app/startup/ServerRenderedHtml.jsx new file mode 100644 index 000000000..4bb6f1a7b --- /dev/null +++ b/spec/dummy/client/app/startup/ServerRenderedHtml.jsx @@ -0,0 +1,21 @@ +// Top level component for simple client side only rendering +import React from 'react'; +import { renderToString } from 'react-dom/server' +import EchoProps from '../components/EchoProps'; + +/* + * Export a function that takes the props and returns an object with { renderedHtml } + * Note, this is imported as "RenderedHtml" by "serverRegistration.jsx" + * + * Note, this is a fictional example, as you'd only use a generator function if you wanted to run + * some extra code, such as setting up Redux and React-Router. + * + * And the use of renderToString would probably be done with react-router v4 + * + */ +export default (props, railsContext) => { + const renderedHtml = renderToString( + + ); + return { renderedHtml }; +}; diff --git a/spec/dummy/client/app/startup/clientRegistration.jsx b/spec/dummy/client/app/startup/clientRegistration.jsx index a72c78c83..4b4ad703d 100644 --- a/spec/dummy/client/app/startup/clientRegistration.jsx +++ b/spec/dummy/client/app/startup/clientRegistration.jsx @@ -16,6 +16,9 @@ import DeferredRenderApp from './DeferredRenderAppRenderer'; import SharedReduxStore from '../stores/SharedReduxStore'; +// Deferred render on the client side w/ server render +import RenderedHtml from './ClientRenderedHtml'; + ReactOnRails.setOptions({ traceTurbolinks: true, }); @@ -32,7 +35,8 @@ ReactOnRails.register({ CssModulesImagesFontsExample, ManualRenderApp, DeferredRenderApp, - CacheDisabled + CacheDisabled, + RenderedHtml, }); ReactOnRails.registerStore({ diff --git a/spec/dummy/client/app/startup/serverRegistration.jsx b/spec/dummy/client/app/startup/serverRegistration.jsx index d0db2f97c..5df515a62 100644 --- a/spec/dummy/client/app/startup/serverRegistration.jsx +++ b/spec/dummy/client/app/startup/serverRegistration.jsx @@ -29,6 +29,9 @@ import SharedReduxStore from '../stores/SharedReduxStore'; // Deferred render on the client side w/ server render import DeferredRenderApp from './DeferredRenderAppServer'; +// Deferred render on the client side w/ server render +import RenderedHtml from './ServerRenderedHtml'; + ReactOnRails.register({ HelloWorld, HelloWorldWithLogAndThrow, @@ -41,6 +44,7 @@ ReactOnRails.register({ PureComponent, CssModulesImagesFontsExample, DeferredRenderApp, + RenderedHtml, }); ReactOnRails.registerStore({ diff --git a/spec/dummy/config/routes.rb b/spec/dummy/config/routes.rb index 689a4a9b6..63855424b 100644 --- a/spec/dummy/config/routes.rb +++ b/spec/dummy/config/routes.rb @@ -28,4 +28,5 @@ get "pure_component" => "pages#pure_component" get "css_modules_images_fonts_example" => "pages#css_modules_images_fonts_example" get "turbolinks_cache_disabled" => "pages#turbolinks_cache_disabled" + get "rendered_html" => "pages#rendered_html" end diff --git a/spec/dummy/spec/features/integration_spec.rb b/spec/dummy/spec/features/integration_spec.rb index 87b1eb230..cb92cc1fb 100644 --- a/spec/dummy/spec/features/integration_spec.rb +++ b/spec/dummy/spec/features/integration_spec.rb @@ -176,6 +176,15 @@ def change_text_expect_dom_selector(dom_selector) end end +feature "renderedHtml from generator function", :js do + subject { page } + background { visit "/rendered_html" } + scenario "renderedHtml should not have any errors" do + expect(subject).to have_text "Props: {\"hello\":\"world\"}" + expect(subject.html).to include("[SERVER] RENDERED RenderedHtml to dom node with id") + end +end + shared_examples "React Component Shared Store" do |url| subject { page } background { visit url } From d57c731da7e04e8599e034cbe967882582f332cb Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Sat, 21 Jan 2017 12:06:28 -1000 Subject: [PATCH 24/42] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7450b3eee..cdd9a24d6 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ Follow [@ShakaCode](https://twitter.com/shakacode) for notications of new releas ### Videos 1. [egghead.io: Creating a component with React on Rails](https://egghead.io/lessons/react-creating-a-component-with-react-on-rails) +1. [egghead.io: Creating a redux component with React on Rails](https://egghead.io/lessons/react-add-redux-state-management-to-a-react-on-rails-project) 1. [React On Rails Tutorial Series](https://www.youtube.com/playlist?list=PL5VAKH-U1M6dj84BApfUtvBjvF-0-JfEU) 1. [History and Motivation](https://youtu.be/F4oymbUHvoY) 1. [Basic Tutorial Walkthrough](https://youtu.be/_bjScw60FBk) From 935d20e7f5e122aad7c5ca2835fdead3caad1813 Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Sat, 21 Jan 2017 15:15:00 -1000 Subject: [PATCH 25/42] Doc Changes for links on gitbook When making doc changes, we want the change to work on both the gitbook and the regular github site. The issue is that non-doc files will not go to the gitbook site, so doc references to non doc files must use the github URL. Links to other docs: * When making references to doc files, use a relative URL path like: `[Installation Overview](docs/basics/installation-overview.md)` * When making references to source code files, use a full url path like: `[spec/dummy/config/initializers/react_on_rails.rb](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/config/initializers/react_on_rails.rb)` --- CONTRIBUTING.md | 12 ++++++++++ README.md | 18 +++++++------- docs/additional-reading/code-splitting.md | 12 +++++----- .../hot-reloading-rails-development.md | 24 +++++++++---------- .../additional-reading/rspec-configuration.md | 2 +- 5 files changed, 40 insertions(+), 28 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8728793e7..1c1e68ce7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,6 +29,18 @@ From [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/ 1. Use the body to explain what and why vs. how +## Doc Changes + +When making doc changes, we want the change to work on both the gitbook and the regular github site. The issue is that non-doc files will not go to the gitbook site, so doc references to non doc files must use the github URL. + +### Links to other docs: +* When making references to doc files, use a relative URL path like: +`[Installation Overview](docs/basics/installation-overview.md)` + +* When making references to source code files, use a full url path like: +`[spec/dummy/config/initializers/react_on_rails.rb](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/config/initializers/react_on_rails.rb)` + + ## To run tests: * After updating code via git, to prepare all examples and run all tests: diff --git a/README.md b/README.md index cdd9a24d6..1941be345 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,7 @@ See the [Installation Overview](docs/basics/installation-overview.md) for a conc ### Initializer Configuration -Configure the `config/initializers/react_on_rails.rb`. You can adjust some necessary settings and defaults. See file [spec/dummy/config/initializers/react_on_rails.rb](spec/dummy/config/initializers/react_on_rails.rb) for a detailed example of configuration, including comments on the different values to configure. +Configure the `config/initializers/react_on_rails.rb`. You can adjust some necessary settings and defaults. See file [spec/dummy/config/initializers/react_on_rails.rb](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/config/initializers/react_on_rails.rb) for a detailed example of configuration, including comments on the different values to configure. ### Including your React Component in your Rails Views @@ -193,7 +193,7 @@ That will install the latest version and update your package.json. ## How it Works The generator installs your webpack files in the `client` folder. Foreman uses webpack to compile your code and output the bundled results to `app/assets/webpack`, which are then loaded by sprockets. These generated bundle files have been added to your `.gitignore` for your convenience. -Inside your Rails views, you can now use the `react_component` helper method provided by React on Rails. You can pass props directly to the react component helper. You can also initialize a Redux store with view or controller helper `redux_store` so that the store can be shared amongst multiple React components. See the docs for `redux_store` below and scan the code inside of the [/spec/dummy](spec/dummy) sample app. +Inside your Rails views, you can now use the `react_component` helper method provided by React on Rails. You can pass props directly to the react component helper. You can also initialize a Redux store with view or controller helper `redux_store` so that the store can be shared amongst multiple React components. See the docs for `redux_store` below and scan the code inside of the [/spec/dummy](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy) sample app. ### Client-Side Rendering vs. Server-Side Rendering In most cases, you should use the `prerender: false` (default behavior) with the provided helper method to render the React component from your Rails views. In some cases, such as when SEO is vital, or many users will not have JavaScript enabled, you can enable server-rendering by passing `prerender: true` to your helper, or you can simply change the default in `config/initializers/react_on_rails`. @@ -242,7 +242,7 @@ Note, you never make these calls. This is what React on Rails does when either s (Note, see below [section](#multiple-react-components-on-a-page-with-one-store) on how to setup redux stores that allow multiple components to talk to the same store.) -The `railsContext` has: (see implementation in file [react_on_rails_helper.rb](app/helpers/react_on_rails_helper.rb), method `rails_context` for the definitive list). +The `railsContext` has: (see implementation in file [react_on_rails_helper.rb](https://github.com/shakacode/react_on_rails/tree/master/app/helpers/react_on_rails_helper.rb), method `rails_context` for the definitive list). ```ruby { @@ -280,7 +280,7 @@ Set the config value for the `rendering_extension`: Implement it like this above in the same file. Create a class method on the module called `custom_context` that takes the `view_context` for a param. -See [spec/dummy/config/initializers/react_on_rails.rb](spec/dummy/config/initializers/react_on_rails.rb) for a detailed example. +See [spec/dummy/config/initializers/react_on_rails.rb](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/config/initializers/react_on_rails.rb) for a detailed example. ```ruby module RenderingExtension @@ -362,7 +362,7 @@ Include the module ReactOnRails::Controller in your controller, probably in Appl 2. In your component definition, you'll call `ReactOnRails.getStore('storeName')` to get the hydrated Redux store to attach to your components. + **props:** Named parameter `props`. ReactOnRails takes care of setting up the hydration of your store with props from the view. -For an example, see [spec/dummy/app/controllers/pages_controller.rb](spec/dummy/app/controllers/pages_controller.rb). Note, this is preferable to using the equivalent view_helper `redux_store` in that you can be assured that the store is initialized before your components. +For an example, see [spec/dummy/app/controllers/pages_controller.rb](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/app/controllers/pages_controller.rb). Note, this is preferable to using the equivalent view_helper `redux_store` in that you can be assured that the store is initialized before your components. #### View Helper `redux_store(store_name, props: {})` @@ -371,7 +371,7 @@ Same API as the controller extension. **HOWEVER**, we recommend the controller e `redux_store_hydration_data` -Place this view helper (no parameters) at the end of your shared layout. This tell ReactOnRails where to client render the redux store hydration data. Since we're going to be setting up the stores in the controllers, we need to know where on the view to put the client side rendering of this hydration data, which is a hidden div with a matching class that contains a data props. For an example, see [spec/dummy/app/views/layouts/application.html.erb](spec/dummy/app/views/layouts/application.html.erb). +Place this view helper (no parameters) at the end of your shared layout. This tell ReactOnRails where to client render the redux store hydration data. Since we're going to be setting up the stores in the controllers, we need to know where on the view to put the client side rendering of this hydration data, which is a hidden div with a matching class that contains a data props. For an example, see [spec/dummy/app/views/layouts/application.html.erb](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/app/views/layouts/application.html.erb). #### Redux Store Notes Note, you don't need to separately initialize your redux store. However, it's recommended for the two following use cases: @@ -466,11 +466,11 @@ If you are using [jquery-ujs](https://github.com/rails/jquery-ujs) for AJAX call [React Router](https://github.com/reactjs/react-router) is supported, including server side rendering! See: 1. [React on Rails docs for react-router](docs/additional-reading/react-router.md) -1. Examples in [spec/dummy/app/views/react_router](spec/dummy/app/views/react_router) and follow to the JavaScript code in the [spec/dummy/client/app/startup/ServerRouterApp.jsx](spec/dummy/client/app/startup/ServerRouterApp.jsx). +1. Examples in [spec/dummy/app/views/react_router](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/app/views/react_router) and follow to the JavaScript code in the [spec/dummy/client/app/startup/ServerRouterApp.jsx](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/client/app/startup/ServerRouterApp.jsx). 1. [Code Splitting docs](docs/additional-reading/code-splitting.md) for information about how to set up code splitting for server rendered routes. ## Deployment -* Version 6.0 puts the necessary precompile steps automatically in the rake precompile step. You can, however, disable this by setting certain values to nil in the [config/initializers/react_on_rails.rb](spec/dummy/config/initializers/react_on_rails.rb). +* Version 6.0 puts the necessary precompile steps automatically in the rake precompile step. You can, however, disable this by setting certain values to nil in the [config/initializers/react_on_rails.rb](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/config/initializers/react_on_rails.rb). * `config.symlink_non_digested_assets_regex`: Set to nil to turn off the setup of non-js assets. * `npm_build_production_command`: Set to nil to turn off the precompilation of the js assets. * See the [Heroku Deployment](docs/additional-reading/heroku-deployment.md) doc for specifics regarding Heroku. @@ -533,7 +533,7 @@ Node.js can be used as the backend for server-side rendering instead of [execJS] ## Demos + [www.reactrails.com](http://www.reactrails.com) with the source at [shakacode/react-webpack-rails-tutorial](https://github.com/shakacode/react-webpack-rails-tutorial/). -+ [spec app](spec/dummy): Great simple examples used for our tests. ++ [spec app](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy): Great simple examples used for our tests. ``` cd spec/dummy bundle && npm i diff --git a/docs/additional-reading/code-splitting.md b/docs/additional-reading/code-splitting.md index e57788d3e..30dad47c9 100644 --- a/docs/additional-reading/code-splitting.md +++ b/docs/additional-reading/code-splitting.md @@ -111,12 +111,12 @@ There's an implemented example of code splitting in the `spec/dummy` folder of t See: -- [spec/dummy/client/app/startup/clientRegistration.jsx](../../spec/dummy/client/app/startup/clientRegistration.jsx) -- [spec/dummy/client/app/startup/serverRegistration.jsx](../../spec/dummy/client/app/startup/serverRegistration.jsx) -- [spec/dummy/client/app/startup/DeferredRenderAppRenderer.jsx](../../spec/dummy/client/app/startup/DeferredRenderAppRenderer.jsx) <-- Code splitting implemented here -- [spec/dummy/client/app/startup/DeferredRenderAppServer.jsx](../../spec/dummy/client/app/startup/DeferredRenderAppServer.jsx) -- [spec/dummy/client/app/components/DeferredRender.jsx](../../spec/dummy/client/app/components/DeferredRender.jsx) -- [spec/dummy/client/app/components/DeferredRenderAsyncPage.jsx](../../spec/dummy/client/app/components/DeferredRenderAsyncPage.jsx) +- [spec/dummy/client/app/startup/clientRegistration.jsx](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/client/app/startup/clientRegistration.jsx) +- [spec/dummy/client/app/startup/serverRegistration.jsx](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/client/app/startup/serverRegistration.jsx) +- [spec/dummy/client/app/startup/DeferredRenderAppRenderer.jsx](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/client/app/startup/DeferredRenderAppRenderer.jsx) <-- Code splitting implemented here +- [spec/dummy/client/app/startup/DeferredRenderAppServer.jsx](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/client/app/startup/DeferredRenderAppServer.jsx) +- [spec/dummy/client/app/components/DeferredRender.jsx](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/client/app/components/DeferredRender.jsx) +- [spec/dummy/client/app/components/DeferredRenderAsyncPage.jsx](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/client/app/components/DeferredRenderAsyncPage.jsx) ### Caveats diff --git a/docs/additional-reading/hot-reloading-rails-development.md b/docs/additional-reading/hot-reloading-rails-development.md index 1e24e0ce8..b7d9eee8a 100644 --- a/docs/additional-reading/hot-reloading-rails-development.md +++ b/docs/additional-reading/hot-reloading-rails-development.md @@ -11,26 +11,26 @@ We'll use a Webpack Dev server on port 3500 to provide the assets to Rails, rath `Procfile.static` provides an alternative that uses "static" assets, similar to a production deployment. -The secret sauce is in the [app/views/layouts/application.html.erb](../../spec/dummy/app/views/layouts/application.html.erb) where it uses view helps to configure the correct assets to load, being either the "hot" assets or the "static" assets. +The secret sauce is in the [app/views/layouts/application.html.erb](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/app/views/layouts/application.html.erb) where it uses view helps to configure the correct assets to load, being either the "hot" assets or the "static" assets. ## Places to Configure (Files to Examine) 1. See the Webpack config files. Note, these examples are now setup for using [CSS Modules](https://github.com/css-modules/css-modules). - 1. [client/webpack.client.base.config.js](../../spec/dummy/client/webpack.client.base.config.js): Common configuration for hot or static assets. - 1. [client/webpack.client.rails.hot.config.js](../../spec/dummy/client/webpack.client.rails.hot.config.js): Setup for hot loading, using react-transform-hmr. - 1. [client/webpack.client.rails.build.config.js](../../spec/dummy/client/webpack.client.rails.build.config.js): Setup for static loading, as is done in a production deployment. -1. [app/views/layouts/application.html.erb](../../spec/dummy/app/views/layouts/application.html.erb): Uses the view helpers `env_stylesheet_link_tag` and `env_javascript_include_tag` which will either do the hot reloading or the static loading. -1. See the Procfiles: [Procfile.hot](../../spec/dummy/Procfile.hot) and [Procfile.static](../../spec/dummy/Procfile.static). These: + 1. [client/webpack.client.base.config.js](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/client/webpack.client.base.config.js): Common configuration for hot or static assets. + 1. [client/webpack.client.rails.hot.config.js](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/client/webpack.client.rails.hot.config.js): Setup for hot loading, using react-transform-hmr. + 1. [client/webpack.client.rails.build.config.js](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/client/webpack.client.rails.build.config.js): Setup for static loading, as is done in a production deployment. +1. [app/views/layouts/application.html.erb](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/app/views/layouts/application.html.erb): Uses the view helpers `env_stylesheet_link_tag` and `env_javascript_include_tag` which will either do the hot reloading or the static loading. +1. See the Procfiles: [Procfile.hot](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/Procfile.hot) and [Procfile.static](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/Procfile.static). These: 1. Start the webpack processes, depending on the mode or HOT or not. 2. Start the rails server, setting an ENV value of REACT_ON_RAILS_ENV to HOT if we're hot loading or else setting this to blank. 1. Configure the file Rails asset pipeline files: - 1. [app/assets/javascripts/application_static.js](../../spec/dummy/app/assets/javascripts/application_static.js) - 1. [app/assets/stylesheets/application_static.css.scss](../../spec/dummy/app/assets/stylesheets/application_static.css.scss) -1. Be sure your [config/initializers/assets.rb](../../spec/dummy/config/initializers/assets.rb) is configured to include the webpack generated files. -1. Copy the [client/server-rails-hot.js](../../spec/dummy/client/server-rails-hot.js) to the your client directory. + 1. [app/assets/javascripts/application_static.js](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/app/assets/javascripts/application_static.js) + 1. [app/assets/stylesheets/application_static.css.scss](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/app/assets/stylesheets/application_static.css.scss) +1. Be sure your [config/initializers/assets.rb](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/config/initializers/assets.rb) is configured to include the webpack generated files. +1. Copy the [client/server-rails-hot.js](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/client/server-rails-hot.js) to the your client directory. 1. Copy the scripts in the top level and client level `package.json` files: - 1. Top Level: [package.json](../../spec/dummy/package.json) - 1. Client Level: [package.json](../../spec/dummy/client/package.json) + 1. Top Level: [package.json](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/package.json) + 1. Client Level: [package.json](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/client/package.json) ## Code Snippets diff --git a/docs/additional-reading/rspec-configuration.md b/docs/additional-reading/rspec-configuration.md index 4465ce69c..24626b6c7 100644 --- a/docs/additional-reading/rspec-configuration.md +++ b/docs/additional-reading/rspec-configuration.md @@ -40,7 +40,7 @@ If you want to speed up the re-compiling process, you can call `npm run build:de }, ``` -[spec/dummy](../../spec/dummy) contains examples of how to set the proc files for this purpose. +[spec/dummy](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy) contains examples of how to set the proc files for this purpose. ## Hot Reloading If you're using the hot reloading setup, you'll be running a Webpack development server to provide the JavaScript and mabye CSS assets to your Rails app. If you're doing server rendering, you'll also have a webpack watch process to refresh the server rendering file. **If your server and client bundles are different**, and you run specs, the client bundle files will not be created until React on Rails detects it's out of date. Then your script to create all bundle files will redo the server bundle file. There's a few simple remedies for this situation: From 3f84aa854f018f9bdc269b9382075ab48b6e2a4f Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Sun, 22 Jan 2017 15:26:16 -1000 Subject: [PATCH 26/42] Update PROJECTS.md --- PROJECTS.md | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/PROJECTS.md b/PROJECTS.md index b0eb3cf00..1f5ba6296 100644 --- a/PROJECTS.md +++ b/PROJECTS.md @@ -4,11 +4,13 @@ ## Commercial Products Live * **[Friends and Guests](https://www.friendsandguests.com/)**, the signature product of [ShakaCode](http://www.shakacode.com), which is a "Network Connecting Hosts and Guests". +* **[Nootrobox](https://nootrobox.com)**: Web ecommerce site for "biohacking" products. +* **[GuavaPass](https://guavapass.com/)**: Coaching client of [ShakaCode](http://www.shakacode.com) and React on Rails fan! +* **[Pivotal Tracker](http://www.pivotaltracker.com/)**: The first (and most-loved) agile project management tool built on Rails. React on Rails has greatly simplified integration and workflow for our React components in Rails! * **[Blink Inc](https://www.blinkinc.com)**: Website and more built by [ShakaCode](http://www.shakacode.com). * **[Madrone Analytics](http://madroneco.com/)**: The original client of [ShakaCode](http://www.shakacode.com) that led to the development of React on Rails, as described in [Fast Rich Client Rails Development With Webpack and the ES6 Transpiler](http://www.railsonmaui.com/blog/2014/10/03/integrating-webpack-and-the-es6-transpiler-into-an-existing-rails-project/). * **[Deliveroo](https://deliveroo.co.uk/)**: The leading food delivery site in Europe has gone live with React on Rails, with multi-lingual JavaScript support! ![2016-05-03_19-18-34](https://cloud.githubusercontent.com/assets/1118459/15027253/91fd151a-11de-11e6-93e3-720518995fe0.png) -* **[Nootrobox](https://nootrobox.com)**: Web ecommerce site for "biohacking" products. * **[Airgoat](https://airgoat.com/)**: Marketplace for sneakers. * **[Apprentus](https://www.apprentus.com/)**: A marketplace to find the best private teachers. Using react-on-rails from the homepage to infinity! * **[Confident Financial Solutions](https://www.mycfsapp.com/)**: Auto Repair Financing to help people get back on the road and back to life. @@ -16,14 +18,6 @@ * **[Undeveloped](https://undeveloped.com/)**: Buy and sell domain names. ![image](https://cloud.githubusercontent.com/assets/1118459/19623703/7c6d63d0-9870-11e6-83f2-8b83ca49daa9.png) * **[Foxford.ru](http://foxford.ru/)**: Online School ![2016-12-17_13-23-21](https://cloud.githubusercontent.com/assets/1118459/21290377/1adacdf2-c45c-11e6-97c1-f726ab749b2d.png) - -## Commercial Products in Development -* **[GuavaPass](https://guavapass.com/)**: Coaching client of [ShakaCode](http://www.shakacode.com) and React on Rails fan! -* **[Pivotal Tracker](http://www.pivotaltracker.com/)**: The first (and most-loved) agile project management tool built on Rails. React on Rails has greatly simplified integration and workflow for our React components in Rails! - - --------- - ## Demos and Tutorials * [reactrails.com](http://www.reactrails.com), source code [github.com/shakacode/react-webpack-rails-tutorial](https://github.com/shakacode/react-webpack-rails-tutorial/) * [Relay Rails Blog](https://github.com/gauravtiwari/relay-rails-blog): Tutorial to learn Relay with Rails. From ea69e3cb24646c834036a524ae6558adf444b751 Mon Sep 17 00:00:00 2001 From: Alexey Mahotkin Date: Fri, 27 Jan 2017 10:04:47 +0100 Subject: [PATCH 27/42] Small fixes to achieve reproducible build (#661) * Typo in 'npm run dummy:spec' * 'babel' package is deprecated, remove from dependencies * Mention that 'react-dom' also needs to be in webpack.conf; fix typo --- CONTRIBUTING.md | 4 ++-- .../react_on_rails/templates/base/base/client/package.json.tt | 1 - spec/dummy/client/package.json | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1c1e68ce7..8baab32c1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -98,7 +98,7 @@ npm install --save "react-on-rails@../../react_on_rails" When you use a relative path, be sure to run the above `npm install` command whenever you change the node package for react-on-rails. -Wihle we'd prefer to us `npm link`, we get errors. If you can figure out how to get `npm link react-on-rails` to work with this project, please file an issue or PR! This used to work with babel 5. +While we'd prefer to use `npm link`, we get errors. If you can figure out how to get `npm link react-on-rails` to work with this project, please file an issue or PR! This used to work with babel 5. This is the error: @@ -174,7 +174,7 @@ spec/dummy. # Optionally change default selenium_firefox driver export DRIVER=poltergeist cd -npm dummy:spec +npm run dummy:spec ``` ### Run NPM JS tests diff --git a/lib/generators/react_on_rails/templates/base/base/client/package.json.tt b/lib/generators/react_on_rails/templates/base/base/client/package.json.tt index b785e9e58..60bda3b4f 100644 --- a/lib/generators/react_on_rails/templates/base/base/client/package.json.tt +++ b/lib/generators/react_on_rails/templates/base/base/client/package.json.tt @@ -14,7 +14,6 @@ }, "cacheDirectories": ["node_modules", "client/node_modules"], "dependencies": { - "babel": "^6.5.2", "babel-cli": "^6.18.0", "babel-core": "^6.21.0", "babel-loader": "^6.2.10", diff --git a/spec/dummy/client/package.json b/spec/dummy/client/package.json index 289d9c581..3fa95b812 100644 --- a/spec/dummy/client/package.json +++ b/spec/dummy/client/package.json @@ -9,7 +9,6 @@ "main": "js/app.js", "dependencies": { "autoprefixer": "^6.6.1", - "babel": "^6.5.2", "babel-cli": "^6.18.0", "babel-core": "^6.21.0", "babel-loader": "^6.2.10", From 9003e8689f64fba0fc1c6b968565a965b76e5eea Mon Sep 17 00:00:00 2001 From: Xavier Riley Date: Sat, 28 Jan 2017 07:24:10 +0000 Subject: [PATCH 28/42] Remove reference to heroku-buildpack-multi (#698) `heroku buildpacks:add ...` will support any custom buildpacks - there's no use case for using `heroku-buildpack-multi` unless you are relying on a `.buildpacks` file to be present in the repo (which some older projects do). In addition, https://github.com/ddollar/heroku-buildpack-multi is deprecated and is no longer being maintained. There is a maintained fork of the project at https://github.com/heroku/heroku-buildpack-multi but it isn't necessary to point people to this. --- docs/additional-reading/heroku-deployment.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/additional-reading/heroku-deployment.md b/docs/additional-reading/heroku-deployment.md index 542b43725..1e791277b 100644 --- a/docs/additional-reading/heroku-deployment.md +++ b/docs/additional-reading/heroku-deployment.md @@ -47,8 +47,6 @@ heroku buildpacks:add --index 1 heroku/nodejs For more information, see [Using Multiple Buildpacks for an App](https://devcenter.heroku.com/articles/using-multiple-buildpacks-for-an-app) -If for some reason you need custom buildpacks that are not officially supported by Heroku ([see this page](https://devcenter.heroku.com/articles/buildpacks)), we recommend checking out [heroku-buildpack-multi](https://github.com/ddollar/heroku-buildpack-multi). - ## Fresh Rails Install ### Swap out sqlite for postgres by doing the following: From 1058bf4e62a8f7cf3c64eec417aad14d496085ec Mon Sep 17 00:00:00 2001 From: nostophilia Date: Wed, 18 Jan 2017 22:06:05 +0800 Subject: [PATCH 29/42] Fix incorrect "this" references of Node.js SSR --- CHANGELOG.md | 5 +- .../node-server-rendering.md | 117 +++++++++++------- .../templates/node/base/client/node/server.js | 76 ++++++------ 3 files changed, 111 insertions(+), 87 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4ee209a0..a3186f988 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,13 @@ All notable changes to this project's source code will be documented in this fil Contributors: please follow the recommendations outlined at [keepachangelog.com](http://keepachangelog.com/). Please use the existing headings and styling as a guide, and add a link for the version diff at the bottom of the file. Also, please update the `Unreleased` link to compare to the latest release version. ## [Unreleased] -*Please add entries here for your pull requests.* +### Fixed +- Fix incorrect "this" references of Node.js SSR [#690] by [nostophilia](https://github.com/nostophilia) ## [6.4.0] - 2017-1-12 ### Possible Breaking Change -- Since foreman is no longer a dependency of the React on Rails gem, please run `gem install foreman`. If you are using rvm, you may wish to run `rvm @global do gem install foreman` to install foreman for all your gemsets. +- Since foreman is no longer a dependency of the React on Rails gem, please run `gem install foreman`. If you are using rvm, you may wish to run `rvm @global do gem install foreman` to install foreman for all your gemsets. ### Fixed - Removed foreman as a dependency. [#678](https://github.com/shakacode/react_on_rails/pull/678) by [x2es](https://github.com/x2es). diff --git a/docs/additional-reading/node-server-rendering.md b/docs/additional-reading/node-server-rendering.md index a90b0fd56..68b0c5c53 100644 --- a/docs/additional-reading/node-server-rendering.md +++ b/docs/additional-reading/node-server-rendering.md @@ -39,7 +39,7 @@ You need to configure the name of the server bundle in two places: # If you are using the same file for client and server rendering, having this set probably does # not affect performance. config.server_bundle_js_file = "webpack-bundle.js" -``` +``` And in `client/node/package.json` @@ -61,79 +61,102 @@ And you'll need this file: `client/node/server.js` ```javascript // client/node/server.js -var net = require('net'); -var fs = require('fs'); - -var bundlePath = '../../app/assets/webpack/'; -var bundleFileName = 'webpack-bundle.js'; +const net = require('net'); +const fs = require('fs'); -var currentArg; +const bundlePath = '../../app/assets/webpack/'; +let bundleFileName = 'server-bundle.js'; -function Handler() { - this.queue = []; - this.initialized = false; -} +let currentArg; -Handler.prototype.handle = function (connection) { - var callback = function () { - connection.setEncoding('utf8'); - connection.on('data', (data)=> { - console.log('Processing request: ' + data); - var result = eval(data); - connection.write(result); - }); - }; - - if (this.initialized) { - callback(); - } else { - this.queue.push(callback); +class Handler { + constructor() { + this.queue = []; + this.initialized = false; } -}; -Handler.prototype.initialize = function () { - console.log('Processing ' + this.queue.length + ' pending requests'); - var callback; - while (callback = this.queue.pop()) { - callback(); + initialize() { + console.log(`Processing ${this.queue.length} pending requests`); + let callback; + + // eslint-disable-next-line no-cond-assign + while (callback = this.queue.pop()) { + callback(); + } + + this.initialized = true; } - this.initialized = true; -}; + handle(connection) { + const callback = () => { + const terminator = '\r\n\0'; + let request = ''; + connection.setEncoding('utf8'); + connection.on('data', (data) => { + console.log(`Processing chunk: ${data}`); + request += data; + if (data.slice(-terminator.length) === terminator) { + request = request.slice(0, -terminator.length); + + // eslint-disable-next-line no-eval + const response = eval(request); + connection.write(`${response}${terminator}`); + request = ''; + } + }); + }; + + if (this.initialized) { + callback(); + } else { + this.queue.push(callback); + } + } +} -var handler = new Handler(); +const handler = new Handler(); process.argv.forEach((val) => { - if (val[0] == '-') { + if (val[0] === '-') { currentArg = val.slice(1); return; } - if (currentArg == 's') { + if (currentArg === 's') { bundleFileName = val; } }); +function loadBundle() { + if (handler.initialized) { + console.log('Reloading server bundle must be implemented by restarting the node process!'); + return; + } + + /* eslint-disable */ + require(bundlePath + bundleFileName); + /* eslint-enable */ + console.log(`Loaded server bundle: ${bundlePath}${bundleFileName}`); + handler.initialize(); +} + try { fs.mkdirSync(bundlePath); } catch (e) { - if (e.code != 'EEXIST') throw e; + if (e.code !== 'EEXIST') { + throw e; + } else { + loadBundle(); + } } fs.watchFile(bundlePath + bundleFileName, (curr) => { if (curr && curr.blocks && curr.blocks > 0) { - if (handler.initialized) { - console.log('Reloading server bundle must be implemented by restarting the node process!'); - return; - } - - require(bundlePath + bundleFileName); - console.log('Loaded server bundle: ' + bundlePath + bundleFileName); - handler.initialize(); + loadBundle(); } }); -var unixServer = net.createServer(function (connection) { +const unixServer = net.createServer((connection) => { handler.handle(connection); }); @@ -143,6 +166,4 @@ process.on('SIGINT', () => { unixServer.close(); process.exit(); }); - ``` - diff --git a/lib/generators/react_on_rails/templates/node/base/client/node/server.js b/lib/generators/react_on_rails/templates/node/base/client/node/server.js index c50218ab8..bb57bc194 100644 --- a/lib/generators/react_on_rails/templates/node/base/client/node/server.js +++ b/lib/generators/react_on_rails/templates/node/base/client/node/server.js @@ -6,48 +6,50 @@ let bundleFileName = 'server-bundle.js'; let currentArg; -function Handler() { - this.queue = []; - this.initialized = false; -} - -Handler.prototype.handle = (connection) => { - const callback = () => { - const terminator = '\r\n\0'; - let request = ''; - connection.setEncoding('utf8'); - connection.on('data', (data) => { - console.log(`Processing chunk: ${data}`); - request += data; - if (data.slice(-terminator.length) === terminator) { - request = request.slice(0, -terminator.length); - - // eslint-disable-next-line no-eval - const response = eval(request); - connection.write(`${response}${terminator}`); - request = ''; - } - }); - }; - - if (this.initialized) { - callback(); - } else { - this.queue.push(callback); +class Handler { + constructor() { + this.queue = []; + this.initialized = false; } -}; -Handler.prototype.initialize = () => { - console.log(`Processing ${this.queue.length} pending requests`); - let callback; + initialize() { + console.log(`Processing ${this.queue.length} pending requests`); + let callback; - // eslint-disable-next-line no-cond-assign - while (callback = this.queue.pop()) { - callback(); + // eslint-disable-next-line no-cond-assign + while (callback = this.queue.pop()) { + callback(); + } + + this.initialized = true; } - this.initialized = true; -}; + handle(connection) { + const callback = () => { + const terminator = '\r\n\0'; + let request = ''; + connection.setEncoding('utf8'); + connection.on('data', (data) => { + console.log(`Processing chunk: ${data}`); + request += data; + if (data.slice(-terminator.length) === terminator) { + request = request.slice(0, -terminator.length); + + // eslint-disable-next-line no-eval + const response = eval(request); + connection.write(`${response}${terminator}`); + request = ''; + } + }); + }; + + if (this.initialized) { + callback(); + } else { + this.queue.push(callback); + } + } +} const handler = new Handler(); From 522ef97b4fe954612f8f88d4b76e9c5a9b964e5a Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Mon, 30 Jan 2017 12:59:10 -1000 Subject: [PATCH 30/42] Update README.md --- README.md | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4a0f7b680..8c794b790 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,24 @@ I'm offering a free half-hour project consultation, on anything from React on Ra Whether you have a new project or need help on an existing project, feel free to contact me directly at [justin@shakacode.com](mailto:justin@shakacode.com) and thanks in advance for any referrals! -Your support keeps this project going. +Your support keeps this project going! + +(Want to become a contributor? [Contact us](mailto:contact@shakacode.com) for a Slack room invite and let us know that you want to contribute.) + +# Community +Please [Subscribe](https://app.mailerlite.com/webforms/landing/l1d9x5) to keep in touch with Justin Gordon and [ShakaCode](http://www.shakacode.com/). I intend to send a monthly summary including announcements of new releases of React on Rails and of our latest [blog articles](https://blog.shakacode.com) and tutorials. Subscribers will also have access to **exclusive content**, including tips and examples. -(Want to become a contributor? [Contact us](mailto:contact@shakacode.com) for a Slack team invite! Also, see ["easy" issues](https://github.com/shakacode/react_on_rails/labels/easy) and [issues for the full tutorial](https://github.com/shakacode/react-webpack-rails-tutorial/issues?q=is%3Aissue+is%3Aopen+label%3Aeasy +[![2017-01-30_12-33-52](https://cloud.githubusercontent.com/assets/1118459/22444904/191f32b4-e6e9-11e6-9c52-ab7000529474.png)](https://app.mailerlite.com/webforms/landing/l1d9x5) -Follow [@ShakaCode](https://twitter.com/shakacode) for notications of new releases. +* **Slack Room**: [Contact us](mailto:contact@shakacode.com) for an invite to the ShakaCode Slack room! +* **[forum.shakacode.com](https://forum.shakacode.com): Post your questions +* **[@ShakaCode on Twitter](https://twitter.com/shakacode)** + +# Testimonials +From Joel Hooks, Co-Founder, Chief Nerd at [egghead.io](https://egghead.io/), January 30, 2017: +![2017-01-30_11-33-59](https://cloud.githubusercontent.com/assets/1118459/22443635/b3549fb4-e6e3-11e6-8ea2-6f589dc93ed3.png) + +For more testimonials, see [Live Projects](PROJECTS.md) and [Kudos](./KUDOS.md). # Articles, Videos, and Podcasts @@ -567,6 +580,9 @@ We owe much gratitude to the work of the [react-rails gem](https://github.com/re # FINAL NOTES * See [Projects](PROJECTS.md) using and [KUDOS](./KUDOS.md) for React on Rails. Please submit yours! Please edit either page or [email us](mailto:contact@shakacode.com) and we'll add your info. We also **love stars** as it helps us attract new users and contributors. * Follow [@railsonmaui](https://twitter.com/railsonmaui) and [@shakacode](https://twitter.com/shakacode) on Twitter for updates on releases. We've also got a forum category dedicated to [react_on_rails](https://forum.shakacode.com/c/rails/reactonrails). +* Please [Subscribe](https://app.mailerlite.com/webforms/landing/l1d9x5) to keep in touch with Justin Gordon and [ShakaCode](http://www.shakacode.com/). I intend to send a monthly summary including announcements of new releases of React on Rails and of our latest [blog articles](https://blog.shakacode.com) and tutorials. Subscribers will also have access to **exclusive content**, including tips and examples. + +[![2017-01-30_12-33-52](https://cloud.githubusercontent.com/assets/1118459/22444904/191f32b4-e6e9-11e6-9c52-ab7000529474.png)](https://app.mailerlite.com/webforms/landing/l1d9x5) --- From fa7233ec6375900585be14c296e410b2327acd75 Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Mon, 30 Jan 2017 12:59:42 -1000 Subject: [PATCH 31/42] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8c794b790..3052dce02 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Please [Subscribe](https://app.mailerlite.com/webforms/landing/l1d9x5) to keep i [![2017-01-30_12-33-52](https://cloud.githubusercontent.com/assets/1118459/22444904/191f32b4-e6e9-11e6-9c52-ab7000529474.png)](https://app.mailerlite.com/webforms/landing/l1d9x5) * **Slack Room**: [Contact us](mailto:contact@shakacode.com) for an invite to the ShakaCode Slack room! -* **[forum.shakacode.com](https://forum.shakacode.com): Post your questions +* **[forum.shakacode.com](https://forum.shakacode.com)**: Post your questions * **[@ShakaCode on Twitter](https://twitter.com/shakacode)** # Testimonials From 60960186b4f318513b3b4e2f8cb875ab1f7d938d Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Tue, 31 Jan 2017 14:19:34 -1000 Subject: [PATCH 32/42] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3052dce02..d2d652815 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Your support keeps this project going! # Community Please [Subscribe](https://app.mailerlite.com/webforms/landing/l1d9x5) to keep in touch with Justin Gordon and [ShakaCode](http://www.shakacode.com/). I intend to send a monthly summary including announcements of new releases of React on Rails and of our latest [blog articles](https://blog.shakacode.com) and tutorials. Subscribers will also have access to **exclusive content**, including tips and examples. -[![2017-01-30_12-33-52](https://cloud.githubusercontent.com/assets/1118459/22444904/191f32b4-e6e9-11e6-9c52-ab7000529474.png)](https://app.mailerlite.com/webforms/landing/l1d9x5) +[![2017-01-31_14-16-56](https://cloud.githubusercontent.com/assets/1118459/22490211/f7a70418-e7bf-11e6-9bef-b3ccd715dbf8.png)](https://app.mailerlite.com/webforms/landing/l1d9x5) * **Slack Room**: [Contact us](mailto:contact@shakacode.com) for an invite to the ShakaCode Slack room! * **[forum.shakacode.com](https://forum.shakacode.com)**: Post your questions @@ -582,7 +582,7 @@ We owe much gratitude to the work of the [react-rails gem](https://github.com/re * Follow [@railsonmaui](https://twitter.com/railsonmaui) and [@shakacode](https://twitter.com/shakacode) on Twitter for updates on releases. We've also got a forum category dedicated to [react_on_rails](https://forum.shakacode.com/c/rails/reactonrails). * Please [Subscribe](https://app.mailerlite.com/webforms/landing/l1d9x5) to keep in touch with Justin Gordon and [ShakaCode](http://www.shakacode.com/). I intend to send a monthly summary including announcements of new releases of React on Rails and of our latest [blog articles](https://blog.shakacode.com) and tutorials. Subscribers will also have access to **exclusive content**, including tips and examples. -[![2017-01-30_12-33-52](https://cloud.githubusercontent.com/assets/1118459/22444904/191f32b4-e6e9-11e6-9c52-ab7000529474.png)](https://app.mailerlite.com/webforms/landing/l1d9x5) +[![2017-01-31_14-16-56](https://cloud.githubusercontent.com/assets/1118459/22490211/f7a70418-e7bf-11e6-9bef-b3ccd715dbf8.png)](https://app.mailerlite.com/webforms/landing/l1d9x5) --- From 11690c84d0fd7896ddee0c53f0d0aca6e440a85e Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Tue, 31 Jan 2017 15:07:11 -1000 Subject: [PATCH 33/42] Updated CHANGELOG.md --- CHANGELOG.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 33df04da1..2f1824bbe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,16 @@ All notable changes to this project's source code will be documented in this fil Contributors: please follow the recommendations outlined at [keepachangelog.com](http://keepachangelog.com/). Please use the existing headings and styling as a guide, and add a link for the version diff at the bottom of the file. Also, please update the `Unreleased` link to compare to the latest release version. ## [Unreleased] +*Please add entries here for your pull requests.* + +## [6.5.0] - 2017-01-31 +### Added +- Allow generator function to return Object with property `renderedHtml` (already could return Object with props `redirectLocation, error`) rather than a React component or a function that returns a React component. One reason to use a generator function is that sometimes in server rendering, specifically with React Router v4, you need to return the result of calling ReactDOMServer.renderToString(element). [#689](https://github.com/shakacode/react_on_rails/issues/689) by [justin808](https://github.com/justin808). + ### Fixed -- Fix incorrect "this" references of Node.js SSR [#690] by [nostophilia](https://github.com/nostophilia) +- Fix incorrect "this" references of Node.js SSR [#690](https://github.com/shakacode/react_on_rails/issues/689) by [nostophilia](https://github.com/nostophilia). -## [6.4.2] - 2017-1-17 +## [6.4.2] - 2017-01-17 ### Fixed - Added OS detection for install generator, system call for Windows and unit-tests for it. [#666](https://github.com/shakacode/react_on_rails/pull/666) by [GeorgeGorbanev](https://github.com/GeorgeGorbanev). @@ -436,7 +442,8 @@ Best done with Object destructing: ##### Fixed - Fix several generator related issues. -[Unreleased]: https://github.com/shakacode/react_on_rails/compare/6.4.2...master +[Unreleased]: https://github.com/shakacode/react_on_rails/compare/6.5.0...master +[6.5.0]: https://github.com/shakacode/react_on_rails/compare/6.4.2...6.5.0 [6.4.2]: https://github.com/shakacode/react_on_rails/compare/6.4.1...6.4.2 [6.4.1]: https://github.com/shakacode/react_on_rails/compare/6.4.0...6.4.1 [6.4.0]: https://github.com/shakacode/react_on_rails/compare/6.3.5...6.4.0 From 0594062b4cb158924add015b338d298e70eff413 Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Tue, 31 Jan 2017 15:08:44 -1000 Subject: [PATCH 34/42] Release 6.5.0 --- lib/react_on_rails/version.rb | 2 +- package.json | 2 +- spec/dummy/Gemfile.lock | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/react_on_rails/version.rb b/lib/react_on_rails/version.rb index a62325a86..106a1dff8 100644 --- a/lib/react_on_rails/version.rb +++ b/lib/react_on_rails/version.rb @@ -1,4 +1,4 @@ # frozen_string_literal: true module ReactOnRails - VERSION = "6.4.2".freeze + VERSION = "6.5.0".freeze end diff --git a/package.json b/package.json index 550360feb..7f9db8fa5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-on-rails", - "version": "6.4.2", + "version": "6.5.0", "description": "react-on-rails JavaScript for react_on_rails Ruby gem", "main": "node_package/lib/ReactOnRails.js", "directories": { diff --git a/spec/dummy/Gemfile.lock b/spec/dummy/Gemfile.lock index 66846c365..4e38ff277 100644 --- a/spec/dummy/Gemfile.lock +++ b/spec/dummy/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: ../.. specs: - react_on_rails (6.4.2) + react_on_rails (6.5.0) addressable connection_pool execjs (~> 2.5) From 35412ba9c98ceb29b331a9844c29c4e69306dbc4 Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Tue, 31 Jan 2017 19:43:34 -1000 Subject: [PATCH 35/42] Small formatting tweak --- node_package/src/clientStartup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node_package/src/clientStartup.js b/node_package/src/clientStartup.js index 5bb8b4dfc..15d01d0e4 100644 --- a/node_package/src/clientStartup.js +++ b/node_package/src/clientStartup.js @@ -121,7 +121,7 @@ You should return a React.Component always for the client side entry point.`); } } } catch (e) { - e.message = `ReactOnRails encountered an error while rendering component: ${name}.` + + e.message = `ReactOnRails encountered an error while rendering component: ${name}.\n` + `Original message: ${e.message}`; throw e; } From 75cf8106e6d7660da7d5283a274245ecdd5fae62 Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Tue, 7 Feb 2017 16:55:15 -1000 Subject: [PATCH 36/42] Update i18n.md --- docs/basics/i18n.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/basics/i18n.md b/docs/basics/i18n.md index f3a96df4e..12a29f78f 100644 --- a/docs/basics/i18n.md +++ b/docs/basics/i18n.md @@ -2,7 +2,7 @@ Here's a summary of adding the I18n functionality. -You can refer to [react-webpack-rails-tutorial](https://github.com/shakacode/react-webpack-rails-tutorial) for a complete example. +You can refer to [react-webpack-rails-tutorial](https://github.com/shakacode/react-webpack-rails-tutorial) and [PR #340](https://github.com/shakacode/react-webpack-rails-tutorial/pull/340) for a complete example. 1. Add `react-intl` & `intl` to `client/package.json`, and remember to `bundle && npm install`. From d4e47c6a21067a447fbd245c347b6ea01a21f237 Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Thu, 9 Feb 2017 20:02:41 -1000 Subject: [PATCH 37/42] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d2d652815..38f916b68 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ We're definitely not doing that. With react_on_rails, webpack is mainly generati gem "react_on_rails", "~> 6" ``` -2. Commit this to git (you cannot run the generator unless you do this). +2. Commit this to git (you cannot run the generator unless you do this or pass the option `--ignore-warnings`). 3. See help for the generator: From 4badd571ccc1fa4416a441134595a9a287d432a1 Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Thu, 9 Feb 2017 20:09:30 -1000 Subject: [PATCH 38/42] Update generator.md --- docs/basics/generator.md | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/docs/basics/generator.md b/docs/basics/generator.md index 97471b7ea..476f85533 100644 --- a/docs/basics/generator.md +++ b/docs/basics/generator.md @@ -1,7 +1,6 @@ - [Generator](#generator) - [Understanding the Organization of the Generated Client Code](#understanding-the-organization-of-the-generated-client-code) - [Redux](#redux) - - [Multiple React Components on a Page with One Store](#multiple-react-components-on-a-page-with-one-store) - [Using Images and Fonts](#using-images-and-fonts) The `react_on_rails:install` generator combined with the example pull requests of generator runs will get you up and running efficiently. There's a fair bit of setup with integrating Webpack with Rails. Defaults for options are such that the default is for the flag to be off. For example, the default for `-R` is that `redux` is off, and the default of `-b` is that `skip-bootstrap` is off. @@ -13,7 +12,9 @@ Usage: rails generate react_on_rails:install [options] Options: - -R, [--redux], [--no-redux] # Install Redux gems and Redux version of Hello World Example + -R, [--redux], [--no-redux] # Install Redux gems and Redux version of Hello World Example. Default: false + -N, [--node], [--no-node] # Sets up node as a server rendering option. Default: false + [--ignore-warnings], [--no-ignore-warnings] # Skip warnings. Default: false Runtime options: -f, [--force] # Overwrite files that already exist @@ -22,10 +23,36 @@ Runtime options: -s, [--skip], [--no-skip] # Skip files that already exist Description: - Create react on rails files for install generator. + +The react_on_rails:install generator integrates webpack with rails with ease. You +can pass the redux option if you'd like to have redux setup for you automatically. + +* Redux + + Passing the --redux generator option causes the generated Hello World example + to integrate the Redux state container framework. The necessary node modules + will be automatically included for you. + +* Node + + Passing the --node generator option sets up the necessary files for node to render the react_components. + +******************************************************************************* + +After running the generator, you will want to: + + bundle && npm i + +Then you may run + + foreman start -f Procfile.dev + +More Details: + + `https://github.com/shakacode/react_on_rails/blob/master/docs/basics/generator.md` ``` -For a clear example of what each generator option will do, see our generator results repo: [Generator Results](https://github.com/shakacode/react_on_rails-generator-results/blob/master/README.md). Each pull request shows a git "diff" that highlights the changes that the generator has made. Another good option is to create a simple test app per the [Tutorial](docs/tutorial.md). +Another good option is to create a simple test app per the [Tutorial](docs/tutorial.md). ### Understanding the Organization of the Generated Client Code The generated client code follows our organization scheme. Each unique set of functionality, is given its own folder inside of `client/app/bundles`. This encourages for modularity of *domains*. From 7ad5c1392004b9f326aadb13bf10746ba6495e1b Mon Sep 17 00:00:00 2001 From: Sergey Zyablitsky Date: Sat, 11 Feb 2017 16:49:26 +1000 Subject: [PATCH 39/42] Change Turbolinks unmount event from before-visit to before-render (#709) * change turbolinks unmount event from before-visit to before-render * Addresses #706 --- CHANGELOG.md | 2 ++ docs/additional-reading/turbolinks.md | 2 +- docs/api/javascript-api.md | 2 +- node_package/src/clientStartup.js | 4 ++-- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f1824bbe..84bf1e729 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ Contributors: please follow the recommendations outlined at [keepachangelog.com] ## [Unreleased] *Please add entries here for your pull requests.* +### Fixed +- Fixed issue [#706](https://github.com/shakacode/react_on_rails/issues/706) with "flickering" components when they are unmounted too early [#709](https://github.com/shakacode/react_on_rails/pull/709) by [szyablitsky](https://github.com/szyablitsky) ## [6.5.0] - 2017-01-31 ### Added diff --git a/docs/additional-reading/turbolinks.md b/docs/additional-reading/turbolinks.md index 725ea7564..7b8adb0da 100644 --- a/docs/additional-reading/turbolinks.md +++ b/docs/additional-reading/turbolinks.md @@ -94,7 +94,7 @@ TURBO: reactOnRailsPageLoaded Turbolinks 5: ``` -TURBO: WITH TURBOLINKS 5: document turbolinks:before-cache and turbolinks:load handlers installed. (program) +TURBO: WITH TURBOLINKS 5: document turbolinks:before-render and turbolinks:load handlers installed. (program) TURBO: reactOnRailsPageLoaded ``` diff --git a/docs/api/javascript-api.md b/docs/api/javascript-api.md index 104f5f954..5a4a68201 100644 --- a/docs/api/javascript-api.md +++ b/docs/api/javascript-api.md @@ -6,7 +6,7 @@ The best source of docs is the main [ReactOnRails.js](../../node_package/src/Rea * Main entry point to using the react-on-rails npm package. This is how Rails will be able to * find you components for rendering. Components get called with props, or you may use a * "generator function" to return a React component or an object with the following shape: - * { renderedHtml, redirectLocation, error }. + * { renderedHtml, redirectLocation, error }. * @param components (key is component name, value is component) */ register(components) diff --git a/node_package/src/clientStartup.js b/node_package/src/clientStartup.js index 15d01d0e4..f3eb4848e 100644 --- a/node_package/src/clientStartup.js +++ b/node_package/src/clientStartup.js @@ -183,8 +183,8 @@ export function clientStartup(context) { if (turbolinksVersion5()) { debugTurbolinks( 'USING TURBOLINKS 5: document added event listeners ' + - ' turbolinks:before-visit and turbolinks:load.'); - document.addEventListener('turbolinks:before-visit', reactOnRailsPageUnloaded); + 'turbolinks:before-render and turbolinks:load.'); + document.addEventListener('turbolinks:before-render', reactOnRailsPageUnloaded); document.addEventListener('turbolinks:load', reactOnRailsPageLoaded); } else { debugTurbolinks( From 85c6b08d34a439ef90da2e46b91801e1973047b0 Mon Sep 17 00:00:00 2001 From: "Arthur Shcheglov (fc_arny)" Date: Sun, 12 Feb 2017 00:04:40 +0300 Subject: [PATCH 40/42] Ability to work without sprockets (#671) This enables omitting Sprockets. Sprockets' tasks (assets:*) not available if you do not require 'sprockets/railtie' and when you try run some rake task got a message: ```bash ReactOnRails: Set generated_assets_dir to default: app/assets/webpack Running via Spring preloader in process 18586 rake aborted! Don't know how to build task 'assets:precompile' (see --tasks) /Users/arthur/.rvm/gems/ruby-2.3.3/gems/react_on_rails-6.3.4/lib/tasks/assets.rake:35:in `' ... ``` My application config ```ruby # frozen_string_literal: true require_relative 'boot' require 'rails' # Pick the frameworks you want: require 'active_model/railtie' require 'active_job/railtie' require 'active_record/railtie' require 'action_controller/railtie' require 'action_mailer/railtie' require 'action_view/railtie' # require 'sprockets/railtie' Bundler.require(*Rails.groups) module My class Application < Rails::Application # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s] config.i18n.default_locale = :ru config.i18n.enforce_available_locales = true config.time_zone = 'Moscow' config.middleware.use I18n::JS::Middleware end end ``` --- CHANGELOG.md | 3 ++ lib/tasks/assets.rake | 68 +++++++++++++++++++++++-------------------- 2 files changed, 40 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84bf1e729..82e9b59bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ Contributors: please follow the recommendations outlined at [keepachangelog.com] ## [Unreleased] *Please add entries here for your pull requests.* +### Changed +- Add ability use gem without sprockets. [#671](https://github.com/shakacode/react_on_rails/pull/671) by [fc-arny](https://github.com/fc-arny) + ### Fixed - Fixed issue [#706](https://github.com/shakacode/react_on_rails/issues/706) with "flickering" components when they are unmounted too early [#709](https://github.com/shakacode/react_on_rails/pull/709) by [szyablitsky](https://github.com/szyablitsky) diff --git a/lib/tasks/assets.rake b/lib/tasks/assets.rake index ea83248fb..c1a255134 100644 --- a/lib/tasks/assets.rake +++ b/lib/tasks/assets.rake @@ -1,28 +1,50 @@ require "react_on_rails/assets_precompile" -namespace :react_on_rails do - namespace :assets do - desc "Creates non-digested symlinks for the assets in the public asset dir" - task symlink_non_digested_assets: :"assets:environment" do - ReactOnRails::AssetsPrecompile.new.symlink_non_digested_assets - end +if defined?(Sprockets) + namespace :react_on_rails do + namespace :assets do + desc "Creates non-digested symlinks for the assets in the public asset dir" + task symlink_non_digested_assets: :"assets:environment" do + ReactOnRails::AssetsPrecompile.new.symlink_non_digested_assets + end - desc "Cleans all broken symlinks for the assets in the public asset dir" - task delete_broken_symlinks: :"assets:environment" do - ReactOnRails::AssetsPrecompile.new.delete_broken_symlinks - end + desc "Cleans all broken symlinks for the assets in the public asset dir" + task delete_broken_symlinks: :"assets:environment" do + ReactOnRails::AssetsPrecompile.new.delete_broken_symlinks + end - # In this task, set prerequisites for the assets:precompile task - desc <<-DESC + # In this task, set prerequisites for the assets:precompile task + desc <<-DESC Create webpack assets before calling assets:environment The webpack task must run before assets:environment task. Otherwise Sprockets cannot find the files that webpack produces. This is the secret sauce for how a Heroku deployment knows to create the webpack generated JavaScript files. - DESC - task compile_environment: :webpack do - Rake::Task["assets:environment"].invoke + DESC + task compile_environment: :webpack do + Rake::Task["assets:environment"].invoke + end + + desc "Delete assets created with webpack, in the generated assetst directory (/app/assets/webpack)" + task clobber: :environment do + ReactOnRails::AssetsPrecompile.new.clobber + end end + end + + # These tasks run as pre-requisites of assets:precompile. + # Note, it's not possible to refer to ReactOnRails configuration values at this point. + Rake::Task["assets:precompile"] + .clear_prerequisites + .enhance([:environment, "react_on_rails:assets:compile_environment"]) + .enhance do + Rake::Task["react_on_rails:assets:symlink_non_digested_assets"].invoke + Rake::Task["react_on_rails:assets:delete_broken_symlinks"].invoke + end +end +# Sprockets independent tasks +namespace :react_on_rails do + namespace :assets do desc <<-DESC Compile assets with webpack Uses command defined with ReactOnRails.configuration.npm_build_production_command @@ -33,21 +55,5 @@ sh "cd client && `ReactOnRails.configuration.npm_build_production_command`" sh "cd client && #{ReactOnRails.configuration.npm_build_production_command}" end end - - desc "Delete assets created with webpack, in the generated assetst directory (/app/assets/webpack)" - task clobber: :environment do - ReactOnRails::AssetsPrecompile.new.clobber - end end end - -# These tasks run as pre-requisites of assets:precompile. -# Note, it's not possible to refer to ReactOnRails configuration values at this point. -Rake::Task["assets:precompile"] - .clear_prerequisites - .enhance([:environment, "react_on_rails:assets:compile_environment"]) - .enhance do - Rake::Task["react_on_rails:assets:symlink_non_digested_assets"].invoke - Rake::Task["react_on_rails:assets:delete_broken_symlinks"].invoke - end - From f2c3359ccf3a92d4674521d7f5693b4794a08e3a Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Sat, 11 Feb 2017 11:09:21 -1000 Subject: [PATCH 41/42] Update CHANGELOG.md --- CHANGELOG.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82e9b59bc..11339bcd4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,11 +5,12 @@ Contributors: please follow the recommendations outlined at [keepachangelog.com] ## [Unreleased] *Please add entries here for your pull requests.* -### Changed -- Add ability use gem without sprockets. [#671](https://github.com/shakacode/react_on_rails/pull/671) by [fc-arny](https://github.com/fc-arny) +## [6.5.1] - 2017-02-11 ### Fixed -- Fixed issue [#706](https://github.com/shakacode/react_on_rails/issues/706) with "flickering" components when they are unmounted too early [#709](https://github.com/shakacode/react_on_rails/pull/709) by [szyablitsky](https://github.com/szyablitsky) +- Allow using gem without sprockets. [#671](https://github.com/shakacode/react_on_rails/pull/671) by [fc-arny](https://github.com/fc-arny). +- Fixed issue [#706](https://github.com/shakacode/react_on_rails/issues/706) with "flickering" components when they are unmounted too early [#709](https://github.com/shakacode/react_on_rails/pull/709) by [szyablitsky](https://github.com/szyablitsky). +- Small formatting fix for errors [#703](https://github.com/shakacode/react_on_rails/pull/703) by [justin808](https://github.com/justin808). ## [6.5.0] - 2017-01-31 ### Added @@ -447,7 +448,8 @@ Best done with Object destructing: ##### Fixed - Fix several generator related issues. -[Unreleased]: https://github.com/shakacode/react_on_rails/compare/6.5.0...master +[Unreleased]: https://github.com/shakacode/react_on_rails/compare/6.5.1...master +[6.5.1]: https://github.com/shakacode/react_on_rails/compare/6.5.0...6.5.1 [6.5.0]: https://github.com/shakacode/react_on_rails/compare/6.4.2...6.5.0 [6.4.2]: https://github.com/shakacode/react_on_rails/compare/6.4.1...6.4.2 [6.4.1]: https://github.com/shakacode/react_on_rails/compare/6.4.0...6.4.1 From 0ec2f39ad9817716f890fe49d9fe8fa4fa3137cd Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Sat, 11 Feb 2017 11:12:44 -1000 Subject: [PATCH 42/42] Release 6.5.1 --- lib/react_on_rails/version.rb | 2 +- package.json | 2 +- spec/dummy/Gemfile.lock | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/react_on_rails/version.rb b/lib/react_on_rails/version.rb index 106a1dff8..c7444346b 100644 --- a/lib/react_on_rails/version.rb +++ b/lib/react_on_rails/version.rb @@ -1,4 +1,4 @@ # frozen_string_literal: true module ReactOnRails - VERSION = "6.5.0".freeze + VERSION = "6.5.1".freeze end diff --git a/package.json b/package.json index 7f9db8fa5..52b9c4fc5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-on-rails", - "version": "6.5.0", + "version": "6.5.1", "description": "react-on-rails JavaScript for react_on_rails Ruby gem", "main": "node_package/lib/ReactOnRails.js", "directories": { diff --git a/spec/dummy/Gemfile.lock b/spec/dummy/Gemfile.lock index 4e38ff277..098d63236 100644 --- a/spec/dummy/Gemfile.lock +++ b/spec/dummy/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: ../.. specs: - react_on_rails (6.5.0) + react_on_rails (6.5.1) addressable connection_pool execjs (~> 2.5)