react_on_rails 16.6.0.rc.0 → 16.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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/generators/react_on_rails/js_dependency_manager.rb +31 -18
- data/lib/generators/react_on_rails/pro_generator.rb +89 -24
- data/lib/generators/react_on_rails/rsc_setup.rb +2 -2
- data/lib/generators/react_on_rails/templates/base/base/Procfile.dev +1 -1
- data/lib/generators/react_on_rails/templates/base/base/bin/switch-bundler +12 -6
- data/lib/react_on_rails/configuration.rb +14 -50
- data/lib/react_on_rails/controller.rb +12 -6
- data/lib/react_on_rails/dev/server_manager.rb +4 -2
- data/lib/react_on_rails/doctor.rb +233 -32
- data/lib/react_on_rails/error.rb +2 -0
- data/lib/react_on_rails/helper.rb +46 -6
- data/lib/react_on_rails/packer_utils.rb +5 -1
- data/lib/react_on_rails/packs_generator.rb +3 -3
- data/lib/react_on_rails/pro_helper.rb +8 -12
- data/lib/react_on_rails/react_component/render_options.rb +0 -10
- data/lib/react_on_rails/system_checker.rb +42 -68
- data/lib/react_on_rails/utils.rb +0 -40
- data/lib/react_on_rails/version.rb +1 -1
- data/lib/react_on_rails/version_checker.rb +21 -1
- data/lib/react_on_rails/version_synchronizer.rb +106 -29
- data/lib/tasks/generate_packs.rake +2 -3
- data/sig/react_on_rails/configuration.rbs +0 -2
- data/sig/react_on_rails/controller.rbs +1 -2
- data/sig/react_on_rails/helper.rbs +6 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bd57c5ba417fed762b468a17579ea7bdf04bb314730eb62e9b2ae210fd873c9c
|
|
4
|
+
data.tar.gz: a860a8fafb5f17aaf1bb9f07d519a3d73bbc6f3b997b44d7398c7fce7e4c45ab
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 36ac38e9d74615e2970df360ce082bbfc625624347deaf0ddddf4756c21c112a76572795652ccd94f8f0cc05e8bbf51b6499a68a36c61a0e32eac06b17268721
|
|
7
|
+
data.tar.gz: 6a084e79ce8b4b8b5f9328d3243d71d740a2f34291f07c57fc56e33985d75242015171fc7c15b74a36545dc40263e603ece9cb0d4d722e4d624060fb56c14726
|
data/Gemfile.lock
CHANGED
|
@@ -52,29 +52,39 @@ module ReactOnRails
|
|
|
52
52
|
# Include this module in generator classes and call setup_js_dependencies
|
|
53
53
|
# to handle all JS dependency installation via package_json gem.
|
|
54
54
|
module JsDependencyManager
|
|
55
|
+
# Third-party dependencies are pinned to ^major.0.0 ranges to prevent breaking
|
|
56
|
+
# changes from uncontrolled major version bumps (e.g., peer dependency conflicts)
|
|
57
|
+
# while still allowing minor/patch updates. Pre-1.0 packages are left bare since
|
|
58
|
+
# ^0.x ranges pin to the minor version, which is too narrow.
|
|
59
|
+
# Exception: SWC deps are pinned to match Shakapacker's own version constraints
|
|
60
|
+
# (swc-loader@^0.2.0 is pre-1.0 but deliberately pinned for Shakapacker compat).
|
|
61
|
+
#
|
|
62
|
+
# Update these pins deliberately when adopting a new major version.
|
|
63
|
+
|
|
55
64
|
# Core React dependencies required for React on Rails
|
|
56
65
|
# Note: @babel/preset-react is handled separately in BABEL_REACT_DEPENDENCIES
|
|
57
66
|
# and is added only when SWC is not the active transpiler.
|
|
58
67
|
REACT_DEPENDENCIES = %w[
|
|
59
|
-
react
|
|
60
|
-
react-dom
|
|
61
|
-
prop-types
|
|
68
|
+
react@^19.0.0
|
|
69
|
+
react-dom@^19.0.0
|
|
70
|
+
prop-types@^15.0.0
|
|
62
71
|
].freeze
|
|
63
72
|
|
|
64
73
|
# Babel preset needed by the generated babel.config.js for non-SWC setups.
|
|
65
74
|
BABEL_REACT_DEPENDENCIES = %w[
|
|
66
|
-
@babel/preset-react
|
|
75
|
+
@babel/preset-react@^7.0.0
|
|
67
76
|
].freeze
|
|
68
77
|
|
|
69
78
|
# CSS processing dependencies for webpack
|
|
70
79
|
CSS_DEPENDENCIES = %w[
|
|
71
|
-
css-loader
|
|
72
|
-
css-minimizer-webpack-plugin
|
|
73
|
-
mini-css-extract-plugin
|
|
74
|
-
style-loader
|
|
80
|
+
css-loader@^7.0.0
|
|
81
|
+
css-minimizer-webpack-plugin@^8.0.0
|
|
82
|
+
mini-css-extract-plugin@^2.0.0
|
|
83
|
+
style-loader@^4.0.0
|
|
75
84
|
].freeze
|
|
76
85
|
|
|
77
86
|
# Development-only dependencies for hot reloading (Webpack)
|
|
87
|
+
# Both packages are pre-1.0, so left bare (see pinning note above).
|
|
78
88
|
DEV_DEPENDENCIES = %w[
|
|
79
89
|
@pmmmwh/react-refresh-webpack-plugin
|
|
80
90
|
react-refresh
|
|
@@ -82,14 +92,15 @@ module ReactOnRails
|
|
|
82
92
|
|
|
83
93
|
# Rspack core dependencies (only installed when --rspack flag is used)
|
|
84
94
|
RSPACK_DEPENDENCIES = %w[
|
|
85
|
-
@rspack/core
|
|
86
|
-
rspack-manifest-plugin
|
|
95
|
+
@rspack/core@^1.0.0
|
|
96
|
+
rspack-manifest-plugin@^5.0.0
|
|
87
97
|
].freeze
|
|
88
98
|
|
|
89
99
|
# Rspack development dependencies for hot reloading
|
|
100
|
+
# react-refresh is pre-1.0, so left bare (see pinning note above).
|
|
90
101
|
RSPACK_DEV_DEPENDENCIES = %w[
|
|
91
|
-
@rspack/cli
|
|
92
|
-
@rspack/plugin-react-refresh
|
|
102
|
+
@rspack/cli@^1.0.0
|
|
103
|
+
@rspack/plugin-react-refresh@^1.0.0
|
|
93
104
|
react-refresh
|
|
94
105
|
].freeze
|
|
95
106
|
|
|
@@ -100,16 +111,17 @@ module ReactOnRails
|
|
|
100
111
|
# - If users choose javascript_transpiler: 'babel', they should manually add @babel/preset-typescript
|
|
101
112
|
# and configure it in their babel.config.js
|
|
102
113
|
TYPESCRIPT_DEPENDENCIES = %w[
|
|
103
|
-
typescript
|
|
104
|
-
@types/react
|
|
105
|
-
@types/react-dom
|
|
114
|
+
typescript@^6.0.0
|
|
115
|
+
@types/react@^19.0.0
|
|
116
|
+
@types/react-dom@^19.0.0
|
|
106
117
|
].freeze
|
|
107
118
|
|
|
108
119
|
# SWC transpiler dependencies (for Shakapacker 9.3.0+ default transpiler)
|
|
109
120
|
# SWC is ~20x faster than Babel and is the default for new Shakapacker installations
|
|
121
|
+
# Version ranges match Shakapacker's own constraints.
|
|
110
122
|
SWC_DEPENDENCIES = %w[
|
|
111
|
-
@swc/core
|
|
112
|
-
swc-loader
|
|
123
|
+
@swc/core@^1.3.0
|
|
124
|
+
swc-loader@^0.2.0
|
|
113
125
|
].freeze
|
|
114
126
|
|
|
115
127
|
# React on Rails Pro dependencies (only installed when --pro or --rsc flag is used)
|
|
@@ -222,7 +234,8 @@ module ReactOnRails
|
|
|
222
234
|
# RSC requires React 19.0.x specifically (not 19.1.x or later)
|
|
223
235
|
# Pin to ~19.0.4 to allow patch updates while staying within 19.0.x
|
|
224
236
|
react_deps = if respond_to?(:use_rsc?) && use_rsc?
|
|
225
|
-
["react@#{RSC_REACT_VERSION_RANGE}", "react-dom@#{RSC_REACT_VERSION_RANGE}",
|
|
237
|
+
["react@#{RSC_REACT_VERSION_RANGE}", "react-dom@#{RSC_REACT_VERSION_RANGE}",
|
|
238
|
+
"prop-types@^15.0.0"]
|
|
226
239
|
else
|
|
227
240
|
REACT_DEPENDENCIES
|
|
228
241
|
end
|
|
@@ -147,28 +147,25 @@ module ReactOnRails
|
|
|
147
147
|
|
|
148
148
|
base_gem_entry_found = true
|
|
149
149
|
|
|
150
|
+
declaration = consume_non_parenthesized_base_gem_declaration(
|
|
151
|
+
gemfile_lines,
|
|
152
|
+
line_index,
|
|
153
|
+
match.end(0)
|
|
154
|
+
)
|
|
155
|
+
|
|
150
156
|
unless pro_entry_added
|
|
151
157
|
indentation = match[1]
|
|
152
158
|
quote = match[2]
|
|
153
159
|
updated_lines << build_pro_gem_replacement_line(
|
|
154
160
|
indentation: indentation,
|
|
155
161
|
quote: quote,
|
|
156
|
-
suffix:
|
|
162
|
+
suffix: declaration[:trailing_suffix],
|
|
157
163
|
parenthesized_gem_call: match[0].include?("(")
|
|
158
164
|
)
|
|
159
165
|
pro_entry_added = true
|
|
160
166
|
end
|
|
161
167
|
|
|
162
|
-
|
|
163
|
-
line_index += 1
|
|
164
|
-
current_line = line
|
|
165
|
-
while line_index < gemfile_lines.length &&
|
|
166
|
-
line_continues_with_comma?(current_line) &&
|
|
167
|
-
gem_declaration_continues_on_next_line?(gemfile_lines[line_index])
|
|
168
|
-
next_line = gemfile_lines[line_index]
|
|
169
|
-
current_line = next_line unless comment_or_blank_line?(next_line)
|
|
170
|
-
line_index += 1
|
|
171
|
-
end
|
|
168
|
+
line_index = declaration[:next_index]
|
|
172
169
|
end
|
|
173
170
|
|
|
174
171
|
updated_content = updated_lines.join
|
|
@@ -476,17 +473,18 @@ module ReactOnRails
|
|
|
476
473
|
pending_multiline_static_import_specifier
|
|
477
474
|
) { |line_fragment| yield line_fragment }
|
|
478
475
|
in_multiline_template_literal = updated_template_literal_state
|
|
479
|
-
in_block_comment =
|
|
476
|
+
in_block_comment = unclosed_block_comment_starts?(rewritten_line)
|
|
480
477
|
rewritten_line
|
|
481
478
|
elsif line_contains_unescaped_backtick
|
|
482
479
|
rewritten_line, pending_multiline_module_call_depth, pending_multiline_static_import_specifier =
|
|
483
480
|
rewrite_line_before_template_literal_open(
|
|
484
481
|
line,
|
|
485
482
|
pending_multiline_module_call_depth,
|
|
486
|
-
pending_multiline_static_import_specifier
|
|
483
|
+
pending_multiline_static_import_specifier,
|
|
484
|
+
in_block_comment: in_block_comment
|
|
487
485
|
) { |line_fragment| yield line_fragment }
|
|
488
486
|
in_multiline_template_literal = updated_template_literal_state
|
|
489
|
-
in_block_comment =
|
|
487
|
+
in_block_comment = unclosed_block_comment_starts?(rewritten_line)
|
|
490
488
|
rewritten_line
|
|
491
489
|
else
|
|
492
490
|
in_multiline_template_literal = updated_template_literal_state
|
|
@@ -648,7 +646,7 @@ module ReactOnRails
|
|
|
648
646
|
|
|
649
647
|
rewritten_line = yield line_without_inline_templates
|
|
650
648
|
template_placeholders.each do |placeholder, template_literal|
|
|
651
|
-
rewritten_line = rewritten_line.sub(placeholder
|
|
649
|
+
rewritten_line = rewritten_line.sub(placeholder) { template_literal }
|
|
652
650
|
end
|
|
653
651
|
rewritten_line
|
|
654
652
|
end
|
|
@@ -742,8 +740,13 @@ module ReactOnRails
|
|
|
742
740
|
["#{template_literal_prefix}#{rewritten_fragment}", pending_depth, pending_multiline_static_import_specifier]
|
|
743
741
|
end
|
|
744
742
|
|
|
745
|
-
def rewrite_line_before_template_literal_open(
|
|
746
|
-
|
|
743
|
+
def rewrite_line_before_template_literal_open(
|
|
744
|
+
line,
|
|
745
|
+
pending_depth,
|
|
746
|
+
pending_multiline_static_import_specifier,
|
|
747
|
+
in_block_comment: false
|
|
748
|
+
)
|
|
749
|
+
opening_index = opening_backtick_index_for_multiline_start(line, in_block_comment: in_block_comment)
|
|
747
750
|
return [line, pending_depth, pending_multiline_static_import_specifier] unless opening_index&.positive?
|
|
748
751
|
|
|
749
752
|
line_prefix = line[0, opening_index]
|
|
@@ -757,17 +760,56 @@ module ReactOnRails
|
|
|
757
760
|
end
|
|
758
761
|
|
|
759
762
|
def first_unescaped_backtick_index(line)
|
|
763
|
+
unescaped_backtick_indexes(line, skip_comments: true).first
|
|
764
|
+
end
|
|
765
|
+
|
|
766
|
+
def opening_backtick_index_for_multiline_start(line, in_block_comment: false)
|
|
767
|
+
backtick_indexes = unescaped_backtick_indexes(line, in_block_comment: in_block_comment)
|
|
768
|
+
return nil if backtick_indexes.empty? || backtick_indexes.length.even?
|
|
769
|
+
|
|
770
|
+
backtick_indexes.last
|
|
771
|
+
end
|
|
772
|
+
|
|
773
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
774
|
+
def unescaped_backtick_indexes(line, in_block_comment: false, skip_comments: false)
|
|
760
775
|
quote_state = nil
|
|
776
|
+
backtick_indexes = []
|
|
777
|
+
|
|
778
|
+
scan_index = 0
|
|
779
|
+
while scan_index < line.length
|
|
780
|
+
if in_block_comment
|
|
781
|
+
closing_index = line.index("*/", scan_index)
|
|
782
|
+
break unless closing_index
|
|
783
|
+
|
|
784
|
+
in_block_comment = false
|
|
785
|
+
scan_index = closing_index + 2
|
|
786
|
+
next
|
|
787
|
+
end
|
|
761
788
|
|
|
762
|
-
|
|
763
|
-
quote_state = next_quote_state(quote_state, char, line,
|
|
764
|
-
|
|
765
|
-
|
|
789
|
+
char = line[scan_index]
|
|
790
|
+
quote_state = next_quote_state(quote_state, char, line, scan_index)
|
|
791
|
+
if quote_state
|
|
792
|
+
scan_index += 1
|
|
793
|
+
next
|
|
794
|
+
end
|
|
795
|
+
|
|
796
|
+
unless skip_comments
|
|
797
|
+
break if line[scan_index, 2] == "//"
|
|
798
|
+
|
|
799
|
+
if line[scan_index, 2] == "/*"
|
|
800
|
+
in_block_comment = true
|
|
801
|
+
scan_index += 2
|
|
802
|
+
next
|
|
803
|
+
end
|
|
804
|
+
end
|
|
766
805
|
|
|
767
|
-
|
|
806
|
+
backtick_indexes << scan_index if char == "`" && !character_escaped?(line, scan_index)
|
|
807
|
+
scan_index += 1
|
|
768
808
|
end
|
|
769
|
-
|
|
809
|
+
|
|
810
|
+
backtick_indexes
|
|
770
811
|
end
|
|
812
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
771
813
|
|
|
772
814
|
def next_quote_state(current_state, char, line, index)
|
|
773
815
|
if current_state
|
|
@@ -830,13 +872,36 @@ module ReactOnRails
|
|
|
830
872
|
end
|
|
831
873
|
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
832
874
|
|
|
875
|
+
def consume_non_parenthesized_base_gem_declaration(lines, start_index, match_end)
|
|
876
|
+
line_index = start_index
|
|
877
|
+
current_line = lines[line_index]
|
|
878
|
+
declaration_lines = [current_line]
|
|
879
|
+
line_index += 1
|
|
880
|
+
|
|
881
|
+
while line_index < lines.length &&
|
|
882
|
+
line_continues_with_comma?(current_line) &&
|
|
883
|
+
gem_declaration_continues_on_next_line?(lines[line_index])
|
|
884
|
+
next_line = lines[line_index]
|
|
885
|
+
declaration_lines << next_line
|
|
886
|
+
current_line = next_line unless comment_or_blank_line?(next_line)
|
|
887
|
+
line_index += 1
|
|
888
|
+
end
|
|
889
|
+
|
|
890
|
+
trailing_suffix = lines[start_index][match_end..].to_s + declaration_lines.drop(1).join
|
|
891
|
+
{ trailing_suffix: trailing_suffix, next_index: line_index }
|
|
892
|
+
end
|
|
893
|
+
|
|
833
894
|
def build_pro_gem_replacement_line(indentation:, quote:, suffix:, parenthesized_gem_call: false)
|
|
834
895
|
normalized_suffix = suffix || "\n"
|
|
835
896
|
normalized_suffix = "#{normalized_suffix}\n" unless normalized_suffix.end_with?("\n")
|
|
836
897
|
version_arg_pattern = /\A(?<prefix>\s*,(?:\s*#.*\n|\s++)*)["'][^"']*["'](?<trailing_comma>\s*,)?/
|
|
837
898
|
loop do
|
|
838
899
|
updated_suffix = normalized_suffix.sub(version_arg_pattern) do
|
|
839
|
-
Regexp.last_match[:trailing_comma]
|
|
900
|
+
if Regexp.last_match[:trailing_comma]
|
|
901
|
+
Regexp.last_match[:prefix].sub(/\n[ \t]*\z/, "")
|
|
902
|
+
else
|
|
903
|
+
""
|
|
904
|
+
end
|
|
840
905
|
end
|
|
841
906
|
break if updated_suffix == normalized_suffix
|
|
842
907
|
|
|
@@ -170,7 +170,7 @@ module ReactOnRails
|
|
|
170
170
|
⚠️ Procfile.dev not found. Skipping RSC bundle watcher addition.
|
|
171
171
|
|
|
172
172
|
You'll need to add the RSC bundle watcher to your process manager manually:
|
|
173
|
-
rsc-bundle: RSC_BUNDLE_ONLY=
|
|
173
|
+
rsc-bundle: RSC_BUNDLE_ONLY=true bin/shakapacker-watch --watch
|
|
174
174
|
MSG
|
|
175
175
|
return
|
|
176
176
|
end
|
|
@@ -185,7 +185,7 @@ module ReactOnRails
|
|
|
185
185
|
rsc_watcher_line = <<~PROCFILE
|
|
186
186
|
|
|
187
187
|
# React on Rails Pro - RSC bundle watcher
|
|
188
|
-
rsc-bundle: RSC_BUNDLE_ONLY=
|
|
188
|
+
rsc-bundle: RSC_BUNDLE_ONLY=true bin/shakapacker-watch --watch
|
|
189
189
|
PROCFILE
|
|
190
190
|
|
|
191
191
|
append_to_file("Procfile.dev", rsc_watcher_line)
|
|
@@ -6,14 +6,17 @@ require "json"
|
|
|
6
6
|
|
|
7
7
|
# Script to switch between webpack and rspack bundlers
|
|
8
8
|
class BundlerSwitcher
|
|
9
|
+
# Pinned to ^major.0.0 to prevent peer dependency conflicts from major version bumps.
|
|
10
|
+
# Pre-1.0 packages are left bare since ^0.x pins to the minor version.
|
|
11
|
+
# webpack-cli pinned to ^6 (not ^7) to stay within Shakapacker's supported peer range.
|
|
9
12
|
WEBPACK_DEPS = {
|
|
10
|
-
dependencies: %w[webpack webpack-assets-manifest webpack-merge],
|
|
11
|
-
dev_dependencies: %w[webpack-cli webpack-dev-server @pmmmwh/react-refresh-webpack-plugin]
|
|
13
|
+
dependencies: %w[webpack@^5.0.0 webpack-assets-manifest@^6.0.0 webpack-merge@^6.0.0],
|
|
14
|
+
dev_dependencies: %w[webpack-cli@^6.0.0 webpack-dev-server@^5.0.0 @pmmmwh/react-refresh-webpack-plugin]
|
|
12
15
|
}.freeze
|
|
13
16
|
|
|
14
17
|
RSPACK_DEPS = {
|
|
15
|
-
dependencies: %w[@rspack/core rspack-manifest-plugin],
|
|
16
|
-
dev_dependencies: %w[@rspack/cli @rspack/plugin-react-refresh]
|
|
18
|
+
dependencies: %w[@rspack/core@^1.0.0 rspack-manifest-plugin@^5.0.0],
|
|
19
|
+
dev_dependencies: %w[@rspack/cli@^1.0.0 @rspack/plugin-react-refresh@^1.0.0]
|
|
17
20
|
}.freeze
|
|
18
21
|
|
|
19
22
|
def initialize(target_bundler)
|
|
@@ -83,11 +86,14 @@ class BundlerSwitcher
|
|
|
83
86
|
remove_deps = @target_bundler == "rspack" ? WEBPACK_DEPS : RSPACK_DEPS
|
|
84
87
|
|
|
85
88
|
# Remove old bundler dependencies
|
|
89
|
+
# Strip version suffix (e.g., "webpack@^5.0.0" -> "webpack") since package.json keys are bare names.
|
|
90
|
+
# The regex handles scoped (@scope/name@ver) and unscoped (name@ver) packages, and is a no-op for
|
|
91
|
+
# bare names without a version suffix (e.g., "@pmmmwh/react-refresh-webpack-plugin" stays unchanged).
|
|
86
92
|
remove_deps[:dependencies].each do |dep|
|
|
87
|
-
package_json["dependencies"]&.delete(dep)
|
|
93
|
+
package_json["dependencies"]&.delete(dep[%r{\A(@[^/]+/[^@]+|[^@]+)}])
|
|
88
94
|
end
|
|
89
95
|
remove_deps[:dev_dependencies].each do |dep|
|
|
90
|
-
package_json["devDependencies"]&.delete(dep)
|
|
96
|
+
package_json["devDependencies"]&.delete(dep[%r{\A(@[^/]+/[^@]+|[^@]+)}])
|
|
91
97
|
end
|
|
92
98
|
|
|
93
99
|
puts "✅ Removed #{@target_bundler == 'rspack' ? 'webpack' : 'rspack'} dependencies"
|
|
@@ -94,51 +94,6 @@ module ReactOnRails
|
|
|
94
94
|
:server_bundle_output_path, :enforce_private_server_bundles,
|
|
95
95
|
:check_database_on_dev_start
|
|
96
96
|
|
|
97
|
-
# Class instance variable and mutex to track if deprecation warning has been shown
|
|
98
|
-
# Using mutex to ensure thread-safety in multi-threaded environments
|
|
99
|
-
@immediate_hydration_warned = false
|
|
100
|
-
@immediate_hydration_mutex = Mutex.new
|
|
101
|
-
|
|
102
|
-
class << self
|
|
103
|
-
attr_accessor :immediate_hydration_warned, :immediate_hydration_mutex
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
# Deprecated: immediate_hydration configuration has been removed
|
|
107
|
-
def immediate_hydration=(value)
|
|
108
|
-
warned = false
|
|
109
|
-
self.class.immediate_hydration_mutex.synchronize do
|
|
110
|
-
warned = self.class.immediate_hydration_warned
|
|
111
|
-
self.class.immediate_hydration_warned = true unless warned
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
return if warned
|
|
115
|
-
|
|
116
|
-
Rails.logger.warn <<~WARNING
|
|
117
|
-
[REACT ON RAILS] The 'config.immediate_hydration' configuration option is deprecated and no longer used.
|
|
118
|
-
Immediate hydration is now automatically enabled for React on Rails Pro users.
|
|
119
|
-
Please remove 'config.immediate_hydration = #{value}' from your config/initializers/react_on_rails.rb file.
|
|
120
|
-
See CHANGELOG.md for migration instructions.
|
|
121
|
-
WARNING
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
def immediate_hydration
|
|
125
|
-
warned = false
|
|
126
|
-
self.class.immediate_hydration_mutex.synchronize do
|
|
127
|
-
warned = self.class.immediate_hydration_warned
|
|
128
|
-
self.class.immediate_hydration_warned = true unless warned
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
return nil if warned
|
|
132
|
-
|
|
133
|
-
Rails.logger.warn <<~WARNING
|
|
134
|
-
[REACT ON RAILS] The 'config.immediate_hydration' configuration option is deprecated and no longer used.
|
|
135
|
-
Immediate hydration is now automatically enabled for React on Rails Pro users.
|
|
136
|
-
Please remove any references to 'config.immediate_hydration' from your config/initializers/react_on_rails.rb file.
|
|
137
|
-
See CHANGELOG.md for migration instructions.
|
|
138
|
-
WARNING
|
|
139
|
-
nil
|
|
140
|
-
end
|
|
141
|
-
|
|
142
97
|
# rubocop:disable Metrics/AbcSize
|
|
143
98
|
def initialize(node_modules_location: nil, server_bundle_js_file: nil, prerender: nil,
|
|
144
99
|
replay_console: nil, make_generated_server_bundle_the_entrypoint: nil,
|
|
@@ -257,12 +212,14 @@ module ReactOnRails
|
|
|
257
212
|
Rails.logger.warn("**WARNING** #{msg}")
|
|
258
213
|
self.generated_component_packs_loading_strategy = :sync
|
|
259
214
|
elsif generated_component_packs_loading_strategy == :async
|
|
260
|
-
raise ReactOnRails::Error, "**ERROR** #{msg}"
|
|
215
|
+
raise ReactOnRails::Error, "**ERROR** #{msg}\n\n#{ReactOnRails::DOCTOR_RECOMMENDATION}"
|
|
261
216
|
end
|
|
262
217
|
|
|
263
218
|
return if %i[async defer sync].include?(generated_component_packs_loading_strategy)
|
|
264
219
|
|
|
265
|
-
raise ReactOnRails::Error,
|
|
220
|
+
raise ReactOnRails::Error,
|
|
221
|
+
"generated_component_packs_loading_strategy must be either :async, :defer, or :sync. " \
|
|
222
|
+
"#{ReactOnRails::DOCTOR_RECOMMENDATION}"
|
|
266
223
|
end
|
|
267
224
|
|
|
268
225
|
def validate_enforce_private_server_bundles
|
|
@@ -272,7 +229,8 @@ module ReactOnRails
|
|
|
272
229
|
if server_bundle_output_path.nil?
|
|
273
230
|
raise ReactOnRails::Error, "enforce_private_server_bundles is set to true, but " \
|
|
274
231
|
"server_bundle_output_path is nil. Please set server_bundle_output_path " \
|
|
275
|
-
"to a directory outside of the public directory."
|
|
232
|
+
"to a directory outside of the public directory. " \
|
|
233
|
+
"#{ReactOnRails::DOCTOR_RECOMMENDATION}"
|
|
276
234
|
end
|
|
277
235
|
|
|
278
236
|
# Check if server_bundle_output_path is inside public directory
|
|
@@ -286,7 +244,8 @@ module ReactOnRails
|
|
|
286
244
|
|
|
287
245
|
raise ReactOnRails::Error, "enforce_private_server_bundles is set to true, but " \
|
|
288
246
|
"server_bundle_output_path (#{server_bundle_output_path}) is inside " \
|
|
289
|
-
"the public directory. Please set it to a directory outside of public."
|
|
247
|
+
"the public directory. Please set it to a directory outside of public. " \
|
|
248
|
+
"#{ReactOnRails::DOCTOR_RECOMMENDATION}"
|
|
290
249
|
end
|
|
291
250
|
|
|
292
251
|
# Auto-detect server_bundle_output_path from Shakapacker 9.0+ private_output_path
|
|
@@ -401,6 +360,8 @@ module ReactOnRails
|
|
|
401
360
|
that does not match the value for public_output_path specified in
|
|
402
361
|
shakapacker.yml = #{packer_public_output_path}. You should remove the configuration
|
|
403
362
|
value for "generated_assets_dir" from your config/initializers/react_on_rails.rb file.
|
|
363
|
+
|
|
364
|
+
#{ReactOnRails::DOCTOR_RECOMMENDATION}
|
|
404
365
|
MSG
|
|
405
366
|
raise ReactOnRails::Error, msg
|
|
406
367
|
end
|
|
@@ -465,7 +426,9 @@ module ReactOnRails
|
|
|
465
426
|
msg = <<~MSG
|
|
466
427
|
**ERROR** ReactOnRails: auto_load_bundle is set to true, yet components_subdirectory is not configured.\
|
|
467
428
|
Please set components_subdirectory to the desired directory. For more information, please see \
|
|
468
|
-
https://reactonrails.com/docs/core-concepts/auto-bundling
|
|
429
|
+
https://reactonrails.com/docs/core-concepts/auto-bundling/
|
|
430
|
+
|
|
431
|
+
#{ReactOnRails::DOCTOR_RECOMMENDATION}
|
|
469
432
|
MSG
|
|
470
433
|
|
|
471
434
|
raise ReactOnRails::Error, msg
|
|
@@ -482,6 +445,7 @@ module ReactOnRails
|
|
|
482
445
|
Alternatively, remove the config/react_on_rails.rb config.build_production_command and the
|
|
483
446
|
default bin/shakapacker script will be used for assets:precompile.
|
|
484
447
|
|
|
448
|
+
#{ReactOnRails::DOCTOR_RECOMMENDATION}
|
|
485
449
|
MSG
|
|
486
450
|
end
|
|
487
451
|
end
|
|
@@ -9,16 +9,22 @@ module ReactOnRails
|
|
|
9
9
|
# JavaScript code.
|
|
10
10
|
# props: Named parameter props which is a Ruby Hash or JSON string which contains the properties
|
|
11
11
|
# to pass to the redux store.
|
|
12
|
-
# immediate_hydration: React on Rails Pro (licensed) feature. When nil (default), Pro users get
|
|
13
|
-
# immediate hydration, non-Pro users don't. Can be explicitly overridden.
|
|
14
12
|
#
|
|
15
13
|
# Be sure to include view helper `redux_store_hydration_data` at the end of your layout or view
|
|
16
14
|
# or else there will be no client side hydration of your stores.
|
|
17
|
-
def redux_store(store_name, props: {},
|
|
18
|
-
|
|
15
|
+
def redux_store(store_name, props: {}, **rest)
|
|
16
|
+
immediate_hydration_present = rest.key?(:immediate_hydration)
|
|
17
|
+
unknown_keys = rest.keys - [:immediate_hydration]
|
|
18
|
+
if unknown_keys.any?
|
|
19
|
+
plural = unknown_keys.one? ? "" : "s"
|
|
20
|
+
unknown_options = unknown_keys.map { |key| ":#{key}" }.join(", ")
|
|
21
|
+
raise ArgumentError, "unknown keyword#{plural}: #{unknown_options}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
ReactOnRails::Helper.warn_removed_immediate_hydration_option("redux_store") if immediate_hydration_present
|
|
25
|
+
|
|
19
26
|
redux_store_data = { store_name: store_name,
|
|
20
|
-
props: props
|
|
21
|
-
immediate_hydration: immediate_hydration }
|
|
27
|
+
props: props }
|
|
22
28
|
@registered_stores_defer_render ||= []
|
|
23
29
|
@registered_stores_defer_render << redux_store_data
|
|
24
30
|
end
|
|
@@ -290,7 +290,7 @@ module ReactOnRails
|
|
|
290
290
|
|
|
291
291
|
env = { "RAILS_ENV" => "test" }
|
|
292
292
|
if resolved_mode == "client-only"
|
|
293
|
-
env["CLIENT_BUNDLE_ONLY"] = "
|
|
293
|
+
env["CLIENT_BUNDLE_ONLY"] = "true"
|
|
294
294
|
puts Rainbow("🧪 Starting test watch (client-only mode)...").cyan
|
|
295
295
|
puts Rainbow(" Reusing server bundle from existing watcher if available.").cyan
|
|
296
296
|
else
|
|
@@ -320,7 +320,9 @@ module ReactOnRails
|
|
|
320
320
|
def shakapacker_watch_process_running?
|
|
321
321
|
# Detect existing shakapacker watcher processes (from either bin/dev or bin/dev static).
|
|
322
322
|
# If one is already running, client-only test watch avoids duplicate server-bundle rebuilds.
|
|
323
|
-
|
|
323
|
+
# Also detect legacy =yes convention during transition
|
|
324
|
+
server_only_watchers = find_process_pids("SERVER_BUNDLE_ONLY=true bin/shakapacker --watch")
|
|
325
|
+
server_only_watchers |= find_process_pids("SERVER_BUNDLE_ONLY=yes bin/shakapacker --watch")
|
|
324
326
|
if server_only_watchers.any?
|
|
325
327
|
return true if shared_private_output_paths?
|
|
326
328
|
|