react_on_rails 12.4.0 → 12.6.0

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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +2 -1
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +23 -0
  4. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  5. data/.github/workflows/main.yml +3 -3
  6. data/.gitignore +0 -3
  7. data/.prettierignore +2 -0
  8. data/CHANGELOG.md +32 -2
  9. data/Gemfile.development_dependencies +7 -6
  10. data/REACT-ON-RAILS-PRO-LICENSE +1 -1
  11. data/README.md +22 -12
  12. data/SUMMARY.md +9 -0
  13. data/docs/deployment/heroku-deployment.md +16 -5
  14. data/docs/guides/configuration.md +26 -12
  15. data/docs/guides/how-react-on-rails-works.md +0 -1
  16. data/docs/guides/tutorial.md +18 -14
  17. data/lib/generators/react_on_rails/base_generator.rb +46 -3
  18. data/lib/generators/react_on_rails/generator_helper.rb +4 -0
  19. data/lib/generators/react_on_rails/templates/.eslintrc +3 -1
  20. data/lib/generators/react_on_rails/templates/base/base/Procfile.dev +4 -8
  21. data/lib/generators/react_on_rails/templates/base/base/Procfile.dev-static +9 -0
  22. data/lib/generators/react_on_rails/templates/base/base/app/javascript/bundles/HelloWorld/components/HelloWorld.jsx +2 -1
  23. data/lib/generators/react_on_rails/templates/base/base/app/javascript/bundles/HelloWorld/components/HelloWorld.module.css +4 -0
  24. data/lib/generators/react_on_rails/templates/base/base/app/javascript/bundles/HelloWorld/components/HelloWorldServer.js +5 -0
  25. data/lib/generators/react_on_rails/templates/base/base/app/javascript/packs/server-bundle.js +8 -0
  26. data/lib/generators/react_on_rails/templates/base/base/app/views/layouts/hello_world.html.erb +1 -0
  27. data/lib/generators/react_on_rails/templates/base/base/babel.config.js.tt +15 -0
  28. data/lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb +1 -1
  29. data/lib/generators/react_on_rails/templates/base/base/config/webpack/clientWebpackConfig.js.tt +17 -0
  30. data/lib/generators/react_on_rails/templates/base/base/config/webpack/commonWebpackConfig.js.tt +15 -0
  31. data/lib/generators/react_on_rails/templates/base/base/config/webpack/development.js.tt +27 -0
  32. data/lib/generators/react_on_rails/templates/base/base/config/webpack/production.js.tt +11 -0
  33. data/lib/generators/react_on_rails/templates/base/base/config/webpack/serverWebpackConfig.js.tt +117 -0
  34. data/lib/generators/react_on_rails/templates/base/base/config/webpack/webpackConfig.js.tt +36 -0
  35. data/lib/generators/react_on_rails/templates/base/base/config/webpacker.yml +62 -0
  36. data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/components/HelloWorld.jsx +2 -1
  37. data/lib/react_on_rails/configuration.rb +70 -35
  38. data/lib/react_on_rails/helper.rb +1 -1
  39. data/lib/react_on_rails/react_component/render_options.rb +14 -0
  40. data/lib/react_on_rails/server_rendering_js_code.rb +13 -0
  41. data/lib/react_on_rails/server_rendering_pool/ruby_embedded_java_script.rb +3 -1
  42. data/lib/react_on_rails/version.rb +1 -1
  43. data/lib/tasks/assets.rake +5 -47
  44. data/lib/tasks/locale.rake +1 -2
  45. data/package.json +1 -1
  46. data/rakelib/example_type.rb +5 -1
  47. data/rakelib/examples.rake +8 -3
  48. data/rakelib/release.rake +7 -1
  49. data/rakelib/task_helpers.rb +7 -0
  50. data/react_on_rails.gemspec +3 -3
  51. data/yarn.lock +117 -71
  52. metadata +22 -9
  53. data/lib/generators/react_on_rails/templates/base/base/Procfile.dev-hmr +0 -26
