react_on_rails 11.3.0 → 12.0.0.pre.beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.circleci/config.yml +320 -0
- data/.eslintignore +2 -1
- data/.eslintrc +23 -1
- data/.github/FUNDING.yml +1 -0
- data/.gitignore +3 -1
- data/.prettierignore +10 -1
- data/.prettierrc +3 -0
- data/.rubocop.yml +37 -11
- data/.travis.yml +9 -22
- data/CHANGELOG.md +65 -6
- data/CONTRIBUTING.md +60 -71
- data/Gemfile +3 -4
- data/{COMM-LICENSE → REACT-ON-RAILS-PRO-LICENSE} +6 -9
- data/README.md +129 -92
- data/Rakefile +0 -7
- data/SUMMARY.md +7 -11
- data/book.json +5 -5
- data/docs/additional-reading/asset-pipeline.md +8 -16
- data/docs/additional-reading/react-helmet.md +30 -10
- data/docs/additional-reading/react-router.md +52 -75
- data/docs/additional-reading/server-rendering-tips.md +12 -7
- data/docs/api/javascript-api.md +3 -3
- data/docs/api/redux-store-api.md +4 -2
- data/docs/api/view-helpers-api.md +6 -7
- data/docs/basics/configuration.md +83 -69
- data/docs/basics/deployment.md +2 -4
- data/docs/basics/heroku-deployment.md +24 -0
- data/docs/basics/hmr-and-hot-reloading-with-the-webpack-dev-server.md +49 -0
- data/docs/basics/i18n.md +45 -23
- data/docs/basics/installation-into-an-existing-rails-app.md +4 -9
- data/docs/basics/react-server-rendering.md +1 -1
- data/docs/basics/recommended-project-structure.md +5 -22
- data/docs/basics/{generator-functions-and-railscontext.md → render-functions-and-railscontext.md} +59 -21
- data/docs/basics/rspec-configuration.md +27 -16
- data/docs/basics/upgrading-react-on-rails.md +58 -2
- data/docs/basics/webpack-configuration.md +18 -8
- data/docs/contributor-info/errors-with-hooks.md +45 -0
- data/docs/contributor-info/pull-requests.md +44 -0
- data/docs/misc/doctrine.md +1 -1
- data/docs/{misc-pending → outdated}/code-splitting.md +12 -8
- data/docs/{basics → outdated}/how-react-on-rails-works.md +8 -4
- data/docs/{misc-pending → outdated}/manual-installation-overview.md +5 -5
- data/docs/{additional-reading → outdated}/rails-assets-relative-paths.md +3 -3
- data/docs/{misc-pending → outdated}/rails-assets.md +2 -12
- data/docs/{misc → outdated}/rails3.md +0 -0
- data/docs/tutorial.md +94 -68
- data/jest.config.js +4 -0
- data/lib/generators/react_on_rails/base_generator.rb +2 -2
- data/lib/generators/react_on_rails/dev_tests_generator.rb +1 -1
- data/lib/generators/react_on_rails/generator_helper.rb +4 -6
- data/lib/generators/react_on_rails/templates/base/base/Procfile.dev +3 -1
- data/lib/generators/react_on_rails/templates/base/base/Procfile.dev-hmr +26 -0
- data/lib/generators/react_on_rails/templates/base/base/app/javascript/bundles/HelloWorld/components/HelloWorld.jsx +20 -40
- data/lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb +4 -1
- data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/components/HelloWorld.jsx +4 -8
- data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/store/helloWorldStore.js +1 -3
- data/lib/react_on_rails.rb +3 -1
- data/lib/react_on_rails/configuration.rb +58 -28
- data/lib/react_on_rails/error.rb +2 -0
- data/lib/react_on_rails/helper.rb +41 -91
- data/lib/react_on_rails/json_parse_error.rb +2 -0
- data/lib/react_on_rails/locales/base.rb +150 -0
- data/lib/react_on_rails/locales/to_js.rb +37 -0
- data/lib/react_on_rails/locales/to_json.rb +27 -0
- data/lib/react_on_rails/prerender_error.rb +11 -15
- data/lib/react_on_rails/server_rendering_pool/ruby_embedded_java_script.rb +41 -46
- data/lib/react_on_rails/test_helper/ensure_assets_compiled.rb +7 -8
- data/lib/react_on_rails/test_helper/webpack_assets_compiler.rb +17 -0
- data/lib/react_on_rails/utils.rb +14 -19
- data/lib/react_on_rails/version.rb +1 -1
- data/lib/react_on_rails/version_checker.rb +1 -0
- data/lib/react_on_rails/webpacker_utils.rb +19 -2
- data/lib/tasks/assets.rake +33 -46
- data/lib/tasks/locale.rake +4 -2
- data/package-scripts.yml +11 -8
- data/package.json +29 -28
- data/rakelib/dummy_apps.rake +1 -9
- data/rakelib/example_type.rb +3 -1
- data/rakelib/examples.rake +3 -0
- data/rakelib/lint.rake +2 -7
- data/rakelib/node_package.rake +2 -2
- data/rakelib/release.rake +0 -6
- data/rakelib/run_rspec.rake +5 -18
- data/react_on_rails.gemspec +4 -5
- data/tsconfig.json +14 -0
- data/webpackConfigLoader.js +3 -2
- data/yarn.lock +4333 -2209
- metadata +46 -57
- data/Gemfile.rails32 +0 -73
- data/docs/additional-reading/babel.md +0 -5
- data/docs/additional-reading/heroku-deployment.md +0 -92
- data/docs/additional-reading/hot-reloading-rails-development-asset-pipeline.md +0 -47
- data/docs/api/ruby-api-hot-reload-view-helpers.md +0 -44
- data/lib/generators/react_on_rails/templates/base/base/Procfile.dev-server +0 -12
- data/lib/react_on_rails/assets_precompile.rb +0 -153
- data/lib/react_on_rails/locales_to_js.rb +0 -138
data/jest.config.js
ADDED
@@ -33,7 +33,7 @@ module ReactOnRails
|
|
33
33
|
app/views/layouts/hello_world.html.erb
|
34
34
|
config/initializers/react_on_rails.rb
|
35
35
|
Procfile.dev
|
36
|
-
Procfile.dev-
|
36
|
+
Procfile.dev-hmr]
|
37
37
|
base_files.each { |file| copy_file("#{base_path}#{file}", file) }
|
38
38
|
end
|
39
39
|
|
@@ -107,7 +107,7 @@ module ReactOnRails
|
|
107
107
|
foreman start -f Procfile.dev
|
108
108
|
|
109
109
|
- To turn on HMR, edit config/webpacker.yml and set HMR to true. Restart the rails server
|
110
|
-
and bin/webpack-dev-server. Or use Procfile.dev-
|
110
|
+
and bin/webpack-dev-server. Or use Procfile.dev-hmr.
|
111
111
|
|
112
112
|
- To server render, change this line app/views/hello_world/index.html.erb to
|
113
113
|
`prerender: true` to see server rendering (right click on page and select "view source").
|
@@ -50,7 +50,7 @@ module ReactOnRails
|
|
50
50
|
contents = File.read(package_json)
|
51
51
|
replacement_value = <<-STRING
|
52
52
|
"scripts": {
|
53
|
-
"postinstall": "
|
53
|
+
"postinstall": "yalc link react-on-rails",
|
54
54
|
STRING
|
55
55
|
new_client_package_json_contents = contents.gsub(/ {2}"scripts": {/,
|
56
56
|
replacement_value)
|
@@ -15,13 +15,11 @@ module GeneratorHelper
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def setup_file_error(file, data)
|
18
|
-
|
19
|
-
|
20
|
-
#{file}
|
21
|
-
|
22
|
-
#{data}
|
18
|
+
<<~MSG
|
19
|
+
#{file} was not found.
|
20
|
+
Please add the following content to your #{file} file:
|
21
|
+
#{data}
|
23
22
|
MSG
|
24
|
-
# rubocop:enable Layout/IndentHeredoc
|
25
23
|
end
|
26
24
|
|
27
25
|
def empty_directory_with_keep_file(destination, config = {})
|
@@ -4,4 +4,6 @@ web: rails s -p 3000
|
|
4
4
|
# Next line runs a watch process with webpack to compile the changed files.
|
5
5
|
# When making frequent changes to client side assets, you will prefer building webpack assets
|
6
6
|
# upon saving rather than when you refresh your browser page.
|
7
|
-
|
7
|
+
# Note, if using React on Rails localization you will need to run
|
8
|
+
# `bundle exec rake react_on_rails:locale` before you run bin/webpack
|
9
|
+
client: sh -c 'rm -rf public/packs/* || true && bin/webpack -w'
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Procfile for development using HMR
|
2
|
+
|
3
|
+
web: rails s -p 3000
|
4
|
+
|
5
|
+
# Note, hot and live reloading don't work with the default generator setup on
|
6
|
+
# top of the rails/webpacker Webpack config with server rendering.
|
7
|
+
# If you have server rendering enabled (prerender is true), you either need to
|
8
|
+
# a. Ensure that you have dev_server.hmr and dev_server.inline BOTH set to false,
|
9
|
+
# and you have this option in your config/initializers/react_on_rails.rb:
|
10
|
+
# config.same_bundle_for_client_and_server = true
|
11
|
+
# If you have either config/webpacker.yml option set to true, you'll see errors like
|
12
|
+
# "ReferenceError: window is not defined" (if hmr is true)
|
13
|
+
# "TypeError: Cannot read property 'prototype' of undefined" (if inline is true)
|
14
|
+
# b. Skip using the webpack-dev-server. bin/webpack --watch is typically
|
15
|
+
fast enough.
|
16
|
+
# c. See the React on Rails README for a link to documentation for how to setup
|
17
|
+
# SSR with HMR and React hot loading using the webpack-dev-server only for the
|
18
|
+
# client bundles and a static file for the server bundle.
|
19
|
+
|
20
|
+
# Run the webpack-dev-server for client and maybe server files
|
21
|
+
webpack-dev-server: bin/webpack-dev-server
|
22
|
+
|
23
|
+
# Keep the JS fresh for server rendering. Remove if not server rendering.
|
24
|
+
# Especially if you have not configured generation of a server bundle without a hash.
|
25
|
+
# as that will conflict with the manifest created by the bin/webpack-dev-server
|
26
|
+
# rails-server-assets: SERVER_BUNDLE_ONLY=yes bin/webpack --watch
|
@@ -1,45 +1,25 @@
|
|
1
1
|
import PropTypes from 'prop-types';
|
2
|
-
import React from 'react';
|
2
|
+
import React, { useState } from 'react';
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
name: PropTypes.string.isRequired, // this is passed from the Rails view
|
7
|
-
};
|
4
|
+
const HelloWorld = (props) => {
|
5
|
+
const [name, setName] = useState(props.name);
|
8
6
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
7
|
+
return (
|
8
|
+
<div>
|
9
|
+
<h3>Hello, {name}!</h3>
|
10
|
+
<hr />
|
11
|
+
<form>
|
12
|
+
<label htmlFor="name">
|
13
|
+
Say hello to:
|
14
|
+
<input id="name" type="text" value={name} onChange={(e) => setName(e.target.value)} />
|
15
|
+
</label>
|
16
|
+
</form>
|
17
|
+
</div>
|
18
|
+
);
|
19
|
+
};
|
14
20
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
}
|
21
|
+
HelloWorld.propTypes = {
|
22
|
+
name: PropTypes.string.isRequired, // this is passed from the Rails view
|
23
|
+
};
|
19
24
|
|
20
|
-
|
21
|
-
this.setState({ name });
|
22
|
-
};
|
23
|
-
|
24
|
-
render() {
|
25
|
-
return (
|
26
|
-
<div>
|
27
|
-
<h3>
|
28
|
-
Hello, {this.state.name}!
|
29
|
-
</h3>
|
30
|
-
<hr />
|
31
|
-
<form >
|
32
|
-
<label htmlFor="name">
|
33
|
-
Say hello to:
|
34
|
-
</label>
|
35
|
-
<input
|
36
|
-
id="name"
|
37
|
-
type="text"
|
38
|
-
value={this.state.name}
|
39
|
-
onChange={(e) => this.updateName(e.target.value)}
|
40
|
-
/>
|
41
|
-
</form>
|
42
|
-
</div>
|
43
|
-
);
|
44
|
-
}
|
45
|
-
}
|
25
|
+
export default HelloWorld;
|
data/lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb
CHANGED
@@ -6,7 +6,8 @@
|
|
6
6
|
ReactOnRails.configure do |config|
|
7
7
|
# This configures the script to run to build the production assets by webpack. Set this to nil
|
8
8
|
# if you don't want react_on_rails building this file for you.
|
9
|
-
|
9
|
+
# If nil, then the standard rails/webpacker assets:precompile will run
|
10
|
+
# config.build_production_command = nil
|
10
11
|
|
11
12
|
################################################################################
|
12
13
|
################################################################################
|
@@ -22,6 +23,8 @@ ReactOnRails.configure do |config|
|
|
22
23
|
# with rspec then this controls what yarn command is run
|
23
24
|
# to automatically refresh your webpack assets on every test run.
|
24
25
|
#
|
26
|
+
# Alternately, you can remove the `ReactOnRails::TestHelper.configure_rspec_to_compile_assets`
|
27
|
+
# and set the config/webpacker.yml option for test to true.
|
25
28
|
config.build_test_command = "RAILS_ENV=test bin/webpack"
|
26
29
|
|
27
30
|
################################################################################
|
@@ -4,19 +4,15 @@ import React from 'react';
|
|
4
4
|
const HelloWorld = ({ name, updateName }) => (
|
5
5
|
<div>
|
6
6
|
<h3>
|
7
|
-
Hello,
|
7
|
+
Hello,
|
8
|
+
{name}!
|
8
9
|
</h3>
|
9
10
|
<hr />
|
10
|
-
<form
|
11
|
+
<form>
|
11
12
|
<label htmlFor="name">
|
12
13
|
Say hello to:
|
14
|
+
<input id="name" type="text" value={name} onChange={(e) => updateName(e.target.value)} />
|
13
15
|
</label>
|
14
|
-
<input
|
15
|
-
id="name"
|
16
|
-
type="text"
|
17
|
-
value={name}
|
18
|
-
onChange={(e) => updateName(e.target.value)}
|
19
|
-
/>
|
20
16
|
</form>
|
21
17
|
</div>
|
22
18
|
);
|
@@ -1,8 +1,6 @@
|
|
1
1
|
import { createStore } from 'redux';
|
2
2
|
import helloWorldReducer from '../reducers/helloWorldReducer';
|
3
3
|
|
4
|
-
const configureStore = (railsProps) => (
|
5
|
-
createStore(helloWorldReducer, railsProps)
|
6
|
-
);
|
4
|
+
const configureStore = (railsProps) => createStore(helloWorldReducer, railsProps);
|
7
5
|
|
8
6
|
export default configureStore;
|
data/lib/react_on_rails.rb
CHANGED
@@ -22,4 +22,6 @@ require "react_on_rails/webpacker_utils"
|
|
22
22
|
require "react_on_rails/test_helper/webpack_assets_compiler"
|
23
23
|
require "react_on_rails/test_helper/webpack_assets_status_checker"
|
24
24
|
require "react_on_rails/test_helper/ensure_assets_compiled"
|
25
|
-
require "react_on_rails/
|
25
|
+
require "react_on_rails/locales/base"
|
26
|
+
require "react_on_rails/locales/to_js"
|
27
|
+
require "react_on_rails/locales/to_json"
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rubocop:disable Metrics/ClassLength
|
4
|
+
|
3
5
|
module ReactOnRails
|
4
6
|
def self.configure
|
5
7
|
yield(configuration)
|
@@ -31,10 +33,11 @@ module ReactOnRails
|
|
31
33
|
webpack_generated_files: %w[manifest.json],
|
32
34
|
rendering_extension: nil,
|
33
35
|
server_render_method: nil,
|
34
|
-
symlink_non_digested_assets_regex: nil,
|
35
36
|
build_test_command: "",
|
36
37
|
build_production_command: "",
|
37
|
-
random_dom_id: DEFAULT_RANDOM_DOM_ID
|
38
|
+
random_dom_id: DEFAULT_RANDOM_DOM_ID,
|
39
|
+
same_bundle_for_client_and_server: false,
|
40
|
+
i18n_output_format: nil
|
38
41
|
)
|
39
42
|
end
|
40
43
|
|
@@ -46,8 +49,9 @@ module ReactOnRails
|
|
46
49
|
:generated_assets_dirs, :generated_assets_dir,
|
47
50
|
:webpack_generated_files, :rendering_extension, :build_test_command,
|
48
51
|
:build_production_command,
|
49
|
-
:i18n_dir, :i18n_yml_dir,
|
50
|
-
:server_render_method, :
|
52
|
+
:i18n_dir, :i18n_yml_dir, :i18n_output_format,
|
53
|
+
:server_render_method, :random_dom_id,
|
54
|
+
:same_bundle_for_client_and_server
|
51
55
|
|
52
56
|
def initialize(node_modules_location: nil, server_bundle_js_file: nil, prerender: nil,
|
53
57
|
replay_console: nil,
|
@@ -58,16 +62,17 @@ module ReactOnRails
|
|
58
62
|
generated_assets_dir: nil, webpack_generated_files: nil,
|
59
63
|
rendering_extension: nil, build_test_command: nil,
|
60
64
|
build_production_command: nil,
|
61
|
-
|
62
|
-
|
65
|
+
same_bundle_for_client_and_server: nil,
|
66
|
+
i18n_dir: nil, i18n_yml_dir: nil, i18n_output_format: nil,
|
67
|
+
random_dom_id: nil, server_render_method: nil)
|
63
68
|
self.node_modules_location = node_modules_location.present? ? node_modules_location : Rails.root
|
64
|
-
self.server_bundle_js_file = server_bundle_js_file
|
65
69
|
self.generated_assets_dirs = generated_assets_dirs
|
66
70
|
self.generated_assets_dir = generated_assets_dir
|
67
71
|
self.build_test_command = build_test_command
|
68
72
|
self.build_production_command = build_production_command
|
69
73
|
self.i18n_dir = i18n_dir
|
70
74
|
self.i18n_yml_dir = i18n_yml_dir
|
75
|
+
self.i18n_output_format = i18n_output_format
|
71
76
|
|
72
77
|
self.random_dom_id = random_dom_id
|
73
78
|
self.prerender = prerender
|
@@ -83,6 +88,8 @@ module ReactOnRails
|
|
83
88
|
self.skip_display_none = skip_display_none
|
84
89
|
|
85
90
|
# Server rendering:
|
91
|
+
self.server_bundle_js_file = server_bundle_js_file
|
92
|
+
self.same_bundle_for_client_and_server = same_bundle_for_client_and_server
|
86
93
|
self.server_renderer_pool_size = self.development_mode ? 1 : server_renderer_pool_size
|
87
94
|
self.server_renderer_timeout = server_renderer_timeout # seconds
|
88
95
|
|
@@ -90,7 +97,6 @@ module ReactOnRails
|
|
90
97
|
self.rendering_extension = rendering_extension
|
91
98
|
|
92
99
|
self.server_render_method = server_render_method
|
93
|
-
self.symlink_non_digested_assets_regex = symlink_non_digested_assets_regex
|
94
100
|
end
|
95
101
|
|
96
102
|
# on ReactOnRails
|
@@ -99,15 +105,50 @@ module ReactOnRails
|
|
99
105
|
configure_generated_assets_dirs_deprecation
|
100
106
|
configure_skip_display_none_deprecation
|
101
107
|
ensure_generated_assets_dir_present
|
102
|
-
ensure_server_bundle_js_file_has_no_path
|
103
108
|
check_i18n_directory_exists
|
104
109
|
check_i18n_yml_directory_exists
|
105
110
|
check_server_render_method_is_only_execjs
|
106
111
|
error_if_using_webpacker_and_generated_assets_dir_not_match_public_output_path
|
112
|
+
check_deprecated_settings
|
107
113
|
end
|
108
114
|
|
109
115
|
private
|
110
116
|
|
117
|
+
def check_deprecated_settings
|
118
|
+
if build_production_command.present? &&
|
119
|
+
ReactOnRails::WebpackerUtils.webpacker_webpack_production_config_exists?
|
120
|
+
msg = <<~MSG
|
121
|
+
Setting ReactOnRails configuration for `build_production_command` is
|
122
|
+
not necessary if you have config/webpack/production.js. When that file
|
123
|
+
exists, React on Rails DOES NOT modify the standard assets:precompile.
|
124
|
+
If you want React on Rails to modify to the standard assets:precompile
|
125
|
+
to use your config/initializers/react_on_rails.rb config.build_production_command
|
126
|
+
then delete the config/webpack/production.js.
|
127
|
+
MSG
|
128
|
+
Rails.logger.warn(msg)
|
129
|
+
end
|
130
|
+
#
|
131
|
+
# msg = <<~MSG
|
132
|
+
# ReactOnRails configuration for `build_production_command` is removed.
|
133
|
+
# Move this command into `bin/webpack` converting the script to a shell script.
|
134
|
+
# MSG
|
135
|
+
# raise ReactOnRails::Error, msg
|
136
|
+
# Commenting out until v13 when
|
137
|
+
# https://github.com/rails/webpacker/issues/2640 gets resolved
|
138
|
+
# if node_modules_location.present?
|
139
|
+
# Rails.logger.warn("ReactOnRails configuration for `node_modules_location` is deprecated. "\
|
140
|
+
# "Instead, prepend a `cd client` (or whichever location) before your test command.")
|
141
|
+
# end
|
142
|
+
#
|
143
|
+
# return unless build_production_command.present?
|
144
|
+
#
|
145
|
+
# msg = <<~MSG
|
146
|
+
# ReactOnRails configuration for `build_production_command` is removed.
|
147
|
+
# Move this command into `bin/webpack` converting the script to a shell script.
|
148
|
+
# MSG
|
149
|
+
# raise ReactOnRails::Error, msg
|
150
|
+
end
|
151
|
+
|
111
152
|
def error_if_using_webpacker_and_generated_assets_dir_not_match_public_output_path
|
112
153
|
return unless ReactOnRails::WebpackerUtils.using_webpacker?
|
113
154
|
|
@@ -119,12 +160,12 @@ module ReactOnRails
|
|
119
160
|
Rails.logger.warn("You specified generated_assets_dir in `config/initializers/react_on_rails.rb` "\
|
120
161
|
"with Webpacker. Remove this line from your configuration file.")
|
121
162
|
else
|
122
|
-
msg =
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
163
|
+
msg = <<~MSG
|
164
|
+
Error configuring /config/initializers/react_on_rails.rb: You are using webpacker
|
165
|
+
and your specified value for generated_assets_dir = #{generated_assets_dir}
|
166
|
+
that does not match the value for public_output_path specified in
|
167
|
+
webpacker.yml = #{webpacker_public_output_path}. You should remove the configuration
|
168
|
+
value for "generated_assets_dir" from your config/initializers/react_on_rails.rb file.
|
128
169
|
MSG
|
129
170
|
raise ReactOnRails::Error, msg
|
130
171
|
end
|
@@ -198,24 +239,12 @@ module ReactOnRails
|
|
198
239
|
def ensure_webpack_generated_files_exists
|
199
240
|
return unless webpack_generated_files.empty?
|
200
241
|
|
201
|
-
files = ["
|
242
|
+
files = ["manifest.json"]
|
202
243
|
files << server_bundle_js_file if server_bundle_js_file.present?
|
203
244
|
|
204
245
|
self.webpack_generated_files = files
|
205
246
|
end
|
206
247
|
|
207
|
-
def ensure_server_bundle_js_file_has_no_path
|
208
|
-
return unless server_bundle_js_file.include?(File::SEPARATOR)
|
209
|
-
|
210
|
-
assets_dir = ReactOnRails::Utils.generated_assets_full_path
|
211
|
-
self.server_bundle_js_file = File.basename(server_bundle_js_file)
|
212
|
-
|
213
|
-
Rails.logger.warn do
|
214
|
-
"[DEPRECATION] ReactOnRails: remove path from server_bundle_js_file in configuration. "\
|
215
|
-
"All generated files must go in #{assets_dir}. Using file basename #{server_bundle_js_file}"
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
248
|
def configure_skip_display_none_deprecation
|
220
249
|
return if skip_display_none.nil?
|
221
250
|
|
@@ -223,3 +252,4 @@ module ReactOnRails
|
|
223
252
|
end
|
224
253
|
end
|
225
254
|
end
|
255
|
+
# rubocop:enable Metrics/ClassLength
|
data/lib/react_on_rails/error.rb
CHANGED
@@ -15,68 +15,20 @@ module ReactOnRails
|
|
15
15
|
module Helper
|
16
16
|
include ReactOnRails::Utils::Required
|
17
17
|
|
18
|
-
COMPONENT_HTML_KEY = "componentHtml"
|
18
|
+
COMPONENT_HTML_KEY = "componentHtml"
|
19
19
|
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
20
|
+
# react_component_name: can be a React function or class component or a "render function".
|
21
|
+
# "render functions" differ from a React function in that they take two parameters, the
|
22
|
+
# props and the railsContext, like this:
|
23
23
|
#
|
24
|
-
#
|
25
|
-
# these params are optional, and support either a single value, or an array.
|
24
|
+
# let MyReactComponentApp = (props, railsContext) => <MyReactComponent {...props}/>;
|
26
25
|
#
|
27
|
-
#
|
28
|
-
#
|
26
|
+
# Alternately, you can define the render function with an additional property
|
27
|
+
# `.renderFunction = true`:
|
29
28
|
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
# media: 'all',
|
33
|
-
# 'data-turbolinks-track' => "reload") %>
|
29
|
+
# let MyReactComponentApp = (props) => <MyReactComponent {...props}/>;
|
30
|
+
# MyReactComponent.renderFunction = true;
|
34
31
|
#
|
35
|
-
# <!-- These do not use turbolinks, so no data-turbolinks-track -->
|
36
|
-
# <!-- This is to load the hot assets. -->
|
37
|
-
# <%= env_javascript_include_tag(hot: ['http://localhost:3500/vendor-bundle.js',
|
38
|
-
# 'http://localhost:3500/app-bundle.js']) %>
|
39
|
-
#
|
40
|
-
# <!-- These do use turbolinks -->
|
41
|
-
# <%= env_javascript_include_tag(static: 'application_static',
|
42
|
-
# hot: 'application_non_webpack',
|
43
|
-
# 'data-turbolinks-track' => "reload") %>
|
44
|
-
#
|
45
|
-
# NOTE: for Turbolinks 2.x, use 'data-turbolinks-track' => true
|
46
|
-
# See application.html.erb for usage example
|
47
|
-
# https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/app%2Fviews%2Flayouts%2Fapplication.html.erb
|
48
|
-
def env_javascript_include_tag(args = {})
|
49
|
-
send_tag_method(:javascript_include_tag, args)
|
50
|
-
end
|
51
|
-
|
52
|
-
# Helper to set CSS assets depending on if we want static or "hot", which means from the
|
53
|
-
# Webpack dev server.
|
54
|
-
#
|
55
|
-
# In this example, application_non_webpack is simply a CSS asset pipeline file which includes
|
56
|
-
# styles not placed in the webpack build.
|
57
|
-
#
|
58
|
-
# We don't need styles from the webpack build, as those will come via the JavaScript include
|
59
|
-
# tags.
|
60
|
-
#
|
61
|
-
# The key options are `static` and `hot` which specify what you want for static vs. hot. Both of
|
62
|
-
# these params are optional, and support either a single value, or an array.
|
63
|
-
#
|
64
|
-
# <%= env_stylesheet_link_tag(static: 'application_static',
|
65
|
-
# hot: 'application_non_webpack',
|
66
|
-
# media: 'all',
|
67
|
-
# 'data-turbolinks-track' => true) %>
|
68
|
-
#
|
69
|
-
def env_stylesheet_link_tag(args = {})
|
70
|
-
send_tag_method(:stylesheet_link_tag, args)
|
71
|
-
end
|
72
|
-
|
73
|
-
# react_component_name: can be a React component, created using a ES6 class, or
|
74
|
-
# React.createClass, or a
|
75
|
-
# `generator function` that returns a React component
|
76
|
-
# using ES6
|
77
|
-
# let MyReactComponentApp = (props, railsContext) => <MyReactComponent {...props}/>;
|
78
|
-
# or using ES5
|
79
|
-
# var MyReactComponentApp = function(props, railsContext) { return <YourReactComponent {...props}/>; }
|
80
32
|
# Exposing the react_component_name is necessary to both a plain ReactComponent as well as
|
81
33
|
# a generator:
|
82
34
|
# See README.md for how to "register" your react components.
|
@@ -98,7 +50,8 @@ module ReactOnRails
|
|
98
50
|
# raise_on_prerender_error: <true/false> Default to false. True will raise exception on server
|
99
51
|
# if the JS code throws
|
100
52
|
# Any other options are passed to the content tag, including the id.
|
101
|
-
# random_dom_id can be set to override the
|
53
|
+
# random_dom_id can be set to override the default from the config/initializers. That's only
|
54
|
+
# used if you have multiple instance of the same component on the Rails view.
|
102
55
|
def react_component(component_name, options = {})
|
103
56
|
internal_result = internal_react_component(component_name, options)
|
104
57
|
server_rendered_html = internal_result[:result]["html"]
|
@@ -112,20 +65,24 @@ module ReactOnRails
|
|
112
65
|
render_options: internal_result[:render_options]
|
113
66
|
)
|
114
67
|
elsif server_rendered_html.is_a?(Hash)
|
115
|
-
msg =
|
116
|
-
|
117
|
-
|
118
|
-
|
68
|
+
msg = <<~MSG
|
69
|
+
Use react_component_hash (not react_component) to return a Hash to your ruby view code. See
|
70
|
+
https://github.com/shakacode/react_on_rails/blob/master/spec/dummy/client/app/startup/ReactHelmetServerApp.jsx
|
71
|
+
for an example of the necessary javascript configuration.
|
119
72
|
MSG
|
120
73
|
raise ReactOnRails::Error, msg
|
121
|
-
|
122
74
|
else
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
75
|
+
class_name = server_rendered_html.class.name
|
76
|
+
msg = <<~MSG
|
77
|
+
ReactOnRails: server_rendered_html is expected to be a String or Hash for #{component_name}.
|
78
|
+
Type is #{class_name}
|
79
|
+
Value:
|
80
|
+
#{server_rendered_html}
|
81
|
+
|
82
|
+
If you're trying to use a render function to return a Hash to your ruby view code, then use
|
83
|
+
react_component_hash instead of react_component and see
|
84
|
+
https://github.com/shakacode/react_on_rails/blob/master/spec/dummy/client/app/startup/ReactHelmetServerApp.jsx
|
85
|
+
for an example of the JavaScript code.
|
129
86
|
MSG
|
130
87
|
raise ReactOnRails::Error, msg
|
131
88
|
end
|
@@ -136,7 +93,7 @@ module ReactOnRails
|
|
136
93
|
# It is exactly like react_component except for the following:
|
137
94
|
# 1. prerender: true is automatically added, as this method doesn't make sense for client only
|
138
95
|
# rendering.
|
139
|
-
# 2. Your JavaScript
|
96
|
+
# 2. Your JavaScript render function for server rendering must return an Object rather than a React component.
|
140
97
|
# 3. Your view code must expect an object and not a string.
|
141
98
|
#
|
142
99
|
# Here is an example of the view code:
|
@@ -166,10 +123,12 @@ module ReactOnRails
|
|
166
123
|
render_options: internal_result[:render_options]
|
167
124
|
)
|
168
125
|
else
|
169
|
-
msg =
|
170
|
-
|
126
|
+
msg = <<~MSG
|
127
|
+
render function used by react_component_hash for #{component_name} is expected to return
|
171
128
|
an Object. See https://github.com/shakacode/react_on_rails/blob/master/spec/dummy/client/app/startup/ReactHelmetServerApp.jsx
|
172
|
-
for an example of the JavaScript code.
|
129
|
+
for an example of the JavaScript code.
|
130
|
+
Note, your render function must either take 2 params or have the property
|
131
|
+
`.renderFunction = true` added to it to distinguish it from a React Function Component.
|
173
132
|
MSG
|
174
133
|
raise ReactOnRails::Error, msg
|
175
134
|
end
|
@@ -178,6 +137,9 @@ module ReactOnRails
|
|
178
137
|
# Separate initialization of store from react_component allows multiple react_component calls to
|
179
138
|
# use the same Redux store.
|
180
139
|
#
|
140
|
+
# NOTE: This technique not recommended as it prevents dynamic code splitting for performance.
|
141
|
+
# Instead, you should use the standard react_component view helper.
|
142
|
+
#
|
181
143
|
# store_name: name of the store, corresponding to your call to ReactOnRails.registerStores in your
|
182
144
|
# JavaScript code.
|
183
145
|
# props: Ruby Hash or JSON string which contains the properties to pass to the redux store.
|
@@ -278,11 +240,12 @@ module ReactOnRails
|
|
278
240
|
end
|
279
241
|
|
280
242
|
# 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
|
243
|
+
# second parameter passed to both component and store render functions.
|
282
244
|
# This method can be called from views and from the controller, as `helpers.rails_context`
|
283
245
|
#
|
284
246
|
# rubocop:disable Metrics/AbcSize
|
285
247
|
def rails_context(server_side: true)
|
248
|
+
# ALERT: Keep in sync with node_package/src/types/index.ts for the properties of RailsContext
|
286
249
|
@rails_context ||= begin
|
287
250
|
result = {
|
288
251
|
railsEnv: Rails.env,
|
@@ -395,13 +358,11 @@ module ReactOnRails
|
|
395
358
|
|
396
359
|
def compose_react_component_html_with_spec_and_console(component_specification_tag, rendered_output, console_script)
|
397
360
|
# IMPORTANT: Ensure that we mark string as html_safe to avoid escaping.
|
398
|
-
|
399
|
-
|
400
|
-
#{
|
401
|
-
|
402
|
-
#{console_script}
|
361
|
+
<<~HTML.html_safe
|
362
|
+
#{rendered_output}
|
363
|
+
#{component_specification_tag}
|
364
|
+
#{console_script}
|
403
365
|
HTML
|
404
|
-
# rubocop:enable Layout/IndentHeredoc
|
405
366
|
end
|
406
367
|
|
407
368
|
# prepend the rails_context if not yet applied
|
@@ -551,17 +512,6 @@ module ReactOnRails
|
|
551
512
|
val.nil? ? ReactOnRails.configuration.replay_console : val
|
552
513
|
end
|
553
514
|
|
554
|
-
def use_hot_reloading?
|
555
|
-
ENV["REACT_ON_RAILS_ENV"] == "HOT"
|
556
|
-
end
|
557
|
-
|
558
|
-
def send_tag_method(tag_method_name, args)
|
559
|
-
asset_type = use_hot_reloading? ? :hot : :static
|
560
|
-
assets = Array(args[asset_type])
|
561
|
-
options = args.delete_if { |key, _value| %i[hot static].include?(key) }
|
562
|
-
send(tag_method_name, *assets, options) unless assets.empty?
|
563
|
-
end
|
564
|
-
|
565
515
|
def in_mailer?
|
566
516
|
return false unless defined?(controller)
|
567
517
|
return false unless defined?(ActionMailer::Base)
|