react_on_rails 9.0.3 → 10.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f41863c0e8b5cfbc03a81dc6d8b4adb4267b6475
4
- data.tar.gz: c884cd7c06d50f9abc8d5c084df1912f44dd82ea
3
+ metadata.gz: 1c3ced829061ca6995dd0f55349112955883e87b
4
+ data.tar.gz: be160b38edcaa90ae64ce0ea69a029f48505968b
5
5
  SHA512:
6
- metadata.gz: 17327f03ceea1acf189be53955b0f84f255aafe2809398f1027242877ceb1f7fc79b9c40ade163aaa49cb695beee4e80054774b2fed9a3a8769ee30e0f83a22d
7
- data.tar.gz: 92a3d81eb2440990899f77eaa2d41c20b30adf2faa49b67eb6c8d8eb199848a6d26e85cc2c71c0d21c4c9da451fb5b632a03c60491dab3468924fde37fb37870
6
+ metadata.gz: 69f0ea0f49b5a2e5eab554656ffe8b82b18cad3475ea963a5fced718d2af7498f5aaf23e4a0a9554382f32a6a24f1fa154b1d4e27d208286b54d757ac5032e48
7
+ data.tar.gz: 7442ea55fa1d838d8c8f75dbfdb83c6db36bce40b5be5e3f10a9d38f8455d91930e7aa2bdfdd55ab3546f5c38a96bef1eef9f18f5b15f325c344c7492767dbc4
data/.rubocop.yml CHANGED
@@ -34,7 +34,7 @@ AllCops:
34
34
  - 'gen-examples/examples/**/.*'
35
35
  - 'gen-examples/examples/**/*'
36
36
 
37
- Style/FileName:
37
+ Naming/FileName:
38
38
  Exclude:
39
39
  - 'Gemfile'
40
40
  - 'spec/dummy/Gemfile'
data/CHANGELOG.md CHANGED
@@ -8,18 +8,26 @@ Changes since last non-beta release.
8
8
 
9
9
  *Please add entries here for your pull requests.*
10
10
 