@@ -1,5 +1,7 @@
1
1
  ---
2
- extends: eslint-config-shakacode
2
+ extends:
3
+ - eslint-config-shakacode
4
+ - prettier
3
5
 
4
6
  plugins:
5
7
  - react
@@ -1,9 +1,5 @@
1
+ # Procfile for development using HMR
1
2
  # You can run these commands in separate shells
2
- web: rails s -p 3000
3
-
4
- # Next line runs a watch process with webpack to compile the changed files.
5
- # When making frequent changes to client side assets, you will prefer building webpack assets
6
- # upon saving rather than when you refresh your browser page.
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'
3
+ rails: bundle exec rails s -p 3000
4
+ wp-client: HMR=true bin/webpack-dev-server
5
+ wp-server: HMR=true SERVER_BUNDLE_ONLY=yes bin/webpack --watch
@@ -0,0 +1,9 @@
1
+ # You can run these commands in separate shells
2
+ web: rails s -p 3000
3
+
4
+ # Next line runs a watch process with webpack to compile the changed files.
5
+ # When making frequent changes to client side assets, you will prefer building webpack assets
6
+ # upon saving rather than when you refresh your browser page.
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
+ webpack: sh -c 'rm -rf public/packs/* || true && bin/webpack -w'
@@ -1,5 +1,6 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React, { useState } from 'react';
3
+ import style from './HelloWorld.module.css';
3
4
 
