react_on_rails 11.1.8 → 11.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.eslintrc +8 -2
- data/.prettierignore +1 -0
- data/.prettierrc +20 -0
- data/.release-it.json +3 -0
- data/.travis.yml +10 -9
- data/CHANGELOG.md +55 -3
- data/CONTRIBUTING.md +2 -10
- data/Gemfile +1 -2
- data/Gemfile.rails32 +0 -1
- data/README.md +20 -11
- data/SUMMARY.md +3 -1
- data/docs/additional-reading/images.md +1 -1
- data/docs/additional-reading/rails_view_rendering_from_inline_javascript.md +2 -1
- data/docs/additional-reading/upgrade-webpacker-v3-to-v4.md +10 -0
- data/docs/api/view-helpers-api.md +12 -8
- data/docs/basics/configuration.md +4 -4
- data/docs/basics/minitest-configuration.md +31 -0
- data/docs/basics/recommended-project-structure.md +1 -1
- data/docs/basics/rspec-configuration.md +2 -2
- data/docs/basics/upgrading-react-on-rails.md +11 -1
- data/docs/misc-pending/code-splitting.md +2 -2
- data/docs/testimonials/hvmn.md +3 -3
- data/docs/testimonials/resortpass.md +13 -0
- data/docs/testimonials/testimonials.md +11 -1
- data/docs/tutorial.md +31 -6
- data/lib/generators/react_on_rails/dev_tests_generator.rb +1 -0
- data/lib/generators/react_on_rails/install_generator.rb +2 -0
- data/lib/generators/react_on_rails/templates/dev_tests/spec/rails_helper.rb +8 -1
- data/lib/react_on_rails.rb +1 -0
- data/lib/react_on_rails/assets_precompile.rb +3 -0
- data/lib/react_on_rails/configuration.rb +2 -1
- data/lib/react_on_rails/git_utils.rb +2 -0
- data/lib/react_on_rails/helper.rb +72 -73
- data/lib/react_on_rails/json_output.rb +1 -1
- data/lib/react_on_rails/locales_to_js.rb +2 -0
- data/lib/react_on_rails/react_component/render_options.rb +4 -0
- data/lib/react_on_rails/server_rendering_js_code.rb +42 -0
- data/lib/react_on_rails/server_rendering_pool/ruby_embedded_java_script.rb +30 -5
- data/lib/react_on_rails/utils.rb +1 -1
- data/lib/react_on_rails/version.rb +1 -1
- data/lib/react_on_rails/version_checker.rb +4 -1
- data/lib/react_on_rails/webpacker_utils.rb +4 -1
- data/package-scripts.yml +46 -0
- data/package.json +24 -15
- data/rakelib/release.rake +3 -2
- data/react_on_rails.gemspec +1 -1
- data/webpackConfigLoader.js +2 -2
- data/yarn.lock +4431 -1689
- metadata +13 -6
@@ -0,0 +1,31 @@
|
|
1
|
+
# Minitest Configuration
|
2
|
+
|
3
|
+
The setup for minitest is the same as for rspec with the following difference.
|
4
|
+
|
5
|
+
Rather than calling `ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config)`, instead you will do something like this:
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
class ActiveSupport::TestCase
|
9
|
+
setup do
|
10
|
+
ReactOnRails::TestHelper.ensure_assets_compiled
|
11
|
+
end
|
12
|
+
end
|
13
|
+
```
|
14
|
+
|
15
|
+
|
16
|
+
Or maybe something like this, from the [minitest docs](https://github.com/seattlerb/minitest/blob/master/lib/minitest/test.rb#L119):
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
module MyMinitestPlugin
|
20
|
+
def before_setup
|
21
|
+
super
|
22
|
+
ReactOnRails::TestHelper.ensure_assets_compiled
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class MiniTest::Test
|
27
|
+
include MyMinitestPlugin
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
|
@@ -47,7 +47,7 @@ mv app/javascript client
|
|
47
47
|
`rails/webpacker` probably doesn't support having your main node_modules directory under `/client`, so only follow these steps if you want to use your own webpack configuration (which is highly recommended!).
|
48
48
|
|
49
49
|
1. Move the `/package.json` to `/client/package.json`
|
50
|
-
2. Create a `/
|
50
|
+
2. Create a `/package.json` that delegates to `/client/package.json`. See the example in [spec/dummy/package.json](../../spec/dummy/package.json).
|
51
51
|
3. See the webpack configuration in [spec/dummy/client](../../spec/dummy/client) for a webpack configuration example.
|
52
52
|
|
53
53
|
|
@@ -1,4 +1,6 @@
|
|
1
1
|
# RSpec Configuration
|
2
|
+
_Click [here for minitest](./minitest-configuration.md)_
|
3
|
+
|
2
4
|
Because you will probably want to run RSpec tests that rely on compiled webpack assets (typically, your integration/feature specs where `js: true`), you will want to ensure you don't accidentally run tests on missing or stale webpack assets. If you did use stale Webpack assets, you will get invalid test results as your tests do not use the very latest JavaScript code.
|
3
5
|
|
4
6
|
ReactOnRails provides a helper method called `ReactOnRails::TestHelper.configure_rspec_to_compile_assets`. Call this method from inside of the `RSpec.configure` block in your `spec/rails_helper.rb` file, passing the config as an argument. See file [lib/react_on_rails/test_helper.rb](../../lib/react_on_rails/test_helper.rb) for more details. You can customize this to your particular needs by replacing any of the default components used by `ReactOnRails::TestHelper.configure_rspec_to_compile_assets`.
|
@@ -55,8 +57,6 @@ If you want to speed up the re-compiling process so you don't wait to run your t
|
|
55
57
|
|
56
58
|
[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.
|
57
59
|
|
58
|
-
If you want to use a testing framework other than RSpec, please submit let us know on the changes you need to do and we'll update the docs.
|
59
|
-
|
60
60
|
![2016-01-27_02-36-43](https://cloud.githubusercontent.com/assets/1118459/12611951/7c56d070-c4a4-11e5-8a80-9615f99960d9.png)
|
61
61
|
|
62
62
|
![2016-01-27_03-18-05](https://cloud.githubusercontent.com/assets/1118459/12611975/a8011654-c4a4-11e5-84f9-1baca4835b4b.png)
|
@@ -5,12 +5,22 @@ If you would like help in migrating between React on Rails versions or help with
|
|
5
5
|
|
6
6
|
We specialize in helping companies to quickly and efficiently move from versions before 9 to current. The older versions use the Rails asset pipeline to package client assets. The current and recommended way is to use Webpack 4 for asset preparation. You may also need help migrating from the `rails/webpacker`'s Webpack configuration to a better setup ready for Server Side Rendering.
|
7
7
|
|
8
|
+
## Upgrading rails/webpacker from v3 to v4
|
9
|
+
### Custom Webpack build file
|
10
|
+
The default value for `extract_css` is **false** in `config/webpack.yml`. Custom webpack builds should set this value to true or else no CSS link tags are generated. You have a custom webpack build if you are not using [rails/webpacker](https://github.com/rails/webpacker to setup your Webpack configuration.
|
11
|
+
|
12
|
+
```yml
|
13
|
+
default: &default
|
14
|
+
# other stuff
|
15
|
+
extract_css: true
|
16
|
+
# by default, extract and emit a css file. The default is false
|
17
|
+
```
|
18
|
+
|
8
19
|
## Upgrading to version 11
|
9
20
|
* Remove `server_render_method` from config/initializers/react_on_rails.rb. Alternate server rendering methods are part of React on Rails Pro. If you want to use a custom renderer, contact justin@shakacode.com. We have a custom node rendering solution in production for egghead.io.
|
10
21
|
* Remove your usage of ENV["TRACE_REACT_ON_RAILS"] usage. You can get all tracing with either specifying **`trace`** at your component or in your config/initializers/react_on_rails.rb file.
|
11
22
|
* ReactOnRails::Utils.server_bundle_file_name and ReactOnRails::Utils.bundle_file_name were removed. React on Rails Pro contains upgrades to enable component and other types caching with React on Rails.
|
12
23
|
|
13
|
-
|
14
24
|
## Upgrading to version 10
|
15
25
|
|
16
26
|
Pretty simple:
|
@@ -21,7 +21,7 @@ Different markup is generated on the client than on the server. Why does this ha
|
|
21
21
|
|
22
22
|
### The solution
|
23
23
|
|
24
|
-
To prevent this, you have to wait until the code chunk is fetched before doing the initial render on the client side. To accomplish this, react on rails allows you to register a renderer. This works just like registering a generator function, except that the function you pass takes three arguments: `renderer(props, railsContext, domNodeId)`, and is responsible for calling `ReactDOM.render` to render the component to the DOM. React on rails will automatically detect when a generator function takes three arguments, and will not call `ReactDOM.render`, instead allowing you to control the initial render yourself.
|
24
|
+
To prevent this, you have to wait until the code chunk is fetched before doing the initial render on the client side. To accomplish this, react on rails allows you to register a renderer. This works just like registering a generator function, except that the function you pass takes three arguments: `renderer(props, railsContext, domNodeId)`, and is responsible for calling `ReactDOM.render` or `ReactDOM.hydrate` to render the component to the DOM. React on rails will automatically detect when a generator function takes three arguments, and will not call `ReactDOM.render` or `ReactDOM.hydrate`, instead allowing you to control the initial render yourself. Note, you have to be careful to call `ReactDOM.hydrate` rather than `ReactDOM.render` if you are are server rendering.
|
25
25
|
|
26
26
|
Here's an example of how you might use this in practice:
|
27
27
|
|
@@ -115,7 +115,7 @@ See:
|
|
115
115
|
|
116
116
|
- [spec/dummy/client/app/startup/clientRegistration.jsx](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/client/app/startup/clientRegistration.jsx)
|
117
117
|
- [spec/dummy/client/app/startup/serverRegistration.jsx](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/client/app/startup/serverRegistration.jsx)
|
118
|
-
- [spec/dummy/client/app/startup/
|
118
|
+
- [spec/dummy/client/app/startup/DeferredRenderAppClient](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/client/app/startup/DeferredRenderAppClient.jsx)<-- Code splitting implemented here
|
119
119
|
- [spec/dummy/client/app/startup/DeferredRenderAppServer.jsx](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/client/app/startup/DeferredRenderAppServer.jsx)
|
120
120
|
- [spec/dummy/client/app/components/DeferredRender.jsx](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/client/app/components/DeferredRender.jsx)
|
121
121
|
- [spec/dummy/client/app/components/DeferredRenderAsyncPage.jsx](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/client/app/components/DeferredRenderAsyncPage.jsx)
|
data/docs/testimonials/hvmn.md
CHANGED
@@ -16,9 +16,9 @@ The price we paid for the consultation + the React on Rails pro license has alre
|
|
16
16
|
|
17
17
|
If you have any questions, please reach out.
|
18
18
|
|
19
|
-
Paul Benigeri
|
20
|
-
|
21
|
-
[LinkedIn](https://www.linkedin.com/in/benigeri/)
|
19
|
+
Paul Benigeri, Head of E-Commerce
|
20
|
+
|
21
|
+
[paul@hvmn.com](mailto:paul@hvmn.com), [LinkedIn](https://www.linkedin.com/in/benigeri/)
|
22
22
|
|
23
23
|
Related Article: [HVMN’s 90% Reduction in Server Response Time from React on Rails Pro](https://blog.shakacode.com/hvmns-90-reduction-in-server-response-time-from-react-on-rails-pro-eb08226687db)
|
24
24
|
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# ResortPass Testimonial, by Leora Juster, December 10, 2018
|
2
|
+
|
3
|
+
Many can write code that "works." Even fewer can write sophisticated code that both works and reflects a deep understanding of the technologies and paradigms involved. Only a select few can do the aforementioned while assisting in managing the expectations and time constraints of less technically informed members of software product teams to make the best design decisions possible. Justin and his team were instrumental in assisting us in setting design foundations and standards for our transition to a react on rails application. Just three months of work with the team at Shaka code and we have a main page of our application server-side rendering at exponentially improved speeds. The code and CSS files are well-organized and contain repeatable patterns easy to understand, allowing my team to build on what has already been accomplished. I learned a great deal from my interactions with Justin and his team, as they are just as great teachers as they are developers, and feel like I get to continually learn from them as I build on top of their code. Their different support and pro plan options make it easy to build a continuous professional relationship despite fluctuations in my team's funding, and their team is always extremely personable, punctual, and professional.
|
4
|
+
|
5
|
+
Leora Juster, Full-Stack Lead Software Developer
|
6
|
+
|
7
|
+
[LinkedIn](https://www.linkedin.com/in/leora-juster-38933050)
|
8
|
+
|
9
|
+
![image](https://user-images.githubusercontent.com/1118459/50050877-30399b00-00ab-11e9-9e52-2977de45ccae.png)
|
10
|
+
|
11
|
+
[ResortPass](https://resortpass.com/)
|
12
|
+
|
13
|
+
[![2018-12-15_20-48-35](https://user-images.githubusercontent.com/1118459/50050866-03858380-00ab-11e9-8588-461112f8045b.png)](https://resortpass.com/)
|
@@ -1,8 +1,18 @@
|
|
1
1
|
# Testimonials
|
2
|
-
[HVMN Testimonial, Written by Paul Benigeri, October 12, 2018](./
|
2
|
+
# [HVMN Testimonial, Written by Paul Benigeri, October 12, 2018](./hvmn.md)
|
3
3
|
|
4
4
|
> The price we paid for the consultation + the React on Rails pro license has already been made back a couple of times from hosting fees alone. The entire process was super hands off, and our core team was able to focus on shipping new feature during that sprint.
|
5
5
|
|
6
|
+
Full writeup [here](./hvmn.md).
|
7
|
+
|
8
|
+
---
|
9
|
+
|
10
|
+
# [Leora from ResortPass](./resortpass.md), December 10, 2018
|
11
|
+
|
12
|
+
Justin and his team were instrumental in assisting us in setting design foundations and standards for our transition to a react on rails application. Just three months of work with the team at Shaka code and we have a main page of our application server-side rendering at exponentially improved speeds.
|
13
|
+
|
14
|
+
Full writeup [here](./testimonials/resortpass.md).
|
15
|
+
|
6
16
|
---
|
7
17
|
|
8
18
|
From Joel Hooks, Co-Founder, Chief Nerd at [egghead.io](https://egghead.io/), January 30, 2017:
|
data/docs/tutorial.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# React on Rails Basic Tutorial
|
2
2
|
|
3
|
-
This tutorial guides you through setting up a new or existing Rails app with **React on Rails**, demonstrating Rails + React + Redux + Server Rendering. It is updated to 11.1.
|
3
|
+
This tutorial guides you through setting up a new or existing Rails app with **React on Rails**, demonstrating Rails + React + Redux + Server Rendering. It is updated to 11.2.1.
|
4
4
|
|
5
5
|
After finishing this tutorial you will get an application that can do the following (live on Heroku):
|
6
6
|
|
@@ -57,10 +57,10 @@ bundle exec rails webpacker:install
|
|
57
57
|
bundle exec rails webpacker:install:react
|
58
58
|
```
|
59
59
|
|
60
|
-
Add the **React On Rails** gem to your Gemfile
|
60
|
+
Add the **React On Rails** gem to your `Gemfile`:
|
61
61
|
|
62
62
|
```
|
63
|
-
gem 'react_on_rails', '11.1
|
63
|
+
gem 'react_on_rails', '11.2.1' # prefer exact gem version to match npm version
|
64
64
|
```
|
65
65
|
|
66
66
|
Note: Latest released React On Rails version is considered stable. Please use the latest version to ensure you get all the security patches and the best support.
|
@@ -84,15 +84,40 @@ rails generate react_on_rails:install
|
|
84
84
|
bundle && yarn
|
85
85
|
```
|
86
86
|
|
87
|
-
|
87
|
+
Then run server with static client side files:
|
88
88
|
|
89
89
|
```
|
90
90
|
foreman start -f Procfile.dev
|
91
91
|
```
|
92
92
|
|
93
|
+
To run with the webpack-dev-server:
|
94
|
+
```
|
95
|
+
foreman start -f Procfile.dev-server
|
96
|
+
```
|
97
|
+
|
93
98
|
Visit [http://localhost:3000/hello_world](http://localhost:3000/hello_world) and see your **React On Rails** app running!
|
94
99
|
Note, foreman defaults to PORT 5000 unless you set the value of PORT in your environment or in the Procfile.
|
95
100
|
|
101
|
+
## Using a pre-release of rails/webpacker
|
102
|
+
Until `rails/webpacker` v4 ships, or if you ever want to try out the master branch, you can modify the React on Rails tutorial instructions slightly. You can see the sequence of commits here. To summarize:
|
103
|
+
|
104
|
+
**Don't run `rails new` with the `--webpack=react` option**. Instead, add the webpacker gem to the Gemfile such that it points to master, like this if `11.2.1` is the version you want.
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
gem 'webpacker', github: "rails/webpacker"
|
108
|
+
gem 'react_on_rails', '11.2.1' # always use exact version
|
109
|
+
```
|
110
|
+
|
111
|
+
Then run these commands:
|
112
|
+
|
113
|
+
```sh
|
114
|
+
bundle exec rails webpacker:install
|
115
|
+
yarn add "rails/webpacker" # because the installer has a bug that puts in an invalid version in your package.json.
|
116
|
+
bundle exec rails webpacker:install:react
|
117
|
+
yarn add --dev webpack-dev-server
|
118
|
+
run rails generate react_on_rails:install && bundle && yarn
|
119
|
+
```
|
120
|
+
|
96
121
|
### Custom IP & PORT setup (Cloud9 example)
|
97
122
|
|
98
123
|
In case you are running some custom setup with different IP or PORT you should also edit Procfile.dev. For example to be able to run on free Cloud9 IDE we are putting IP 0.0.0.0 and PORT 8080. The default generated file `Procfile.dev` uses `-p 3000`.
|
@@ -218,7 +243,7 @@ end
|
|
218
243
|
Then after all changes are done don't forget to commit them with git and finally you can push your app to Heroku!
|
219
244
|
|
220
245
|
```
|
221
|
-
git add -
|
246
|
+
git add -A
|
222
247
|
git commit -m "Changes for Heroku"
|
223
248
|
git push heroku master
|
224
249
|
```
|
@@ -243,7 +268,7 @@ You can turn on server rendering by simply changing the `prerender` option to `t
|
|
243
268
|
Then push to Heroku:
|
244
269
|
|
245
270
|
```
|
246
|
-
git add -
|
271
|
+
git add -A
|
247
272
|
git commit -m "Enable server rendering"
|
248
273
|
git push heroku master
|
249
274
|
```
|
@@ -36,6 +36,7 @@ module ReactOnRails
|
|
36
36
|
|
37
37
|
def replace_prerender_if_server_rendering
|
38
38
|
return unless options.example_server_rendering
|
39
|
+
|
39
40
|
hello_world_index = File.join(destination_root, "app", "views", "hello_world", "index.html.erb")
|
40
41
|
hello_world_contents = File.read(hello_world_index)
|
41
42
|
new_hello_world_contents = hello_world_contents.gsub(/prerender: false/,
|
@@ -62,6 +62,7 @@ module ReactOnRails
|
|
62
62
|
|
63
63
|
def missing_yarn?
|
64
64
|
return false unless ReactOnRails::Utils.running_on_windows? ? `where yarn`.blank? : `which yarn`.blank?
|
65
|
+
|
65
66
|
error = "yarn is required. Please install it before continuing. https://yarnpkg.com/en/docs/install"
|
66
67
|
GeneratorMessages.add_error(error)
|
67
68
|
true
|
@@ -69,6 +70,7 @@ module ReactOnRails
|
|
69
70
|
|
70
71
|
def missing_node?
|
71
72
|
return false unless ReactOnRails::Utils.running_on_windows? ? `where node`.blank? : `which node`.blank?
|
73
|
+
|
72
74
|
error = "** nodejs is required. Please install it before continuing. https://nodejs.org/en/"
|
73
75
|
GeneratorMessages.add_error(error)
|
74
76
|
true
|
@@ -14,8 +14,15 @@ require "rspec/rails"
|
|
14
14
|
require "capybara/rspec"
|
15
15
|
require "capybara/rails"
|
16
16
|
Capybara.javascript_driver = :selenium_chrome
|
17
|
+
|
18
|
+
# From https://stackoverflow.com/a/56522500/1009332
|
19
|
+
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
|
20
|
+
chromeOptions: { args: %w[headless window-size=1280,800], w3c: false }
|
21
|
+
)
|
17
22
|
Capybara.register_driver :selenium_chrome do |app|
|
18
|
-
Capybara::Selenium::Driver.new(app,
|
23
|
+
Capybara::Selenium::Driver.new(app,
|
24
|
+
browser: :chrome,
|
25
|
+
desired_capabilities: capabilities)
|
19
26
|
end
|
20
27
|
|
21
28
|
# Requires supporting ruby files with custom matchers and macros, etc, in
|
data/lib/react_on_rails.rb
CHANGED
@@ -11,6 +11,7 @@ require "react_on_rails/version"
|
|
11
11
|
require "react_on_rails/version_checker"
|
12
12
|
require "react_on_rails/configuration"
|
13
13
|
require "react_on_rails/server_rendering_pool"
|
14
|
+
require "react_on_rails/server_rendering_js_code"
|
14
15
|
require "react_on_rails/engine"
|
15
16
|
require "react_on_rails/react_component/render_options"
|
16
17
|
require "react_on_rails/version_syntax_converter"
|
@@ -64,6 +64,7 @@ module ReactOnRails
|
|
64
64
|
# references from webpack's CSS would be invalid. The fix is to symlink the double-digested
|
65
65
|
# file back to the original digested name, and make a similar symlink for the gz version.
|
66
66
|
return unless @symlink_non_digested_assets_regex
|
67
|
+
|
67
68
|
manifest_glob = Dir.glob(@assets_path.join(".sprockets-manifest-*.json")) +
|
68
69
|
Dir.glob(@assets_path.join("manifest-*.json")) +
|
69
70
|
Dir.glob(@assets_path.join("manifest.yml"))
|
@@ -86,6 +87,7 @@ module ReactOnRails
|
|
86
87
|
manifest_data.each do |original_filename, rails_digested_filename|
|
87
88
|
# TODO: we should remove any original_filename that is NOT in the webpack deploy folder.
|
88
89
|
next unless original_filename =~ @symlink_non_digested_assets_regex
|
90
|
+
|
89
91
|
# We're symlinking from the digested filename back to the original filename which has
|
90
92
|
# already been symlinked by Webpack
|
91
93
|
symlink_file(rails_digested_filename, original_filename)
|
@@ -100,6 +102,7 @@ module ReactOnRails
|
|
100
102
|
def delete_broken_symlinks
|
101
103
|
Dir.glob(@assets_path.join("*")).each do |filename|
|
102
104
|
next unless File.lstat(filename).symlink?
|
105
|
+
|
103
106
|
begin
|
104
107
|
target = File.readlink(filename)
|
105
108
|
rescue StandardError
|
@@ -21,7 +21,7 @@ module ReactOnRails
|
|
21
21
|
prerender: false,
|
22
22
|
replay_console: true,
|
23
23
|
logging_on_server: true,
|
24
|
-
raise_on_prerender_error:
|
24
|
+
raise_on_prerender_error: Rails.env.development?,
|
25
25
|
trace: Rails.env.development?,
|
26
26
|
development_mode: Rails.env.development?,
|
27
27
|
server_renderer_pool_size: DEFAULT_POOL_SIZE,
|
@@ -218,6 +218,7 @@ module ReactOnRails
|
|
218
218
|
|
219
219
|
def configure_skip_display_none_deprecation
|
220
220
|
return if skip_display_none.nil?
|
221
|
+
|
221
222
|
Rails.logger.warn "[DEPRECATION] ReactOnRails: remove skip_display_none from configuration."
|
222
223
|
end
|
223
224
|
end
|
@@ -6,8 +6,10 @@ module ReactOnRails
|
|
6
6
|
module GitUtils
|
7
7
|
def self.uncommitted_changes?(message_handler)
|
8
8
|
return false if ENV["COVERAGE"] == "true"
|
9
|
+
|
9
10
|
status = `git status --porcelain`
|
10
11
|
return false if $CHILD_STATUS.success? && status.empty?
|
12
|
+
|
11
13
|
error = if !$CHILD_STATUS.success?
|
12
14
|
"You do not have Git installed. Please install Git, and commit your changes before continuing"
|
13
15
|
else
|
@@ -136,7 +136,7 @@ module ReactOnRails
|
|
136
136
|
# It is exactly like react_component except for the following:
|
137
137
|
# 1. prerender: true is automatically added, as this method doesn't make sense for client only
|
138
138
|
# rendering.
|
139
|
-
# 2. Your JavaScript for server rendering must return an Object
|
139
|
+
# 2. Your JavaScript generator function for server rendering must return an Object rather than a React component.
|
140
140
|
# 3. Your view code must expect an object and not a string.
|
141
141
|
#
|
142
142
|
# Here is an example of the view code:
|
@@ -206,6 +206,7 @@ module ReactOnRails
|
|
206
206
|
# that contains a data props.
|
207
207
|
def redux_store_hydration_data
|
208
208
|
return if @registered_stores_defer_render.blank?
|
209
|
+
|
209
210
|
@registered_stores_defer_render.reduce("".dup) do |accum, redux_store_data|
|
210
211
|
accum << render_redux_store_data(redux_store_data)
|
211
212
|
end.html_safe
|
@@ -265,6 +266,7 @@ module ReactOnRails
|
|
265
266
|
|
266
267
|
def json_safe_and_pretty(hash_or_string)
|
267
268
|
return "{}" if hash_or_string.nil?
|
269
|
+
|
268
270
|
unless hash_or_string.is_a?(String) || hash_or_string.is_a?(Hash)
|
269
271
|
raise ReactOnRails::Error, "#{__method__} only accepts String or Hash as argument "\
|
270
272
|
"(#{hash_or_string.class} given)."
|
@@ -275,6 +277,59 @@ module ReactOnRails
|
|
275
277
|
ReactOnRails::JsonOutput.escape(json_value)
|
276
278
|
end
|
277
279
|
|
280
|
+
# This is the definitive list of the default values used for the rails_context, which is the
|
281
|
+
# second parameter passed to both component and store generator functions.
|
282
|
+
# This method can be called from views and from the controller, as `helpers.rails_context`
|
283
|
+
#
|
284
|
+
# rubocop:disable Metrics/AbcSize
|
285
|
+
def rails_context(server_side: true)
|
286
|
+
@rails_context ||= begin
|
287
|
+
result = {
|
288
|
+
railsEnv: Rails.env,
|
289
|
+
inMailer: in_mailer?,
|
290
|
+
# Locale settings
|
291
|
+
i18nLocale: I18n.locale,
|
292
|
+
i18nDefaultLocale: I18n.default_locale,
|
293
|
+
rorVersion: ReactOnRails::VERSION,
|
294
|
+
rorPro: ReactOnRails::Utils.react_on_rails_pro?
|
295
|
+
}
|
296
|
+
if defined?(request) && request.present?
|
297
|
+
# Check for encoding of the request's original_url and try to force-encoding the
|
298
|
+
# URLs as UTF-8. This situation can occur in browsers that do not encode the
|
299
|
+
# entire URL as UTF-8 already, mostly on the Windows platform (IE11 and lower).
|
300
|
+
original_url_normalized = request.original_url
|
301
|
+
if original_url_normalized.encoding.to_s == "ASCII-8BIT"
|
302
|
+
original_url_normalized = original_url_normalized.force_encoding("ISO-8859-1").encode("UTF-8")
|
303
|
+
end
|
304
|
+
|
305
|
+
# Using Addressable instead of standard URI to better deal with
|
306
|
+
# non-ASCII characters (see https://github.com/shakacode/react_on_rails/pull/405)
|
307
|
+
uri = Addressable::URI.parse(original_url_normalized)
|
308
|
+
# uri = Addressable::URI.parse("http://foo.com:3000/posts?id=30&limit=5#time=1305298413")
|
309
|
+
|
310
|
+
result.merge!(
|
311
|
+
# URL settings
|
312
|
+
href: uri.to_s,
|
313
|
+
location: "#{uri.path}#{uri.query.present? ? "?#{uri.query}" : ''}",
|
314
|
+
scheme: uri.scheme, # http
|
315
|
+
host: uri.host, # foo.com
|
316
|
+
port: uri.port,
|
317
|
+
pathname: uri.path, # /posts
|
318
|
+
search: uri.query, # id=30&limit=5
|
319
|
+
httpAcceptLanguage: request.env["HTTP_ACCEPT_LANGUAGE"]
|
320
|
+
)
|
321
|
+
end
|
322
|
+
if ReactOnRails.configuration.rendering_extension
|
323
|
+
custom_context = ReactOnRails.configuration.rendering_extension.custom_context(self)
|
324
|
+
result.merge!(custom_context) if custom_context
|
325
|
+
end
|
326
|
+
result
|
327
|
+
end
|
328
|
+
|
329
|
+
@rails_context.merge(serverSide: server_side)
|
330
|
+
end
|
331
|
+
# rubocop:enable Metrics/AbcSize
|
332
|
+
|
278
333
|
private
|
279
334
|
|
280
335
|
def build_react_component_result_for_server_rendered_string(
|
@@ -284,9 +339,15 @@ module ReactOnRails
|
|
284
339
|
render_options: required("render_options")
|
285
340
|
)
|
286
341
|
content_tag_options = render_options.html_options
|
342
|
+
if content_tag_options.key?(:tag)
|
343
|
+
content_tag_options_html_tag = content_tag_options[:tag]
|
344
|
+
content_tag_options.delete(:tag)
|
345
|
+
else
|
346
|
+
content_tag_options_html_tag = "div"
|
347
|
+
end
|
287
348
|
content_tag_options[:id] = render_options.dom_id
|
288
349
|
|
289
|
-
rendered_output = content_tag(
|
350
|
+
rendered_output = content_tag(content_tag_options_html_tag.to_sym,
|
290
351
|
server_rendered_html.html_safe,
|
291
352
|
content_tag_options)
|
292
353
|
|
@@ -405,9 +466,7 @@ module ReactOnRails
|
|
405
466
|
|
406
467
|
# Returns object with values that are NOT html_safe!
|
407
468
|
def server_rendered_react_component(render_options)
|
408
|
-
|
409
|
-
return { "html" => "", "consoleReplayScript" => "" }
|
410
|
-
end
|
469
|
+
return { "html" => "", "consoleReplayScript" => "" } unless render_options.prerender
|
411
470
|
|
412
471
|
react_component_name = render_options.react_component_name
|
413
472
|
props = render_options.props
|
@@ -433,22 +492,13 @@ module ReactOnRails
|
|
433
492
|
#
|
434
493
|
# Read more here: http://timelessrepo.com/json-isnt-a-javascript-subset
|
435
494
|
|
436
|
-
|
437
|
-
|
438
|
-
(
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
name: '#{react_component_name}',
|
444
|
-
domNodeId: '#{render_options.dom_id}',
|
445
|
-
props: props,
|
446
|
-
trace: #{render_options.trace},
|
447
|
-
railsContext: railsContext
|
448
|
-
});
|
449
|
-
})()
|
450
|
-
JS
|
451
|
-
# rubocop:enable Layout/IndentHeredoc
|
495
|
+
js_code = ReactOnRails::ServerRenderingJsCode.server_rendering_component_js_code(
|
496
|
+
props_string: props_string(props).gsub("\u2028", '\u2028').gsub("\u2029", '\u2029'),
|
497
|
+
rails_context: rails_context(server_side: true).to_json,
|
498
|
+
redux_stores: initialize_redux_stores,
|
499
|
+
react_component_name: react_component_name,
|
500
|
+
render_options: render_options
|
501
|
+
)
|
452
502
|
|
453
503
|
begin
|
454
504
|
result = ReactOnRails::ServerRenderingPool.server_render_js_with_console_logging(js_code, render_options)
|
@@ -480,6 +530,7 @@ module ReactOnRails
|
|
480
530
|
JS
|
481
531
|
|
482
532
|
return result unless @registered_stores.present? || @registered_stores_defer_render.present?
|
533
|
+
|
483
534
|
declarations = "var reduxProps, store, storeGenerator;\n".dup
|
484
535
|
all_stores = (@registered_stores || []) + (@registered_stores_defer_render || [])
|
485
536
|
|
@@ -496,58 +547,6 @@ module ReactOnRails
|
|
496
547
|
result
|
497
548
|
end
|
498
549
|
|
499
|
-
# This is the definitive list of the default values used for the rails_context, which is the
|
500
|
-
# second parameter passed to both component and store generator functions.
|
501
|
-
# rubocop:disable Metrics/AbcSize
|
502
|
-
def rails_context(server_side: required("server_side"))
|
503
|
-
@rails_context ||= begin
|
504
|
-
result = {
|
505
|
-
railsEnv: Rails.env,
|
506
|
-
inMailer: in_mailer?,
|
507
|
-
# Locale settings
|
508
|
-
i18nLocale: I18n.locale,
|
509
|
-
i18nDefaultLocale: I18n.default_locale,
|
510
|
-
rorVersion: ReactOnRails::VERSION,
|
511
|
-
rorPro: ReactOnRails::Utils.react_on_rails_pro?
|
512
|
-
}
|
513
|
-
if defined?(request) && request.present?
|
514
|
-
# Check for encoding of the request's original_url and try to force-encoding the
|
515
|
-
# URLs as UTF-8. This situation can occur in browsers that do not encode the
|
516
|
-
# entire URL as UTF-8 already, mostly on the Windows platform (IE11 and lower).
|
517
|
-
original_url_normalized = request.original_url
|
518
|
-
if original_url_normalized.encoding.to_s == "ASCII-8BIT"
|
519
|
-
original_url_normalized = original_url_normalized.force_encoding("ISO-8859-1").encode("UTF-8")
|
520
|
-
end
|
521
|
-
|
522
|
-
# Using Addressable instead of standard URI to better deal with
|
523
|
-
# non-ASCII characters (see https://github.com/shakacode/react_on_rails/pull/405)
|
524
|
-
uri = Addressable::URI.parse(original_url_normalized)
|
525
|
-
# uri = Addressable::URI.parse("http://foo.com:3000/posts?id=30&limit=5#time=1305298413")
|
526
|
-
|
527
|
-
result.merge!(
|
528
|
-
# URL settings
|
529
|
-
href: uri.to_s,
|
530
|
-
location: "#{uri.path}#{uri.query.present? ? "?#{uri.query}" : ''}",
|
531
|
-
scheme: uri.scheme, # http
|
532
|
-
host: uri.host, # foo.com
|
533
|
-
port: uri.port,
|
534
|
-
pathname: uri.path, # /posts
|
535
|
-
search: uri.query, # id=30&limit=5
|
536
|
-
httpAcceptLanguage: request.env["HTTP_ACCEPT_LANGUAGE"]
|
537
|
-
)
|
538
|
-
end
|
539
|
-
if ReactOnRails.configuration.rendering_extension
|
540
|
-
custom_context = ReactOnRails.configuration.rendering_extension.custom_context(self)
|
541
|
-
result.merge!(custom_context) if custom_context
|
542
|
-
end
|
543
|
-
result
|
544
|
-
end
|
545
|
-
|
546
|
-
@rails_context.merge(serverSide: server_side)
|
547
|
-
end
|
548
|
-
|
549
|
-
# rubocop:enable Metrics/AbcSize
|
550
|
-
|
551
550
|
def replay_console_option(val)
|
552
551
|
val.nil? ? ReactOnRails.configuration.replay_console : val
|
553
552
|
end
|