11
+ ### [10.0.0] - 2017-10-08
12
+ #### Created
13
+ - Created `react_component_hash` method for react_helmet support.
14
+ #### Deprecated
15
+ - Deprecated `react_component` functionality for react_helmet support.
16
+ To clarify, the method itself is not deprecated, only certain functionality which has been moved to `react_component_hash`
17
+ [PR 951](https://github.com/shakacode/react_on_rails/pull/951) by [Judahmeek](https://github.com/Judahmeek)
18
+
11
19
  ### [9.0.3] - 2017-09-20
12
20
  #### Improved
13
- - Improved comments in generated Procfile.dev-server. [PR 940](https://github.com/shakacode/react_on_rails/pull/940) by [justin808](https://github.com/justin808 )
21
+ - Improved comments in generated Procfile.dev-server. [PR 940](https://github.com/shakacode/react_on_rails/pull/940) by [justin808](https://github.com/justin808 )
14
22
 
15
23
  ### [9.0.2] - 2017-09-10
16
24
  #### Fixed
17
- - Improved post install doc comments for generator. [PR 933](https://github.com/shakacode/react_on_rails/pull/933) by [justin808](https://github.com/justin808 )
25
+ - Improved post install doc comments for generator. [PR 933](https://github.com/shakacode/react_on_rails/pull/933) by [justin808](https://github.com/justin808 )
18
26
 
19
27
  ### [9.0.1] - 2017-09-10
20
28
 
21
29
  #### Fixed
22
- - Fixes Rails 3.2 compatability issues. [PR 926](https://github.com/shakacode/react_on_rails/pull/926) by [morozovm](https://github.com/morozovm )
30
+ - Fixes Rails 3.2 compatability issues. [PR 926](https://github.com/shakacode/react_on_rails/pull/926) by [morozovm](https://github.com/morozovm )
23
31
 
24
32
  ### [9.0.0] - 2017-09-06
25
33
  Updated React on Rails to depend on [rails/webpacker](https://github.com/rails/webpacker). [PR 908](https://github.com/shakacode/react_on_rails/pull/908) by [justin808](https://github.com/justin808).
@@ -33,7 +41,7 @@ For an example of upgrading, see [react-webpack-rails-tutorial/pull/416](https:/
33
41
  1. Added `config.node_modules_location` which defaults to `""` if Webpacker is installed. You may want to set this to 'client'` to `config/initializers/react_on_rails.rb` to keep your node_modules inside of `/client`
34
42
  2. Renamed
35
43
  * config.npm_build_test_command ==> config.build_test_command
36
- * config.build_production_command ==> config.build_production_command
44
+ * config.npm_build_production_command ==> config.build_production_command
37
45
 
38
46
  - Update the gemfile. Switch over to using the webpacker gem.
39
47
 
@@ -52,9 +60,9 @@ gem "webpacker"
52
60
  - manifest ==> Remove this one. We use the default for Webpack of manifest.json
53
61
  - env ==> Use `const { env } = require('process');`
54
62
  - devBuild ==> Use `const devBuild = process.env.NODE_ENV !== 'production';`
55
-
63
+
56
64
  - Edit your Webpack.config files:
57
- - Change your Webpack output to be like:
65
+ - Change your Webpack output to be like this. **Be sure to have the hash or chunkhash in the filename,** unless the bundle is server side.:
58
66
  ```
59
67
  const webpackConfigLoader = require('react-on-rails/webpackConfigLoader');
60
68
  const configPath = resolve('..', 'config');
@@ -65,7 +73,7 @@ gem "webpacker"
65
73
  output: {
66
74
  filename: isHMR ? '[name]-[hash].js' : '[name]-[chunkhash].js',
67
75
  chunkFilename: '[name]-[chunkhash].chunk.js',
68
-
76
+
69
77
  publicPath: output.publicPath,
70
78
  path: output.path,
71
79
  },
@@ -102,13 +110,13 @@ gem "webpacker"
102
110
  - See the example `spec/dummy/config/webpacker.yml`.
103
111
  - Remove keys `hot_reloading_host` and `hot_reloading_enabled_by_default`. These are replaced by the `dev_server` key.
104
112
  - Rename `webpack_public_output_dir` to `public_output_path`.
105
-
113
+
106
114
  - Edit your Procfile.dev
107
115
  - Remove the env value WEBPACKER_DEV_SERVER as it's not used
108
116
  - For hot loading:
109
117
  - Set the `hmr` key in your `webpacker.yml` to `true`.
110
-
111
-
118
+
119
+
112
120
  ### [8.0.7] - 2017-08-16
113
121
  #### Fixed
114
122
  - Fixes generator bug by keeping blank line at top in case existing .gitignore does not end in a newline. [#916](https://github.com/shakacode/react_on_rails/pull/916) by [justin808](https://github.com/justin808).
data/Gemfile CHANGED
@@ -16,7 +16,7 @@ gem "mini_racer"
16
16
  gem "puma"
17
17
  gem "rails", "5.1.2"
18
18
  gem "rails_12factor"
19
- gem "rubocop", require: false
19
+ gem "rubocop", "~> 0.50", require: false
20
20
  gem "ruby-lint", require: false
21
21
  gem "sass-rails", "~> 5.0"
22
22
  gem "scss_lint", require: false
@@ -38,7 +38,7 @@ gem "chromedriver-helper"
38
38
  gem "launchy"
39
39
  gem "poltergeist"
40
40
  gem "selenium-webdriver"
41
- gem "webpacker", "~> 3.0"
41
+ gem "webpacker", "3.0.2"
42
42
 
43
43
  # TODO: remove once we get out of beta.
44
44
  # gem 'webpacker', path: "../../forks/webpacker"
data/KUDOS.md CHANGED
@@ -2,6 +2,11 @@ This is a sibling file to [PROJECTS.md](./PROJECTS.md).
2
2
 
3
3
  I'm looking for quotes on why you like using React on Rails. You might mention any benefits you particularly like and if you've migrated from react-rails. Just click to edit and github will automatically open up a PR. Thanks to everybody that contributes!
4
4
 
5
+ ## September 20, 2017, By [ShakaCode Forum](https://forum.shakacode.com/t/new-ror-users-inbound/1014)
6
+
7
+ ![2017-10-07_00-18-43](https://user-images.githubusercontent.com/1118459/31306902-341a537a-aaf5-11e7-8014-28c126a7c975.png)
8
+
9
+
5
10
  ## June 9, 2017
6
11
  By Github Issue [#868](https://github.com/shakacode/react_on_rails/issues/868)
7
12
 
data/README.md CHANGED
@@ -2,7 +2,8 @@
2
2
 
3
3
  *If this projects helps you, please give us a star!*
4
4
 
5
- [rails/webpacker](https://github.com/rails/webpacker) just shipped 3.0. This now enables me to ship version 9.0. See [PR #908](https://github.com/shakacode/react_on_rails/pull/908) for more details.
5
+ [ShakaCode is hiring team members](http://www.shakacode.com/about/#work-with-us) for our own app, [Friends and Guests](https://www.friendsandguests.com).
6
+
6
7
  # React on Rails v9 is based on Webpacker 3.0!
7
8
 
8
9
  * See the article [Introducing React on Rails v9 with Webpacker Support](https://blog.shakacode.com/introducing-react-on-rails-v9-with-webpacker-support-f2584c6c8fa4) for an overview of the integration of React on Rails with Webpacker.
@@ -20,7 +21,7 @@ Given that Webpacker already provides React integration, why would you add React
20
21
  4. Localization support
21
22
  5. Rspec test helpers to ensure your Webpack bundles are ready for tests
22
23
 
23
- ----
24
+ ----
24
25
 
25
26
  ## Steps to a New App with rails/webpacker v3 plus React on Rails v9:
26
27
  First be sure to run `rails -v` and check that you are using Rails 5.1.3 or above. If you are using an older version of Rails, you'll need to install webpacker with React per the instructions [here](https://github.com/rails/webpacker).
@@ -28,7 +29,7 @@ First be sure to run `rails -v` and check that you are using Rails 5.1.3 or abov
28
29
  ### Basic installation for a new Rails App
29
30
  *See below for steps on an existing Rails app*
30
31
 
31
- 1. New Rails app: `rails new my-app --webpack=react`. `cd` into the directory.
32
+ 1. New Rails app: `rails new my-app --webpack=react`. `cd` into the directory.
32
33
  2. Add gem version: `gem 'react_on_rails', '~> 9.0.1'`
33
34
  3. Run the generator: `rails generate react_on_rails:install`
34
35
  4. Start the app: `rails s`
@@ -131,7 +132,7 @@ For more testimonials, see [Live Projects](PROJECTS.md) and [Kudos](./KUDOS.md).
131
132
 
132
133
  **Project Objective**: To provide an opinionated and optimal framework for integrating Ruby on Rails with React via the [**Webpacker**](https://github.com/rails/webpacker) gem.
133
134
 
134
- React on Rails integrates Facebook's [React](https://github.com/facebook/react) front-end framework with Rails. React v0.14.x and greater is supported, with server rendering. [Redux](https://github.com/reactjs/redux) and [React-Router](https://github.com/reactjs/react-redux) are supported as well, also with server rendering, using **execJS**.
135
+ React on Rails integrates Facebook's [React](https://github.com/facebook/react) front-end framework with Rails. React v0.14.x and greater is supported, with server rendering. [Redux](https://github.com/reactjs/redux) and [React-Router](https://github.com/reactjs/react-redux) are supported as well, also with server rendering, using **execJS**.
135
136
 
136
137
  ## Table of Contents
137
138
 
@@ -161,7 +162,7 @@ React on Rails integrates Facebook's [React](https://github.com/facebook/react)
161
162
  ---
162
163
 
163
164
  ## Features
164
- Like the [react-rails](https://github.com/reactjs/react-rails) gem, React on Rails is capable of server-side rendering with fragment caching and is compatible with [turbolinks](https://github.com/turbolinks/turbolinks). Unlike react-rails, which depends heavily on sprockets and jquery-ujs, React on Rails uses [webpack](http://webpack.github.io/) and does not depend on jQuery. While the initial setup is slightly more involved, it allows for advanced functionality such as:
165
+ Like the [react-rails](https://github.com/reactjs/react-rails) gem, React on Rails is capable of server-side rendering with fragment caching and is compatible with [turbolinks](https://github.com/turbolinks/turbolinks). While the initial setup is slightly more involved, it allows for advanced functionality such as:
165
166
 
166
167
  + [Redux](https://github.com/reactjs/redux)
167
168
  + [Webpack optimization functionality](https://github.com/webpack/docs/wiki/optimization)
@@ -197,7 +198,7 @@ To upgrade existing apps to React on Rails 8 see the [Installation Overview](doc
197
198
  ```
198
199
  bundle exec rails webpacker:install
199
200
  bundle exec rails webpacker:install:react
200
-
201
+
201
202
  ```
202
203
 
203
204
  2. Commit this to git (or else you cannot run the generator unless you pass the option `--ignore-warnings`).
@@ -222,7 +223,7 @@ To upgrade existing apps to React on Rails 8 see the [Installation Overview](doc
222
223
  foreman start -f Procfile.dev
223
224
  ```
224
225
 
225
- 8. Visit [localhost:3000/hello_world](http://localhost:3000/hello_world). Note, `foreman` defaults to PORT 5000 unless you set the value of PORT in your environment. For example, you can `export PORT=3000` to use the Rails default port of 3000. For the hello_world example this is already set.
226
+ 8. Visit [localhost:3000/hello_world](http://localhost:3000/hello_world). Note: `foreman` defaults to PORT 5000 unless you set the value of PORT in your environment. For example, you can `export PORT=3000` to use the Rails default port of 3000. For the hello_world example this is already set.
226
227
 
227
228
  ### Installation Overview
228
229
 
@@ -303,7 +304,7 @@ In the following screenshot you can see the 3 parts of React on Rails rendering:
303
304
 
304
305
  1. A hidden HTML div contains the properties of the React component, such as the registered name and any props. A JavaScript function runs after the page loads to take this data and build initialize React components.
305
306
  2. The wrapper div `<div id="HelloWorld-react-component-0">` specifies the div where to place the React rendering. It encloses the server-rendered HTML for the React component
306
- 3. Additional JavaScript is placed to console-log any messages, such as server rendering errors. Note, these server side logs can be configured only to be sent to the server logs.
307
+ 3. Additional JavaScript is placed to console-log any messages, such as server rendering errors. Note: these server side logs can be configured only to be sent to the server logs.
307
308
 
308
309
  **Note**:
309
310
 
@@ -334,6 +335,8 @@ Another reason to use a generator function is that sometimes in server rendering
334
335
  For server rendering, if you wish to return multiple HTML strings from a generator function, you may return an Object from your generator function with a single top level property of `renderedHtml`. Inside this Object, place a key called `componentHtml`, along with any other needed keys. An example scenario of this is when you are using side effects libraries like [React Helmet](https://github.com/nfl/react-helmet). Your Ruby code will get this Object as a Hash containing keys componentHtml and any other custom keys that you added:
335
336
  { renderedHtml: { componentHtml, customKey1, customKey2} }
336
337
 
338
+ Note: The functionality in the above paragraph requires the use of our new `react_component_hash` method. Said functionality in our `react_component` method is now deprecated.
339
+
337
340
  ### Rails Context and Generator Functions
338
341
  When you use a "generator function" to create react components (or renderedHtml on the server), or you used shared redux stores, you get two params passed to your function that creates a React component:
339
342
 
@@ -372,9 +375,9 @@ and, similarly, any redux store always initialized with 2 parameters:
372
375
  reduxStore = MyReduxStore(props, railsContext);
373
376
  ```
374
377
 
375
- Note, you never make these calls. React on Rails makes these calls when it does either client or server rendering. You will define functions that take these 2 params and return a React component or a Redux Store. Naturally, you do not have to use second parameter of the railsContext if you do not need it.
378
+ Note: you never make these calls. React on Rails makes these calls when it does either client or server rendering. You will define functions that take these 2 params and return a React component or a Redux Store. Naturally, you do not have to use second parameter of the railsContext if you do not need it.
376
379
 
377
- (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.)
380
+ (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.)
378
381
 
379
382
  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).
380
383
 
@@ -390,7 +393,7 @@ The `railsContext` has: (see implementation in file [react_on_rails_helper.rb](h
390
393
  search: uri.query, # id=30&limit=5
391
394
 
392
395
  # Other
393
- serverSide: boolean # Are we being called on the server or client? NOTE, if you conditionally
396
+ serverSide: boolean # Are we being called on the server or client? Note: if you conditionally
394
397
  # render something different on the server than the client, then React will only show the
395
398
  # server version!
396
399
  }
@@ -468,7 +471,7 @@ This is how to expose a component to the `react_component` view helper.
468
471
 
469
472
  You may want different initialization for your server-rendered components. For example, if you have an animation that runs when a component is displayed, you might need to turn that off when server rendering. However, the `railsContext` will tell you if your JavaScript code is running client side or server side. So code that required a different server bundle previously may no longer require this!
470
473
 
471
- If you want different code to run, you'd set up a separate webpack compilation file and you'd specify a different, server side entry file. ex. 'serverHelloWorld.jsx'. Note, you might be initializing HelloWorld with version specialized for server rendering.
474
+ If you want different code to run, you'd set up a separate webpack compilation file and you'd specify a different, server side entry file. ex. 'serverHelloWorld.jsx'. Note: you might be initializing HelloWorld with version specialized for server rendering.
472
475
 
473
476
  #### Renderer Functions
474
477
  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 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).
@@ -496,7 +499,7 @@ react_component(component_name,
496
499
  + **prerender:** enable server-side rendering of a component. Set to false when debugging!
497
500
  + **id:** Id for the div, will be used to attach the React component. This will get assigned automatically if you do not provide an id. Must be unique.
498
501
  + **html_options:** Any other HTML options get placed on the added div for the component. For example, you can set a class (or inline style) on the outer div so that it behaves like a span, with the styling of `display:inline-block`.
499
- + **trace:** set to true to print additional debugging information in the browser. Defaults to true for development, off otherwise. Note, on the client, you will see both the `railsContext` and your props. On the server, you only see the `railsContext` being logged.
502
+ + **trace:** set to true to print additional debugging information in the browser. Defaults to true for development, off otherwise. Note: on the client, you will see both the `railsContext` and your props. On the server, you only see the `railsContext` being logged.
500
503
  + **replay_console:** Default is true. False will disable echoing server-rendering logs to the browser. While this can make troubleshooting server rendering difficult, so long as you have the default configuration of `logging_on_server` set to true, you'll still see the errors on the server.
501
504
  + **raise_on_prerender_error:** Default is false. True will throw an error on the server side rendering. Your controller will have to handle the error.
502
505
 
@@ -511,19 +514,19 @@ Include the module `ReactOnRails::Controller` in your controller, probably in Ap
511
514
  2. In your component definition, you'll call `ReactOnRails.getStore('storeName')` to get the hydrated Redux store to attach to your components.
512
515
  + **props:** Named parameter `props`. ReactOnRails takes care of setting up the hydration of your store with props from the view.
513
516
 
514
- 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.
517
+ 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.
515
518
 
516
519
  #### View Helper
517
520
  `redux_store(store_name, props: {})`
518
521
 
519
- This method has the same API as the controller extension. **HOWEVER**, we recommend the controller extension instead because the Rails executes the template code in the controller action's view file (`erb`, `haml`, `slim`, etc.) before the layout. So long as you call `redux_store` at the beginning of your action's view file, this will work. However, it's an easy mistake to put this call in the wrong place. Calling `redux_store` in the controller action ensures proper load order, regardless of where you call this in the controller action. Note, you won't know of this subtle ordering issue until you server render and you find that your store is not hydrated properly.
522
+ This method has the same API as the controller extension. **HOWEVER**, we recommend the controller extension instead because the Rails executes the template code in the controller action's view file (`erb`, `haml`, `slim`, etc.) before the layout. So long as you call `redux_store` at the beginning of your action's view file, this will work. However, it's an easy mistake to put this call in the wrong place. Calling `redux_store` in the controller action ensures proper load order, regardless of where you call this in the controller action. Note: you won't know of this subtle ordering issue until you server render and you find that your store is not hydrated properly.
520
523
 
521
524
  `redux_store_hydration_data`
522
525
 
523
526
  Place this view helper (no parameters) at the end of your shared layout so ReactOnRails will 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).
524
527
 
525
528
  #### Redux Store Notes
526
- Note, you don't need to initialize your redux store. You can pass the props to your React component in a "generator function." However, consider using the `redux_store` helper for the two following use cases:
529
+ Note: you don't need to initialize your redux store. You can pass the props to your React component in a "generator function." However, consider using the `redux_store` helper for the two following use cases:
527
530
 
528
531
  1. You want to have multiple React components accessing the same store at once.
529
532
  2. You want to place the props to hydrate the client side stores at the very end of your HTML so that the browser can render all earlier HTML first. This is particularly useful if your props will be large.
@@ -541,7 +544,7 @@ You may wish to have 2 React components share the same the Redux store. For exam
541
544
 
542
545
  Suppose the Redux store is called `appStore`, and you have 3 React components that each needs to connect to a store: `NavbarApp`, `CommentsApp`, and `BlogsApp`. I named them with `App` to indicate that they are the registered components.
543
546
 
544
- You will need to make a function that can create the store you will be using for all components and register it via the `registerStore` method. Note, this is a **storeCreator**, meaning that it is a function that takes (props, location) and returns a store:
547
+ You will need to make a function that can create the store you will be using for all components and register it via the `registerStore` method. Note: this is a **storeCreator**, meaning that it is a function that takes (props, location) and returns a store:
545
548
 
546
549
  ```js
547
550
  function appStore(props, railsContext) {
@@ -567,7 +570,7 @@ return (
567
570
  );
568
571
  ```
569
572
 
570
- From your Rails view, you can use the provided helper `redux_store(store_name, props)` to create a fresh version of the store (because it may already exist if you came from visiting a previous page). Note, for this example, since we're initializing this from the main layout, we're using a generic name of `@react_props`. In other words, the Rails controller would set `@react_props` to the properties to hydrate the Redux store.
573
+ From your Rails view, you can use the provided helper `redux_store(store_name, props)` to create a fresh version of the store (because it may already exist if you came from visiting a previous page). Note: for this example, since we're initializing this from the main layout, we're using a generic name of `@react_props`. In other words, the Rails controller would set `@react_props` to the properties to hydrate the Redux store.
571
574
 
572
575
  **app/views/layouts/application.html.erb**
573
576
  ```erb
@@ -97,52 +97,49 @@ module ReactOnRailsHelper
97
97
  # if the JS code throws
98
98
  # Any other options are passed to the content tag, including the id.
99
99
  def react_component(component_name, raw_options = {})
100
- # Create the JavaScript and HTML to allow either client or server rendering of the
101
- # react_component.
102
- #
103
- # Create the JavaScript setup of the global to initialize the client rendering
104
- # (re-hydrate the data). This enables react rendered on the client to see that the
105
- # server has already rendered the HTML.
106
-
107
- options = ReactOnRails::ReactComponent::Options.new(name: component_name, options: raw_options)
108
-
109
- # Setup the page_loaded_js, which is the same regardless of prerendering or not!
110
- # The reason is that React is smart about not doing extra work if the server rendering did its job.
111
- component_specification_tag = content_tag(:script,
112
- json_safe_and_pretty(options.props).html_safe,
113
- type: "application/json",
114
- class: "js-react-on-rails-component",
115
- "data-component-name" => options.name,
116
- "data-trace" => (options.trace ? true : nil),
117
- "data-dom-id" => options.dom_id)
118
-
119
- # Create the HTML rendering part
120
- result = server_rendered_react_component_html(options.props,
121
- options.name,
122
- options.dom_id,
123
- prerender: options.prerender,
124
- trace: options.trace,
125
- raise_on_prerender_error: options.raise_on_prerender_error)
126
-
127
- server_rendered_html = result["html"]
128
- console_script = result["consoleReplayScript"]
100
+ internal_result = internal_react_component(component_name, raw_options)
101
+ server_rendered_html = internal_result["result"]["html"]
102
+ console_script = internal_result["result"]["consoleReplayScript"]
129
103
 
130
104
  if server_rendered_html.is_a?(String)
131
105
  build_react_component_result_for_server_rendered_string(
132
106
  server_rendered_html: server_rendered_html,
133
- component_specification_tag: component_specification_tag,
107
+ component_specification_tag: internal_result["tag"],
134
108
  console_script: console_script,
135
- options: options
109
+ options: internal_result["options"]
136
110
  )
137
111
  elsif server_rendered_html.is_a?(Hash)
112
+ puts "[DEPRECATION] ReactOnRails: Use react_component_hash to return a Hash to your ruby view code"
138
113
  build_react_component_result_for_server_rendered_hash(
139
114
  server_rendered_html: server_rendered_html,
140
- component_specification_tag: component_specification_tag,
115
+ component_specification_tag: internal_result["tag"],
141
116
  console_script: console_script,
142
- options: options
117
+ options: internal_result["options"]
143
118
  )
144
119
  else
145
- raise "server_rendered_html expected to be a String or a Hash."
120
+ raise "server_rendered_html is expected to be a String. If you're trying to use a generator function to
121
+ return a Hash to your ruby view code, then use react_component_hash instead of react_component and
122
+ see https://github.com/shakacode/react_on_rails/blob/master/spec/dummy/client/app/startup/ReactHelmetServerApp.jsx
123
+ for an example of the necessary javascript configuration."
124
+ end
125
+ end
126
+
127
+ def react_component_hash(component_name, raw_options = {})
128
+ internal_result = internal_react_component(component_name, raw_options)
129
+ server_rendered_html = internal_result["result"]["html"]
130
+ console_script = internal_result["result"]["consoleReplayScript"]
131
+
132
+ if server_rendered_html.is_a?(Hash)
133
+ build_react_component_result_for_server_rendered_hash(
134
+ server_rendered_html: server_rendered_html,
135
+ component_specification_tag: internal_result["tag"],
136
+ console_script: console_script,
137
+ options: internal_result["options"]
138
+ )
139
+ else
140
+ raise "Generator function is expected to return an Object. See
141
+ https://github.com/shakacode/react_on_rails/blob/master/spec/dummy/client/app/startup/ReactHelmetServerApp.jsx
142
+ for an example of the necessary javascript configuration."
146
143
  end
147
144
  end
148
145
 
@@ -177,7 +174,9 @@ module ReactOnRailsHelper
177
174
  # that contains a data props.
178
175
  def redux_store_hydration_data
179
176
  return if @registered_stores_defer_render.blank?
177
+ # rubocop:disable Performance/UnfreezeString
180
178
  @registered_stores_defer_render.reduce("".dup) do |accum, redux_store_data|
179
+ # rubocop:enable Performance/UnfreezeString
181
180
  accum << render_redux_store_data(redux_store_data)
182
181
  end.html_safe
183
182
  end
@@ -327,6 +326,37 @@ module ReactOnRailsHelper
327
326
  "#{rails_context_content}\n#{render_value}".html_safe
328
327
  end
329
328
 
329
+ def internal_react_component(component_name, raw_options = {})
330
+ # Create the JavaScript and HTML to allow either client or server rendering of the
331
+ # react_component.
332
+ #
333
+ # Create the JavaScript setup of the global to initialize the client rendering
334
+ # (re-hydrate the data). This enables react rendered on the client to see that the
335
+ # server has already rendered the HTML.
336
+
337
+ options = ReactOnRails::ReactComponent::Options.new(name: component_name, options: raw_options)
338
+
339
+ # Setup the page_loaded_js, which is the same regardless of prerendering or not!
340
+ # The reason is that React is smart about not doing extra work if the server rendering did its job.
341
+ component_specification_tag = content_tag(:script,
342
+ json_safe_and_pretty(options.props).html_safe,
343
+ type: "application/json",
344
+ class: "js-react-on-rails-component",
345
+ "data-component-name" => options.name,
346
+ "data-trace" => (options.trace ? true : nil),
347
+ "data-dom-id" => options.dom_id)
348
+
349
+ # Create the HTML rendering part
350
+ result = server_rendered_react_component_html(options.props,
351
+ options.name,
352
+ options.dom_id,
353
+ prerender: options.prerender,
354
+ trace: options.trace,
355
+ raise_on_prerender_error: options.raise_on_prerender_error)
356
+
357
+ { "options" => options, "tag" => component_specification_tag, "result" => result }
358
+ end
359
+
330
360
  def render_redux_store_data(redux_store_data)
331
361
  result = content_tag(:script,
332
362
  json_safe_and_pretty(redux_store_data[:props]).html_safe,
@@ -413,13 +443,15 @@ module ReactOnRailsHelper
413
443
 
414
444
  def initialize_redux_stores
415
445
  return "" unless @registered_stores.present? || @registered_stores_defer_render.present?
416
- declarations = "var reduxProps, store, storeGenerator;\n".dup
446
+ declarations = "var reduxProps, store, storeGenerator;\n".dup # rubocop:disable Performance/UnfreezeString
417
447
 
418
448
  all_stores = (@registered_stores || []) + (@registered_stores_defer_render || [])
419
449
 
450
+ # rubocop:disable Performance/UnfreezeString
420
451
  result = <<-JS.dup
421
452
  ReactOnRails.clearHydratedStores();
422
453
  JS
454
+ # rubocop:enable Performance/UnfreezeString
423
455
 
424
456
  result << all_stores.each_with_object(declarations) do |redux_store_data, memo|
425
457
  store_name = redux_store_data[:store_name]
@@ -87,6 +87,6 @@ Run:
87
87
 
88
88
  ```
89
89
  bundle
90
- bin/rake db:migrate
91
90
  bin/rake db:setup
91
+ bin/rake db:migrate
92
92
  ```
@@ -61,9 +61,9 @@ ReactOnRails.register({
61
61
  ReactHelmetApp
62
62
  });
63
63
  ```
64
- Now when `react_component` helper will be called with **"ReactHelmetApp"** as a first argument it will return a hash instead of HTML string:
64
+ Now when the `react_component_hash` helper is called with **"ReactHelmetApp"** as a first argument it will return a hash instead of HTML string:
65
65
  ```ruby
66
- <% react_helmet_app = react_component("ReactHelmetApp", prerender: true, props: { hello: "world" }, trace: true) %>
66
+ <% react_helmet_app = react_component_hash("ReactHelmetApp", prerender: true, props: { hello: "world" }, trace: true) %>
67
67
 
68
68
  <% content_for :title do %>
69
69
  <%= react_helmet_app['title'] %>
@@ -76,3 +76,5 @@ So now we're able to insert received title tag to our application layout:
76
76
  ```ruby
77
77
  <%= yield(:title) if content_for?(:title) %>
78
78
  ```
79
+
80
+ Note: Use of `react_component` for this functionality is deprecated. Please use `react_component_hash` instead.
@@ -1,6 +1,6 @@
1
1
  Here is the full set of config options.
2
2
 
3
- ```yaml
3
+ ```ruby
4
4
  # frozen_string_literal: true
5
5
 
6
6
  # NOTE: you typically will leave the commented out configurations set to their defaults.
@@ -4,7 +4,7 @@ Here's an overview of installation if you're not using the generator.
4
4
 
5
5
  Note, the best way to understand how to use ReactOnRails is to study the examples:
6
6
 
7
- 1. Run the generator per the [Tutorial](../../tutorial.md).
7
+ 1. Run the generator per the [Tutorial](../tutorial.md).
8
8
  2. [spec/dummy](../../spec/dummy): Simple, no DB example.
9
9
  3. [github.com/shakacode/react-webpack-rails-tutorial](https://github.com/shakacode/react-webpack-rails-tutorial): Full featured example.
10
10
 
@@ -30,7 +30,7 @@ module ReactOnRails
30
30
 
31
31
  def add_test_related_gems_to_gemfile
32
32
  gem("rspec-rails", group: :test)
33
- gem("poltergeist", group: :test)
33
+ gem("chromedriver-helper", group: :test)
34
34
  gem("coveralls", require: false)
35
35
  end
36
36
 
@@ -48,7 +48,7 @@ Please add the following content to your #{file} file:
48
48
  end
49
49
 
50
50
  def copy_file_and_missing_parent_directories(source_file, destination_file = nil)
51
- destination_file = source_file unless destination_file
51
+ destination_file ||= source_file
52
52
  destination_path = Pathname.new(destination_file)
53
53
  parent_directories = destination_path.dirname
54
54
  empty_directory(parent_directories) unless dest_dir_exists?(parent_directories)
@@ -13,8 +13,10 @@ require_relative "spec_helper"
13
13
  require "rspec/rails"
14
14
  require "capybara/rspec"
15
15
  require "capybara/rails"
16
- require "capybara/poltergeist"
17
- Capybara.javascript_driver = :poltergeist
16
+ Capybara.javascript_driver = :selenium_chrome
17
+ Capybara.register_driver :selenium_chrome do |app|
18
+ Capybara::Selenium::Driver.new(app, browser: :chrome)
19
+ end
18
20
 
19
21
  # Requires supporting ruby files with custom matchers and macros, etc, in
20
22
  # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
@@ -102,7 +102,7 @@ module ReactOnRails
102
102
  next unless File.lstat(filename).symlink?
103
103
  begin
104
104
  target = File.readlink(filename)
105
- rescue
105
+ rescue # rubocop:disable Lint/RescueWithoutErrorClass
106
106
  puts "React on Rails: Warning: your platform doesn't support File::readlink method." /
107
107
  "Skipping broken link check."
108
108
  break
@@ -139,7 +139,7 @@ module ReactOnRails
139
139
  # pointing to. We can't use File.exist?, as that would check the file pointed at by the symlink.
140
140
  File.lstat(path)
141
141
  true
142
- rescue
142
+ rescue # rubocop:disable Lint/RescueWithoutErrorClass
143
143
  false
144
144
  end
145
145
  end
@@ -21,7 +21,7 @@ module ReactOnRails
21
21
  end
22
22
 
23
23
  def self.check_i18n_directory_exists
24
- return unless @configuration.i18n_dir.present?
24
+ return if @configuration.i18n_dir.blank?
25
25
  return if Dir.exist?(@configuration.i18n_dir)
26
26
 
27
27
  raise "Error configuring /config/react_on_rails.rb: invalid value for `config.i18n_dir`. "\
@@ -30,7 +30,7 @@ module ReactOnRails
30
30
  end
31
31
 
32
32
  def self.check_i18n_yml_directory_exists
33
- return unless @configuration.i18n_yml_dir.present?
33
+ return if @configuration.i18n_yml_dir.blank?
34
34
  return if Dir.exist?(@configuration.i18n_yml_dir)
35
35
 
36
36
  raise "Error configuring /config/react_on_rails.rb: invalid value for `config.i18n_yml_dir`. "\
@@ -39,14 +39,14 @@ module ReactOnRails
39
39
  end
40
40
 
41
41
  def self.ensure_generated_assets_dir_present
42
- return unless @configuration.generated_assets_dir.blank?
42
+ return if @configuration.generated_assets_dir.present?
43
43
 
44
44
  @configuration.generated_assets_dir = DEFAULT_GENERATED_ASSETS_DIR
45
45
  puts "ReactOnRails: Set generated_assets_dir to default: #{DEFAULT_GENERATED_ASSETS_DIR}"
46
46
  end
47
47
 
48
48
  def self.configure_generated_assets_dirs_deprecation
49
- return unless @configuration.generated_assets_dirs.present?
49
+ return if @configuration.generated_assets_dirs.blank?
50
50
 
51
51
  puts "[DEPRECATION] ReactOnRails: Use config.generated_assets_dir rather than "\
52
52
  "generated_assets_dirs"
@@ -5,7 +5,7 @@ require "erb"
5
5
  module ReactOnRails
6
6
  class LocalesToJs
7
7
  def initialize
8
- return unless i18n_dir.present?
8
+ return if i18n_dir.blank?
9
9
  return unless obsolete?
10
10
  @translations, @defaults = generate_translations
11
11
  convert
@@ -6,7 +6,7 @@ module ReactOnRails
6
6
  # err might be nil if JS caught the error
7
7
  def initialize(component_name: nil, err: nil, props: nil,
8
8
  js_code: nil, console_messages: nil)
9
- message = "ERROR in SERVER PRERENDERING\n".dup
9
+ message = "ERROR in SERVER PRERENDERING\n".dup # rubocop:disable Performance/UnfreezeString
10
10
  if err
11
11
  # rubocop:disable Layout/IndentHeredoc
12
12
  message << <<-MSG
@@ -54,7 +54,7 @@ module ReactOnRails
54
54
  console_script = result["consoleReplayScript"]
55
55
  console_script_lines = console_script.split("\n")
56
56
  console_script_lines = console_script_lines[2..-2]
57
- re = /console\.log\.apply\(console, \["\[SERVER\] (?<msg>.*)"\]\);/
57
+ re = /console\.(log|error)\.apply\(console, \["\[SERVER\] (?<msg>.*)"\]\);/
58
58
  if console_script_lines
59
59
  console_script_lines.each do |line|
60
60
  match = re.match(line)
@@ -98,7 +98,7 @@ module ReactOnRails
98
98
  # bundle_js_code = File.read(server_js_file)
99
99
  begin
100
100
  bundle_js_code = open(server_js_file, &:read)
101
- rescue => e
101
+ rescue # rubocop:disable Lint/RescueWithoutErrorClass => e
102
102
  msg = "You specified server rendering JS file: #{server_js_file}, but it cannot be "\
103
103
  "read. You may set the server_bundle_js_file in your configuration to be \"\" to "\
104
104
  "avoid this warning.\nError is: #{e}"
@@ -115,7 +115,7 @@ module ReactOnRails
115
115
  begin
116
116
  trace_messsage(base_js_code, file_name)
117
117
  ExecJS.compile(base_js_code)
118
- rescue => e
118
+ rescue # rubocop:disable Lint/RescueWithoutErrorClass => e
119
119
  msg = "ERROR when compiling base_js_code! "\
120
120
  "See file #{file_name} to "\
121
121
  "correlate line numbers of error. Error is\n\n#{e.message}"\
@@ -122,7 +122,7 @@ exitstatus: #{status.exitstatus}#{stdout_msg}#{stderr_msg}
122
122
  end
123
123
 
124
124
  def self.prepend_cd_node_modules_directory(cmd)
125
- return cmd unless ReactOnRails.configuration.node_modules_location.present?
125
+ return cmd if ReactOnRails.configuration.node_modules_location.blank?
126
126
  "cd #{ReactOnRails.configuration.node_modules_location} && #{cmd}"
127
127
  end
128
128
 
@@ -142,7 +142,8 @@ exitstatus: #{status.exitstatus}#{stdout_msg}#{stderr_msg}
142
142
  end
143
143
 
144
144
  def self.bundle_js_file_path_from_webpacker(bundle_name)
145
- hashed_bundle_name = Webpacker.manifest.lookup(bundle_name)
145
+ possible_result = Webpacker.manifest.lookup(bundle_name)
146
+ hashed_bundle_name = possible_result.nil? ? Webpacker.manifest.lookup!(bundle_name) : possible_result
146
147
  if Webpacker.dev_server.running?
147
148
  result = "#{Webpacker.dev_server.protocol}://#{Webpacker.dev_server.host_with_port}#{hashed_bundle_name}"
148
149
  result
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ReactOnRails
4
- VERSION = "9.0.3"
4
+ VERSION = "10.0.0"
5
5
  end
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-on-rails",
3
- "version": "9.0.3",
3
+ "version": "10.0.0",
4
4
  "description": "react-on-rails JavaScript for react_on_rails Ruby gem",
5
5
  "main": "node_package/lib/ReactOnRails.js",
6
6
  "directories": {
@@ -42,6 +42,7 @@
42
42
  },
43
43
  "peerDependencies": {
44
44
  "babel-runtime": ">= 6",
45
+ "js-yaml": ">= 3.0.0",
45
46
  "react": ">= 0.14",
46
47
  "react-dom": ">= 0.14"
47
48
  },
@@ -87,7 +88,7 @@
87
88
  },
88
89
  "homepage": "https://github.com/shakacode/react_on_rails#readme",
89
90
  "dependencies": {
90
- "react-on-rails": "^9.0.0-beta.12",
91
+ "react-on-rails": "^9.0.3",
91
92
  "react-redux": "^5.0.6"
92
93
  }
93
94
  }
@@ -49,9 +49,8 @@ module ReactOnRails
49
49
  end
50
50
 
51
51
  # Options we pass when running `rails new` from the command-line.
52
- # The webpack=react option is key.
53
52
  def rails_options
54
- "--skip-bundle --skip-spring --skip-git --skip-test-unit --skip-active-record --webpack=react"
53
+ "--skip-bundle --skip-spring --skip-git --skip-test-unit --skip-active-record"
55
54
  end
56
55
 
57
56
  %w[gen clobber npm_install build_webpack_bundles].each do |task_type|
@@ -9,7 +9,7 @@ require "yaml"
9
9
  require_relative "example_type"
10
10
  require_relative "task_helpers"
11
11
  include ReactOnRails::TaskHelpers
12
- namespace :examples do
12
+ namespace :examples do # rubocop:disable Metrics/BlockLength
13
13
  # Loads data from examples_config.yml and instantiates corresponding ExampleType objects
14
14
  examples_config_file = File.expand_path("../examples_config.yml", __FILE__)
15
15
  examples_config = symbolize_keys(YAML.safe_load(File.read(examples_config_file)))
@@ -29,6 +29,9 @@ namespace :examples do
29
29
  mkdir_p(example_type.dir)
30
30
  sh_in_dir(examples_dir, "rails new #{example_type.name} #{example_type.rails_options}")
31
31
  sh_in_dir(example_type.dir, "touch .gitignore")
32
+ sh_in_dir(example_type.dir, "rake webpacker:install")
33
+ sh_in_dir(example_type.dir, "bundle binstubs --path=#{example_type.dir}/bin webpacker")
34
+ sh_in_dir(example_type.dir, "rake webpacker:install:react")
32
35
  append_to_gemfile(example_type.gemfile, example_type.required_gems)
33
36
  bundle_install_in(example_type.dir)
34
37
  sh_in_dir(example_type.dir, example_type.generator_shell_commands)
data/rakelib/release.rake CHANGED
@@ -60,7 +60,9 @@ task :release, %i[gem_version dry_run tools_install] do |_t, args|
60
60
  sh_in_dir(gem_root, "git add .")
61
61
 
62
62
  # Will bump the yarn version, commit, tag the commit, push to repo, and release on yarn
63
+ # rubocop:disable Performance/UnfreezeString
63
64
  release_it_command = "$(yarn bin)/release-it --non-interactive --npm.publish".dup
65
+ # rubocop:enable Performance/UnfreezeString
64
66
  release_it_command << " --dry-run --verbose" if is_dry_run
65
67
  release_it_command << " #{npm_version}" unless npm_version.strip.empty?
66
68
  sh_in_dir(gem_root, release_it_command)
@@ -119,7 +119,9 @@ def run_tests_in(dir, options = {})
119
119
 
120
120
  command_name = options.fetch(:command_name, path.basename)
121
121
  rspec_args = options.fetch(:rspec_args, "")
122
- env_vars = %(#{options.fetch(:env_vars, '')} TEST_ENV_COMMAND_NAME="#{command_name}").dup
122
+ # rubocop:disable Performance/UnfreezeString
123
+ env_vars = "#{options.fetch(:env_vars, '')} TEST_ENV_COMMAND_NAME=\"#{command_name}\"".dup
124
+ # rubocop:enable Performance/UnfreezeString
123
125
  env_vars << "COVERAGE=true" if ENV["USE_COVERALLS"]
124
126
  sh_in_dir(path.realpath, "#{env_vars} bundle exec rspec #{rspec_args}")
125
127
  end
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  lib = File.expand_path("../lib", __FILE__)
data/yarn.lock CHANGED
@@ -2449,6 +2449,13 @@ js-tokens@^3.0.0, js-tokens@^3.0.2:
2449
2449
  version "3.0.2"
2450
2450
  resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
2451
2451
 
2452
+ js-yaml@^3.10.0:
2453
+ version "3.10.0"
2454
+ resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc"
2455
+ dependencies:
2456
+ argparse "^1.0.7"
2457
+ esprima "^4.0.0"
2458
+
2452
2459
  js-yaml@^3.5.1:
2453
2460
  version "3.9.1"
2454
2461
  resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.9.1.tgz#08775cebdfdd359209f0d2acd383c8f86a6904a0"
@@ -3248,6 +3255,13 @@ react-on-rails@^9.0.0-beta.12:
3248
3255
  react-on-rails "^9.0.0-beta.12"
3249
3256
  react-redux "^5.0.6"
3250
3257
 
3258
+ react-on-rails@^9.0.3:
3259
+ version "9.0.3"
3260
+ resolved "https://registry.yarnpkg.com/react-on-rails/-/react-on-rails-9.0.3.tgz#da8a9873a94d62fe91e1f80d76716583f2be9da7"
3261
+ dependencies:
3262
+ react-on-rails "^9.0.0-beta.12"
3263
+ react-redux "^5.0.6"
3264
+
3251
3265
  react-proxy@^1.1.7:
3252
3266
  version "1.1.8"
3253
3267
  resolved "https://registry.yarnpkg.com/react-proxy/-/react-proxy-1.1.8.tgz#9dbfd9d927528c3aa9f444e4558c37830ab8c26a"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: react_on_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.0.3
4
+ version: 10.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Gordon
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-09-20 00:00:00.000000000 Z
11
+ date: 2017-10-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rainbow