4
5
  const HelloWorld = (props) => {
5
6
  const [name, setName] = useState(props.name);
@@ -9,7 +10,7 @@ const HelloWorld = (props) => {
9
10
  <h3>Hello, {name}!</h3>
10
11
  <hr />
11
12
  <form>
12
- <label htmlFor="name">
13
+ <label className={style.bright} htmlFor="name">
13
14
  Say hello to:
14
15
  <input id="name" type="text" value={name} onChange={(e) => setName(e.target.value)} />
15
16
  </label>
@@ -0,0 +1,5 @@
1
+ import HelloWorld from './HelloWorld';
2
+ // This could be specialized for server rendering
3
+ // For example, if using React-Router, we'd have the SSR setup here.
4
+
5
+ export default HelloWorld;
@@ -0,0 +1,8 @@
1
+ import ReactOnRails from 'react-on-rails';
2
+
3
+ import HelloWorld from '../bundles/HelloWorld/components/HelloWorldServer';
4
+
5
+ // This is how react_on_rails can see the HelloWorld in the browser.
6
+ ReactOnRails.register({
7
+ HelloWorld,
8
+ });
@@ -4,6 +4,7 @@
4
4
  <title>ReactOnRailsWithWebpacker</title>
5
5
  <%= csrf_meta_tags %>
6
6
  <%= javascript_pack_tag 'hello-world-bundle' %>
7
+ <%= stylesheet_pack_tag 'hello-world-bundle' %>
7
8
  </head>
8
9
 
9
10
  <body>
@@ -0,0 +1,15 @@
1
+ <%= add_documentation_reference(config[:message], "// https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/babel.config.js") %>
2
+
3
+ const defaultConfigFunc = require('@rails/webpacker/package/babel/preset.js');
4
+
5
+ module.exports = function (api) {
6
+ const resultConfig = defaultConfigFunc(api);
7
+
8
+ const changesOnDefault = {
9
+ plugins: [process.env.WEBPACK_SERVE && 'react-refresh/babel'].filter(Boolean),
10
+ };
11
+
12
+ resultConfig.plugins = [...resultConfig.plugins, ...changesOnDefault.plugins];
13
+
14
+ return resultConfig;
15
+ };
@@ -41,5 +41,5 @@ ReactOnRails.configure do |config|
41
41
  # different. You should have ONE server bundle which can create all of your server rendered
42
42
  # React components.
43
43
  #
44
- config.server_bundle_js_file = "hello-world-bundle.js"
44
+ config.server_bundle_js_file = "server-bundle.js"
45
45
  end
@@ -0,0 +1,17 @@
1
+ <%= add_documentation_reference(config[:message], "// https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/config/webpack/clientWebpackConfig.js") %>
2
+
3
+ const commonWebpackConfig = require('./commonWebpackConfig');
4
+
5
+ const configureClient = () => {
6
+ const clientConfig = commonWebpackConfig();
7
+
8
+ // server-bundle is special and should ONLY be built by the serverConfig
9
+ // In case this entry is not deleted, a very strange "window" not found
10
+ // error shows referring to window["webpackJsonp"]. That is because the
11
+ // client config is going to try to load chunks.
12
+ delete clientConfig.entry['server-bundle'];
13
+
14
+ return clientConfig;
15
+ };
16
+
17
+ module.exports = configureClient;
@@ -0,0 +1,15 @@
1
+ <%= add_documentation_reference(config[:message], "// https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/config/webpack/commonWebpackConfig.js") %>
2
+
3
+ // Common configuration applying to client and server configuration
4
+ const { webpackConfig: baseClientWebpackConfig, merge } = require('@rails/webpacker');
5
+
6
+ const commonOptions = {
7
+ resolve: {
8
+ extensions: ['.css', '.ts', '.tsx'],
9
+ },
10
+ };
11
+
12
+ // Copy the object using merge b/c the baseClientWebpackConfig and commonOptions are mutable globals
13
+ const commonWebpackConfig = () => merge({}, baseClientWebpackConfig, commonOptions);
14
+
15
+ module.exports = commonWebpackConfig;
@@ -0,0 +1,27 @@
1
+ <%= add_documentation_reference(config[:message], "// https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/config/webpack/development.js") %>
2
+
3
+ process.env.NODE_ENV = process.env.NODE_ENV || 'development';
4
+
5
+ const { devServer, inliningCss } = require('@rails/webpacker');
6
+
7
+ const webpackConfig = require('./webpackConfig');
8
+
9
+ const developmentEnvOnly = (clientWebpackConfig, _serverWebpackConfig) => {
10
+ // plugins
11
+ if (inliningCss) {
12
+ // Note, when this is run, we're building the server and client bundles in separate processes.
13
+ // Thus, this plugin is not applied to the server bundle.
14
+
15
+ // eslint-disable-next-line global-require
16
+ const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
17
+ clientWebpackConfig.plugins.push(
18
+ new ReactRefreshWebpackPlugin({
19
+ overlay: {
20
+ sockPort: devServer.port,
21
+ },
22
+ }),
23
+ );
24
+ }
25
+ };
26
+
27
+ module.exports = webpackConfig(developmentEnvOnly);
@@ -0,0 +1,11 @@
1
+ <%= add_documentation_reference(config[:message], "// https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/config/webpack/production.js") %>
2
+
3
+ process.env.NODE_ENV = process.env.NODE_ENV || 'production';
4
+
5
+ const webpackConfig = require('./webpackConfig');
6
+
7
+ const productionEnvOnly = (_clientWebpackConfig, _serverWebpackConfig) => {
8
+ // place any code here that is for production only
9
+ };
10
+
11
+ module.exports = webpackConfig(productionEnvOnly);
@@ -0,0 +1,117 @@
1
+ <%= add_documentation_reference(config[:message], "// https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/config/webpack/serverWebpackConfig.js") %>
2
+
3
+ const { merge, config } = require('@rails/webpacker');
4
+ const commonWebpackConfig = require('./commonWebpackConfig');
5
+
6
+ const webpack = require('webpack');
7
+
8
+ const configureServer = () => {
9
+ // We need to use "merge" because the clientConfigObject, EVEN after running
10
+ // toWebpackConfig() is a mutable GLOBAL. Thus any changes, like modifying the
11
+ // entry value will result in changing the client config!
12
+ // Using webpack-merge into an empty object avoids this issue.
13
+ const serverWebpackConfig = commonWebpackConfig();
14
+
15
+ // We just want the single server bundle entry
16
+ const serverEntry = {
17
+ 'server-bundle': serverWebpackConfig.entry['server-bundle'],
18
+ };
19
+
20
+ if (!serverEntry['server-bundle']) {
21
+ throw new Error(
22
+ "Create a pack with the file name 'server-bundle.js' containing all the server rendering files",
23
+ );
24
+ }
25
+
26
+ serverWebpackConfig.entry = serverEntry;
27
+
28
+ // Remove the mini-css-extract-plugin from the style loaders because
29
+ // the client build will handle exporting CSS.
30
+ // replace file-loader with null-loader
31
+ serverWebpackConfig.module.rules.forEach((loader) => {
32
+ if (loader.use && loader.use.filter) {
33
+ loader.use = loader.use.filter(
34
+ (item) => !(typeof item === 'string' && item.match(/mini-css-extract-plugin/)),
35
+ );
36
+ }
37
+ });
38
+
39
+ // No splitting of chunks for a server bundle
40
+ serverWebpackConfig.optimization = {
41
+ minimize: false,
42
+ };
43
+ serverWebpackConfig.plugins.unshift(new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 }));
44
+
45
+ // Custom output for the server-bundle that matches the config in
46
+ // config/initializers/react_on_rails.rb
47
+ serverWebpackConfig.output = {
48
+ filename: 'server-bundle.js',
49
+ globalObject: 'this',
50
+ // If using the React on Rails Pro node server renderer, uncomment the next line
51
+ // libraryTarget: 'commonjs2',
52
+ path: config.outputPath,
53
+ publicPath: config.publicPath,
54
+ // https://webpack.js.org/configuration/output/#outputglobalobject
55
+ };
56
+
57
+ // Don't hash the server bundle b/c would conflict with the client manifest
58
+ // And no need for the MiniCssExtractPlugin
59
+ serverWebpackConfig.plugins = serverWebpackConfig.plugins.filter(
60
+ (plugin) =>
61
+ plugin.constructor.name !== 'WebpackAssetsManifest' &&
62
+ plugin.constructor.name !== 'MiniCssExtractPlugin' &&
63
+ plugin.constructor.name !== 'ForkTsCheckerWebpackPlugin',
64
+ );
65
+
66
+ // Configure loader rules for SSR
67
+ // Remove the mini-css-extract-plugin from the style loaders because
68
+ // the client build will handle exporting CSS.
69
+ // replace file-loader with null-loader
70
+ const rules = serverWebpackConfig.module.rules;
71
+ rules.forEach((rule) => {
72
+ if (Array.isArray(rule.use)) {
73
+ // remove the mini-css-extract-plugin and style-loader
74
+ rule.use = rule.use.filter((item) => {
75
+ let testValue;
76
+ if (typeof item === 'string') {
77
+ testValue = item;
78
+ } else if (typeof item.loader === 'string') {
79
+ testValue = item.loader;
80
+ }
81
+ return !(testValue.match(/mini-css-extract-plugin/) || testValue === 'style-loader');
82
+ });
83
+ const cssLoader = rule.use.find((item) => {
84
+ let testValue;
85
+
86
+ if (typeof item === 'string') {
87
+ testValue = item;
88
+ } else if (typeof item.loader === 'string') {
89
+ testValue = item.loader;
90
+ }
91
+
92
+ return testValue.includes('css-loader');
93
+ });
94
+ if (cssLoader && cssLoader.options) {
95
+ cssLoader.options.modules = { exportOnlyLocals: true };
96
+ }
97
+
98
+ // Skip writing image files during SSR by setting emitFile to false
99
+ } else if (rule.use && (rule.use.loader === 'url-loader' || rule.use.loader === 'file-loader')) {
100
+ rule.use.options.emitFile = false;
101
+ }
102
+ });
103
+
104
+ // eval works well for the SSR bundle because it's the fastest and shows
105
+ // lines in the server bundle which is good for debugging SSR
106
+ // The default of cheap-module-source-map is slow and provides poor info.
107
+ serverWebpackConfig.devtool = 'eval';
108
+
109
+ // If using the default 'web', then libraries like Emotion and loadable-components
110
+ // break with SSR. The fix is to use a node renderer and change the target.
111
+ // If using the React on Rails Pro node server renderer, uncomment the next line
112
+ // serverWebpackConfig.target = 'node'
113
+
114
+ return serverWebpackConfig;
115
+ };
116
+
117
+ module.exports = configureServer;
@@ -0,0 +1,36 @@
1
+ <%= add_documentation_reference(config[:message], "// https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/config/webpack/webpackConfig.js") %>
2
+
3
+ const clientWebpackConfig = require('./clientWebpackConfig');
4
+ const serverWebpackConfig = require('./serverWebpackConfig');
5
+
6
+ const webpackConfig = (envSpecific) => {
7
+ const clientConfig = clientWebpackConfig();
8
+ const serverConfig = serverWebpackConfig();
9
+
10
+ if (envSpecific) {
11
+ envSpecific(clientConfig, serverConfig);
12
+ }
13
+
14
+ let result;
15
+ // For HMR, need to separate the the client and server webpack configurations
16
+ if (process.env.WEBPACK_SERVE || process.env.CLIENT_BUNDLE_ONLY) {
17
+ // eslint-disable-next-line no-console
18
+ console.log('[React on Rails] Creating only the client bundles.');
19
+ result = clientConfig;
20
+ } else if (process.env.SERVER_BUNDLE_ONLY) {
21
+ // eslint-disable-next-line no-console
22
+ console.log('[React on Rails] Creating only the server bundle.');
23
+ result = serverConfig;
24
+ } else {
25
+ // default is the standard client and server build
26
+ // eslint-disable-next-line no-console
27
+ console.log('[React on Rails] Creating both client and server bundles.');
28
+ result = [clientConfig, serverConfig];
29
+ }
30
+
31
+ // To debug, uncomment next line and inspect "result"
32
+ // debugger
33
+ return result;
34
+ };
35
+
36
+ module.exports = webpackConfig;
@@ -0,0 +1,62 @@
1
+ # Note: You must restart bin/webpack-dev-server for changes to take effect
2
+
3
+ default: &default
4
+ source_path: app/javascript
5
+ source_entry_path: packs
6
+ public_root_path: public
7
+ public_output_path: packs
8
+ cache_path: tmp/webpacker
9
+ webpack_compile_output: true
10
+
11
+ # Additional paths webpack should lookup modules
12
+ # ['app/assets', 'engine/foo/app/assets']
13
+ additional_paths: []
14
+
15
+ # Reload manifest.json on all requests so we reload latest compiled packs
16
+ cache_manifest: false
17
+
18
+ development:
19
+ <<: *default
20
+ # This is false since we're running `bin/webpack -w` in Procfile.dev-setic
21
+ compile: false
22
+
23
+ # Reference: https://webpack.js.org/configuration/dev-server/
24
+ dev_server:
25
+ https: false
26
+ host: localhost
27
+ port: 3035
28
+ # Hot Module Replacement updates modules while the application is running without a full reload
29
+ hmr: true
30
+ client:
31
+ # Should we show a full-screen overlay in the browser when there are compiler errors or warnings?
32
+ overlay: true
33
+ # May also be a string
34
+ # webSocketURL:
35
+ # hostname: "0.0.0.0"
36
+ # pathname: "/ws"
37
+ # port: 8080
38
+ compress: true
39
+ # Note that apps that do not check the host are vulnerable to DNS rebinding attacks
40
+ allowed_hosts: [ 'localhost' ]
41
+ pretty: true
42
+ headers:
43
+ 'Access-Control-Allow-Origin': '*'
44
+ static:
45
+ watch:
46
+ ignored: '**/node_modules/**'
47
+
48
+ test:
49
+ <<: *default
50
+ compile: true
51
+
52
+ # Compile test packs to a separate directory
53
+ public_output_path: packs-test
54
+
55
+ production:
56
+ <<: *default
57
+
58
+ # Production depends on precompilation of packs prior to booting for performance.
59
+ compile: false
60
+
61
+ # Cache manifest.json for performance
62
+ cache_manifest: true
@@ -1,5 +1,6 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React from 'react';
3
+ import style from './HelloWorld.module.css';
3
4
 
4
5
  const HelloWorld = ({ name, updateName }) => (
5
6
  <div>
@@ -9,7 +10,7 @@ const HelloWorld = ({ name, updateName }) => (
9
10
  </h3>
10
11
  <hr />
11
12
  <form>
12
- <label htmlFor="name">
13
+ <label className={style.bright} htmlFor="name">
13
14
  Say hello to:
14
15
  <input id="name" type="text" value={name} onChange={(e) => updateName(e.target.value)} />
15
16
  </label>
@@ -32,6 +32,7 @@ module ReactOnRails
32
32
  # skip_display_none is deprecated
33
33
  webpack_generated_files: %w[manifest.json],
34
34
  rendering_extension: nil,
35
+ rendering_props_extension: nil,
35
36
  server_render_method: nil,
36
37
  build_test_command: "",
37
38
  build_production_command: "",
@@ -51,7 +52,7 @@ module ReactOnRails
51
52
  :build_production_command,
52
53
  :i18n_dir, :i18n_yml_dir, :i18n_output_format,
53
54
  :server_render_method, :random_dom_id,
54
- :same_bundle_for_client_and_server
55
+ :same_bundle_for_client_and_server, :rendering_props_extension
55
56
 
56
57
  # rubocop:disable Metrics/AbcSize
57
58
  def initialize(node_modules_location: nil, server_bundle_js_file: nil, prerender: nil,
@@ -65,7 +66,7 @@ module ReactOnRails
65
66
  build_production_command: nil,
66
67
  same_bundle_for_client_and_server: nil,
67
68
  i18n_dir: nil, i18n_yml_dir: nil, i18n_output_format: nil,
68
- random_dom_id: nil, server_render_method: nil)
69
+ random_dom_id: nil, server_render_method: nil, rendering_props_extension: nil)
69
70
  self.node_modules_location = node_modules_location.present? ? node_modules_location : Rails.root
70
71
  self.generated_assets_dirs = generated_assets_dirs
71
72
  self.generated_assets_dir = generated_assets_dir
@@ -87,6 +88,7 @@ module ReactOnRails
87
88
  self.trace = trace.nil? ? Rails.env.development? : trace
88
89
  self.raise_on_prerender_error = raise_on_prerender_error
89
90
  self.skip_display_none = skip_display_none
91
+ self.rendering_props_extension = rendering_props_extension
90
92
 
91
93
  # Server rendering:
92
94
  self.server_bundle_js_file = server_bundle_js_file
@@ -111,46 +113,79 @@ module ReactOnRails
111
113
  check_i18n_yml_directory_exists
112
114
  check_server_render_method_is_only_execjs
113
115
  error_if_using_webpacker_and_generated_assets_dir_not_match_public_output_path
114
- check_deprecated_settings
116
+ # check_deprecated_settings
117
+ adjust_precompile_task
115
118
  end
116
119
 
117
120
  private
118
121
 
119
- def check_deprecated_settings
120
- if build_production_command.present? &&
121
- ReactOnRails::WebpackerUtils.webpacker_webpack_production_config_exists?
122
- msg = <<~MSG
123
- Setting ReactOnRails configuration for `build_production_command` is
124
- not necessary if you have config/webpack/production.js. When that file
125
- exists, React on Rails DOES NOT modify the standard assets:precompile.
126
- If you want React on Rails to modify to the standard assets:precompile
127
- to use your config/initializers/react_on_rails.rb config.build_production_command
128
- then delete the config/webpack/production.js.
129
- MSG
130
- Rails.logger.warn(msg)
122
+ def adjust_precompile_task
123
+ skip_react_on_rails_precompile = %w[no false n f].include?(ENV["REACT_ON_RAILS_PRECOMPILE"])
124
+
125
+ return if skip_react_on_rails_precompile || build_production_command.blank?
126
+
127
+ # Ensure that rails/webpacker does not call bin/webpack if we're providing
128
+ # the build command.
129
+ ENV["WEBPACKER_PRECOMPILE"] = "false"
130
+
131
+ precompile_tasks = lambda {
132
+ Rake::Task["react_on_rails:assets:webpack"].invoke
133
+ puts "Invoking task webpacker:clean from React on Rails"
134
+
135
+ # VERSIONS is per the rails/webpacker clean method definition.
136
+ # We set it very big so that it is not used, and then clean just
137
+ # removes files older than 1 hour.
138
+ versions = 100_000
139
+ Rake::Task["webpacker:clean"].invoke(versions)
140
+ }
141
+
142
+ if Rake::Task.task_defined?("assets:precompile")
143
+ Rake::Task["assets:precompile"].enhance do
144
+ precompile_tasks.call
145
+ end
146
+ else
147
+ Rake::Task.define_task("assets:precompile") do
148
+ precompile_tasks.call
149
+ end
131
150
  end
132
- #
133
- # msg = <<~MSG
134
- # ReactOnRails configuration for `build_production_command` is removed.
135
- # Move this command into `bin/webpack` converting the script to a shell script.
136
- # MSG
137
- # raise ReactOnRails::Error, msg
138
- # Commenting out until v13 when
139
- # https://github.com/rails/webpacker/issues/2640 gets resolved
140
- # if node_modules_location.present?
141
- # Rails.logger.warn("ReactOnRails configuration for `node_modules_location` is deprecated. "\
142
- # "Instead, prepend a `cd client` (or whichever location) before your test command.")
143
- # end
144
- #
145
- # return unless build_production_command.present?
146
- #
147
- # msg = <<~MSG
148
- # ReactOnRails configuration for `build_production_command` is removed.
149
- # Move this command into `bin/webpack` converting the script to a shell script.
150
- # MSG
151
- # raise ReactOnRails::Error, msg
152
151
  end
153
152
 
153
+ # Pending updates to rails/webpacker v6, we may have some message that prints after configuration runs.
154
+ # def check_deprecated_settings
155
+ # if build_production_command.present? &&
156
+ # ReactOnRails::WebpackerUtils.webpacker_webpack_production_config_exists?
157
+ # msg = <<~MSG
158
+ # Setting ReactOnRails configuration for `build_production_command` is
159
+ # not necessary if you have config/webpack/production.js. When that file
160
+ # exists, React on Rails DOES NOT modify the standard assets:precompile.
161
+ # If you want React on Rails to modify to the standard assets:precompile
162
+ # to use your config/initializers/react_on_rails.rb config.build_production_command
163
+ # then delete the config/webpack/production.js.
164
+ # MSG
165
+ # Rails.logger.warn(msg)
166
+ # end
167
+ #
168
+ # msg = <<~MSG
169
+ # ReactOnRails configuration for `build_production_command` is removed.
170
+ # Move this command into `bin/webpack` converting the script to a shell script.
171
+ # MSG
172
+ # raise ReactOnRails::Error, msg
173
+ # Commenting out until v13 when
174
+ # https://github.com/rails/webpacker/issues/2640 gets resolved
175
+ # if node_modules_location.present?
176
+ # Rails.logger.warn("ReactOnRails configuration for `node_modules_location` is deprecated. "\
177
+ # "Instead, prepend a `cd client` (or whichever location) before your test command.")
178
+ # end
179
+ #
180
+ # return unless build_production_command.present?
181
+ #
182
+ # msg = <<~MSG
183
+ # ReactOnRails configuration for `build_production_command` is removed.
184
+ # Move this command into `bin/webpack` converting the script to a shell script.
185
+ # MSG
186
+ # raise ReactOnRails::Error, msg
187
+ # end
188
+
154
189
  def error_if_using_webpacker_and_generated_assets_dir_not_match_public_output_path
155
190
  return unless ReactOnRails::WebpackerUtils.using_webpacker?
156
191
 
@@ -413,7 +413,7 @@ module ReactOnRails
413
413
  # Setup the page_loaded_js, which is the same regardless of prerendering or not!
414
414
  # The reason is that React is smart about not doing extra work if the server rendering did its job.
415
415
  component_specification_tag = content_tag(:script,
416
- json_safe_and_pretty(render_options.props).html_safe,
416
+ json_safe_and_pretty(render_options.client_props).html_safe,
417
417
  type: "application/json",
418
418
  class: "js-react-on-rails-component",
419
419
  "data-component-name" => render_options.react_component_name,
@@ -27,6 +27,20 @@ module ReactOnRails
27
27
  options.fetch(:props) { NO_PROPS }
28
28
  end
29
29
 
30
+ def client_props
31
+ props_extension = ReactOnRails.configuration.rendering_props_extension
32
+ if props_extension.present?
33
+ if props_extension.respond_to?(:adjust_props_for_client_side_hydration)
34
+ return props_extension.adjust_props_for_client_side_hydration(react_component_name,
35
+ props.clone)
36
+ end
37
+
38
+ raise ReactOnRails::Error, "ReactOnRails: your rendering_props_extension module is missing the "\
39
+ "required adjust_props_for_client_side_hydration method & can not be used"
40
+ end
41
+ props
42
+ end
43
+
30
44
  def random_dom_id
31
45
  retrieve_configuration_value_for(:random_dom_id)
32
46
  end
@@ -18,6 +18,19 @@ module ReactOnRails
18
18
  react_component_name: nil,
19
19
  render_options: nil
20
20
  )
21
+
22
+ config_server_bundle_js = ReactOnRails.configuration.server_bundle_js_file
23
+
24
+ if render_options.prerender == true && config_server_bundle_js.blank?
25
+ msg = <<~MSG
26
+ The `prerender` option to allow Server Side Rendering is marked as true but the ReactOnRails configuration
27
+ for `server_bundle_js_file` is nil or not present in `config/initializers/react_on_rails.rb`.
28
+ Set `config.server_bundle_js_file` to your javascript bundle to allow server side rendering.
29
+ Read more at https://www.shakacode.com/react-on-rails/docs/guides/react-server-rendering/
30
+ MSG
31
+ raise ReactOnRails::Error, msg
32
+ end
33
+
21
34
  js_code_renderer.render(props_string, rails_context, redux_stores, react_component_name, render_options)
22
35
  end
23
36
 
@@ -150,7 +150,9 @@ module ReactOnRails
150
150
  end
151
151
 
152
152
  def execjs_timer_polyfills
153
- if ReactOnRails::Utils.react_on_rails_pro? && ReactOnRailsPro.configuration.include_execjs_polyfills == false
153
+ if ReactOnRails::Utils.react_on_rails_pro? &&
154
+ ReactOnRailsPro.configuration.respond_to?(:include_execjs_polyfills) &&
155
+ ReactOnRailsPro.configuration.include_execjs_polyfills == false
154
156
  return ""
155
157
  end
156
158
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ReactOnRails
4
- VERSION = "12.4.0"
4
+ VERSION = "12.6.0"
5
5
  end