react_on_rails 16.0.1.rc.0 → 16.0.1.rc.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/CHANGELOG.md +59 -1
- data/CLAUDE.md +34 -1
- data/CODING_AGENTS.md +1 -0
- data/CONTRIBUTING.md +12 -6
- data/Gemfile.development_dependencies +1 -0
- data/Gemfile.lock +3 -1
- data/NEWS.md +1 -1
- data/README.md +15 -8
- data/bin/lefthook/check-trailing-newlines +38 -0
- data/bin/lefthook/get-changed-files +26 -0
- data/bin/lefthook/prettier-format +26 -0
- data/bin/lefthook/ruby-autofix +26 -0
- data/bin/lefthook/ruby-lint +27 -0
- data/eslint.config.ts +7 -0
- data/lib/generators/react_on_rails/base_generator.rb +59 -51
- data/lib/generators/react_on_rails/install_generator.rb +139 -1
- data/lib/generators/react_on_rails/react_with_redux_generator.rb +9 -10
- data/lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt +11 -2
- data/lib/generators/react_on_rails/templates/base/base/config/webpack/serverWebpackConfig.js.tt +3 -2
- data/lib/react_on_rails/configuration.rb +63 -50
- data/lib/react_on_rails/json_parse_error.rb +6 -1
- data/lib/react_on_rails/packer_utils.rb +39 -52
- data/lib/react_on_rails/packs_generator.rb +3 -0
- data/lib/react_on_rails/prerender_error.rb +4 -0
- data/lib/react_on_rails/server_rendering_pool/ruby_embedded_java_script.rb +5 -3
- data/lib/react_on_rails/system_checker.rb +6 -6
- data/lib/react_on_rails/test_helper/webpack_assets_compiler.rb +1 -1
- data/lib/react_on_rails/test_helper/webpack_assets_status_checker.rb +1 -2
- data/lib/react_on_rails/test_helper.rb +2 -3
- data/lib/react_on_rails/utils.rb +84 -41
- data/lib/react_on_rails/version.rb +1 -1
- data/lib/tasks/doctor.rake +0 -3
- data/lib/tasks/generate_packs.rake +19 -5
- metadata +6 -2
- data/package-lock.json +0 -11984
@@ -9,6 +9,8 @@ module ReactOnRails
|
|
9
9
|
CONTAINS_CLIENT_OR_SERVER_REGEX = /\.(server|client)($|\.)/
|
10
10
|
COMPONENT_EXTENSIONS = /\.(jsx?|tsx?)$/
|
11
11
|
MINIMUM_SHAKAPACKER_VERSION = "6.5.1"
|
12
|
+
# Auto-registration requires nested_entries support which was added in 7.0.0
|
13
|
+
MINIMUM_SHAKAPACKER_VERSION_FOR_AUTO_BUNDLING = "7.0.0"
|
12
14
|
|
13
15
|
def self.instance
|
14
16
|
@instance ||= PacksGenerator.new
|
@@ -164,6 +166,7 @@ module ReactOnRails
|
|
164
166
|
|
165
167
|
def add_generated_pack_to_server_bundle
|
166
168
|
return if ReactOnRails.configuration.make_generated_server_bundle_the_entrypoint
|
169
|
+
return if ReactOnRails.configuration.server_bundle_js_file.blank?
|
167
170
|
|
168
171
|
relative_path_to_generated_server_bundle = relative_path(server_bundle_entrypoint,
|
169
172
|
generated_server_bundle_file_path)
|
@@ -77,6 +77,7 @@ module ReactOnRails
|
|
77
77
|
if err.message.include?("ReferenceError: self is not defined")
|
78
78
|
msg << "\nError indicates that you may have code-splitting incorrectly enabled.\n"
|
79
79
|
end
|
80
|
+
msg << "\n#{Utils.default_troubleshooting_section}\n"
|
80
81
|
raise ReactOnRails::Error, msg, err.backtrace
|
81
82
|
end
|
82
83
|
|
@@ -122,7 +123,7 @@ module ReactOnRails
|
|
122
123
|
rescue StandardError => e
|
123
124
|
msg = "You specified server rendering JS file: #{server_js_file}, but it cannot be " \
|
124
125
|
"read. You may set the server_bundle_js_file in your configuration to be \"\" to " \
|
125
|
-
"avoid this warning.\nError is: #{e}"
|
126
|
+
"avoid this warning.\nError is: #{e}\n\n#{Utils.default_troubleshooting_section}"
|
126
127
|
raise ReactOnRails::Error, msg
|
127
128
|
end
|
128
129
|
|
@@ -149,7 +150,8 @@ module ReactOnRails
|
|
149
150
|
msg = "ERROR when compiling base_js_code! " \
|
150
151
|
"See file #{file_name} to " \
|
151
152
|
"correlate line numbers of error. Error is\n\n#{e.message}" \
|
152
|
-
"\n\n#{e.backtrace.join("\n")}"
|
153
|
+
"\n\n#{e.backtrace.join("\n")}" \
|
154
|
+
"\n\n#{Utils.default_troubleshooting_section}"
|
153
155
|
Rails.logger.error(msg)
|
154
156
|
trace_js_code_used("Error when compiling JavaScript code for the context.", base_js_code,
|
155
157
|
file_name, force: true)
|
@@ -227,7 +229,7 @@ module ReactOnRails
|
|
227
229
|
encoding_type = match[:encoding]
|
228
230
|
response.body.force_encoding(encoding_type)
|
229
231
|
rescue StandardError => e
|
230
|
-
msg = "file_url_to_string #{url} failed\nError is: #{e}"
|
232
|
+
msg = "file_url_to_string #{url} failed\nError is: #{e}\n\n#{Utils.default_troubleshooting_section}"
|
231
233
|
raise ReactOnRails::Error, msg
|
232
234
|
end
|
233
235
|
|
@@ -618,14 +618,14 @@ module ReactOnRails
|
|
618
618
|
version = shakapacker_match[1].strip
|
619
619
|
|
620
620
|
begin
|
621
|
-
#
|
622
|
-
|
623
|
-
threshold_version = Gem::Version.new("8.2")
|
621
|
+
# Validate version string format
|
622
|
+
Gem::Version.new(version)
|
624
623
|
|
625
|
-
if
|
626
|
-
add_success("✅ Shakapacker #{version} (supports React on Rails auto-
|
624
|
+
if ReactOnRails::PackerUtils.supports_autobundling?
|
625
|
+
add_success("✅ Shakapacker #{version} (supports React on Rails auto-bundling)")
|
627
626
|
else
|
628
|
-
add_warning("⚠️ Shakapacker #{version} - Version
|
627
|
+
add_warning("⚠️ Shakapacker #{version} - Version 7.0+ with nested_entries support needed " \
|
628
|
+
"for React on Rails auto-bundling")
|
629
629
|
end
|
630
630
|
rescue ArgumentError
|
631
631
|
# Fallback for invalid version strings
|
@@ -16,7 +16,7 @@ module ReactOnRails
|
|
16
16
|
|
17
17
|
React on Rails is aborting your test run
|
18
18
|
|
19
|
-
If you wish to use the config
|
19
|
+
If you wish to use the config/shakapacker.yml compile option for tests
|
20
20
|
them remove your call to the ReactOnRails test helper.
|
21
21
|
MSG
|
22
22
|
puts Rainbow(msg).red
|
@@ -31,8 +31,7 @@ module ReactOnRails
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def stale_generated_files(files)
|
34
|
-
manifest_needed = ReactOnRails::PackerUtils.
|
35
|
-
!ReactOnRails::PackerUtils.manifest_exists?
|
34
|
+
manifest_needed = !ReactOnRails::PackerUtils.manifest_exists?
|
36
35
|
|
37
36
|
return ["manifest.json"] if manifest_needed
|
38
37
|
|
@@ -86,10 +86,9 @@ module ReactOnRails
|
|
86
86
|
puts
|
87
87
|
@printed_once = true
|
88
88
|
|
89
|
-
if ReactOnRails::
|
90
|
-
ReactOnRails::Utils.using_packer_source_path_is_not_defined_and_custom_node_modules?
|
89
|
+
if ReactOnRails::Utils.using_packer_source_path_is_not_defined_and_custom_node_modules?
|
91
90
|
msg = <<-MSG.strip_heredoc
|
92
|
-
WARNING: Define config
|
91
|
+
WARNING: Define config/shakapacker.yml to include sourcePath to configure
|
93
92
|
the location of your JavaScript source for React on Rails.
|
94
93
|
Default location of #{source_path} is used.
|
95
94
|
MSG
|
data/lib/react_on_rails/utils.rb
CHANGED
@@ -6,8 +6,9 @@ require "rainbow"
|
|
6
6
|
require "active_support"
|
7
7
|
require "active_support/core_ext/string"
|
8
8
|
|
9
|
+
# rubocop:disable Metrics/ModuleLength
|
9
10
|
module ReactOnRails
|
10
|
-
module Utils
|
11
|
+
module Utils
|
11
12
|
TRUNCATION_FILLER = "\n... TRUNCATED #{
|
12
13
|
Rainbow('To see the full output, set FULL_TEXT_ERRORS=true.').red
|
13
14
|
} ...\n".freeze
|
@@ -57,6 +58,8 @@ module ReactOnRails
|
|
57
58
|
MSG
|
58
59
|
|
59
60
|
puts wrap_message(msg)
|
61
|
+
puts ""
|
62
|
+
puts default_troubleshooting_section
|
60
63
|
|
61
64
|
# Rspec catches exit without! in the exit callbacks
|
62
65
|
exit!(1)
|
@@ -69,34 +72,72 @@ module ReactOnRails
|
|
69
72
|
end
|
70
73
|
|
71
74
|
def self.bundle_js_file_path(bundle_name)
|
72
|
-
#
|
73
|
-
#
|
74
|
-
#
|
75
|
-
|
76
|
-
# 3. The third option of having the server bundle hashed and a different configuration than
|
77
|
-
# the client bundle is not supported for 2 reasons:
|
78
|
-
# a. The webpack manifest plugin would have a race condition where the same manifest.json
|
79
|
-
# is edited by both the webpack-dev-server
|
80
|
-
# b. There is no good reason to hash the server bundle name.
|
81
|
-
if ReactOnRails::PackerUtils.using_packer? && bundle_name != "manifest.json"
|
82
|
-
begin
|
83
|
-
ReactOnRails::PackerUtils.bundle_js_uri_from_packer(bundle_name)
|
84
|
-
rescue Object.const_get(
|
85
|
-
ReactOnRails::PackerUtils.packer_type.capitalize
|
86
|
-
)::Manifest::MissingEntryError
|
87
|
-
File.expand_path(
|
88
|
-
File.join(ReactOnRails::PackerUtils.packer_public_output_path,
|
89
|
-
bundle_name)
|
90
|
-
)
|
91
|
-
end
|
92
|
-
else
|
75
|
+
# Priority order depends on bundle type:
|
76
|
+
# SERVER BUNDLES (normal case): Try private non-public locations first, then manifest, then legacy
|
77
|
+
# CLIENT BUNDLES (normal case): Try manifest first, then fallback locations
|
78
|
+
if bundle_name == "manifest.json"
|
93
79
|
# Default to the non-hashed name in the specified output directory, which, for legacy
|
94
80
|
# React on Rails, this is the output directory picked up by the asset pipeline.
|
95
81
|
# For Shakapacker, this is the public output path defined in the (shaka/web)packer.yml file.
|
96
|
-
File.join(
|
82
|
+
File.join(public_bundles_full_path, bundle_name)
|
83
|
+
else
|
84
|
+
bundle_js_file_path_with_packer(bundle_name)
|
97
85
|
end
|
98
86
|
end
|
99
87
|
|
88
|
+
private_class_method def self.bundle_js_file_path_with_packer(bundle_name)
|
89
|
+
is_server_bundle = server_bundle?(bundle_name)
|
90
|
+
config = ReactOnRails.configuration
|
91
|
+
root_path = Rails.root || "."
|
92
|
+
|
93
|
+
# If server bundle and server_bundle_output_path is configured, return that path directly
|
94
|
+
if is_server_bundle && config.server_bundle_output_path.present?
|
95
|
+
private_server_bundle_path = File.expand_path(File.join(root_path, config.server_bundle_output_path,
|
96
|
+
bundle_name))
|
97
|
+
|
98
|
+
# Don't fall back to public directory if enforce_private_server_bundles is enabled
|
99
|
+
if config.enforce_private_server_bundles || File.exist?(private_server_bundle_path)
|
100
|
+
return private_server_bundle_path
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Try manifest lookup for all bundles
|
105
|
+
begin
|
106
|
+
ReactOnRails::PackerUtils.bundle_js_uri_from_packer(bundle_name)
|
107
|
+
rescue Shakapacker::Manifest::MissingEntryError
|
108
|
+
handle_missing_manifest_entry(bundle_name, is_server_bundle)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
private_class_method def self.server_bundle?(bundle_name)
|
113
|
+
config = ReactOnRails.configuration
|
114
|
+
bundle_name == config.server_bundle_js_file ||
|
115
|
+
bundle_name == config.rsc_bundle_js_file
|
116
|
+
end
|
117
|
+
|
118
|
+
private_class_method def self.handle_missing_manifest_entry(bundle_name, is_server_bundle)
|
119
|
+
config = ReactOnRails.configuration
|
120
|
+
root_path = Rails.root || "."
|
121
|
+
|
122
|
+
# For server bundles with server_bundle_output_path configured, use that
|
123
|
+
if is_server_bundle && config.server_bundle_output_path.present?
|
124
|
+
candidate_paths = [File.expand_path(File.join(root_path, config.server_bundle_output_path, bundle_name))]
|
125
|
+
unless config.enforce_private_server_bundles
|
126
|
+
candidate_paths << File.expand_path(File.join(ReactOnRails::PackerUtils.packer_public_output_path,
|
127
|
+
bundle_name))
|
128
|
+
end
|
129
|
+
|
130
|
+
candidate_paths.each do |path|
|
131
|
+
return path if File.exist?(path)
|
132
|
+
end
|
133
|
+
return candidate_paths.first
|
134
|
+
end
|
135
|
+
|
136
|
+
# For client bundles and server bundles without special config, use packer's public path
|
137
|
+
# This returns the environment-specific path configured in shakapacker.yml
|
138
|
+
File.expand_path(File.join(ReactOnRails::PackerUtils.packer_public_output_path, bundle_name))
|
139
|
+
end
|
140
|
+
|
100
141
|
def self.server_bundle_js_file_path
|
101
142
|
return @server_bundle_path if @server_bundle_path && !Rails.env.development?
|
102
143
|
|
@@ -115,11 +156,7 @@ module ReactOnRails
|
|
115
156
|
return @react_client_manifest_path if @react_client_manifest_path && !Rails.env.development?
|
116
157
|
|
117
158
|
file_name = ReactOnRails.configuration.react_client_manifest_file
|
118
|
-
@react_client_manifest_path =
|
119
|
-
ReactOnRails::PackerUtils.asset_uri_from_packer(file_name)
|
120
|
-
else
|
121
|
-
File.join(generated_assets_full_path, file_name)
|
122
|
-
end
|
159
|
+
@react_client_manifest_path = ReactOnRails::PackerUtils.asset_uri_from_packer(file_name)
|
123
160
|
end
|
124
161
|
|
125
162
|
# React Server Manifest is generated by the server bundle.
|
@@ -133,7 +170,7 @@ module ReactOnRails
|
|
133
170
|
"react_server_client_manifest_file is nil, ensure it is set in your configuration"
|
134
171
|
end
|
135
172
|
|
136
|
-
@react_server_manifest_path = File.join(
|
173
|
+
@react_server_manifest_path = File.join(public_bundles_full_path, asset_name)
|
137
174
|
end
|
138
175
|
|
139
176
|
def self.running_on_windows?
|
@@ -161,26 +198,21 @@ module ReactOnRails
|
|
161
198
|
end
|
162
199
|
|
163
200
|
def self.source_path
|
164
|
-
|
165
|
-
ReactOnRails::PackerUtils.packer_source_path
|
166
|
-
else
|
167
|
-
ReactOnRails.configuration.node_modules_location
|
168
|
-
end
|
201
|
+
ReactOnRails::PackerUtils.packer_source_path
|
169
202
|
end
|
170
203
|
|
171
204
|
def self.using_packer_source_path_is_not_defined_and_custom_node_modules?
|
172
|
-
return false unless ReactOnRails::PackerUtils.using_packer?
|
173
|
-
|
174
205
|
!ReactOnRails::PackerUtils.packer_source_path_explicit? &&
|
175
206
|
ReactOnRails.configuration.node_modules_location.present?
|
176
207
|
end
|
177
208
|
|
209
|
+
def self.public_bundles_full_path
|
210
|
+
ReactOnRails::PackerUtils.packer_public_output_path
|
211
|
+
end
|
212
|
+
|
213
|
+
# DEPRECATED: Use public_bundles_full_path for clarity about public vs private bundle paths
|
178
214
|
def self.generated_assets_full_path
|
179
|
-
|
180
|
-
ReactOnRails::PackerUtils.packer_public_output_path
|
181
|
-
else
|
182
|
-
File.expand_path(ReactOnRails.configuration.generated_assets_dir)
|
183
|
-
end
|
215
|
+
public_bundles_full_path
|
184
216
|
end
|
185
217
|
|
186
218
|
def self.gem_available?(name)
|
@@ -278,5 +310,16 @@ module ReactOnRails
|
|
278
310
|
|
279
311
|
puts "Prepended\n#{text_to_prepend}to #{file}."
|
280
312
|
end
|
313
|
+
|
314
|
+
def self.default_troubleshooting_section
|
315
|
+
<<~DEFAULT
|
316
|
+
📞 Get Help & Support:
|
317
|
+
• 🚀 Professional Support: react_on_rails@shakacode.com (fastest resolution)
|
318
|
+
• 💬 React + Rails Slack: https://invite.reactrails.com
|
319
|
+
• 🆓 GitHub Issues: https://github.com/shakacode/react_on_rails/issues
|
320
|
+
• 📖 Discussions: https://github.com/shakacode/react_on_rails/discussions
|
321
|
+
DEFAULT
|
322
|
+
end
|
281
323
|
end
|
282
324
|
end
|
325
|
+
# rubocop:enable Metrics/ModuleLength
|
data/lib/tasks/doctor.rake
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "../../rakelib/task_helpers"
|
4
3
|
require_relative "../react_on_rails"
|
5
4
|
require_relative "../react_on_rails/doctor"
|
6
5
|
|
@@ -38,8 +37,6 @@ rescue LoadError
|
|
38
37
|
end
|
39
38
|
|
40
39
|
namespace :react_on_rails do
|
41
|
-
include ReactOnRails::TaskHelpers
|
42
|
-
|
43
40
|
desc "Diagnose React on Rails setup and configuration"
|
44
41
|
task :doctor do
|
45
42
|
verbose = ENV["VERBOSE"] == "true"
|
@@ -123,6 +123,24 @@ namespace :react_on_rails do
|
|
123
123
|
puts Rainbow("=" * 80).red
|
124
124
|
end
|
125
125
|
|
126
|
+
def show_help_and_support
|
127
|
+
puts ""
|
128
|
+
troubleshooting_content = ReactOnRails::Utils.default_troubleshooting_section
|
129
|
+
# Display the troubleshooting content with color formatting
|
130
|
+
troubleshooting_content.split("\n").each do |line|
|
131
|
+
case line
|
132
|
+
when /^📞/
|
133
|
+
puts Rainbow(line).magenta.bold
|
134
|
+
when /^\s*•\s*🚀/
|
135
|
+
puts Rainbow(line).yellow
|
136
|
+
when /^\s*•/
|
137
|
+
puts Rainbow(line).cyan
|
138
|
+
else
|
139
|
+
puts Rainbow(line).white unless line.strip.empty?
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
126
144
|
# rubocop:disable Metrics/AbcSize
|
127
145
|
def handle_standard_error(error)
|
128
146
|
puts ""
|
@@ -142,11 +160,7 @@ namespace :react_on_rails do
|
|
142
160
|
puts Rainbow(" 2. Check Rails logs: tail -f log/development.log").white
|
143
161
|
puts Rainbow(" 3. Verify all dependencies are installed: bundle install && npm install").white
|
144
162
|
puts Rainbow(" 4. Clear cache: rm -rf tmp/cache").white
|
145
|
-
|
146
|
-
puts Rainbow("📞 GET HELP:").magenta.bold
|
147
|
-
puts Rainbow(" • Create an issue: https://github.com/shakacode/react_on_rails/issues").cyan
|
148
|
-
puts Rainbow(" • Community discussions: https://github.com/shakacode/react_on_rails/discussions").cyan
|
149
|
-
puts Rainbow(" • Professional support: https://www.shakacode.com/react-on-rails-pro").cyan
|
163
|
+
show_help_and_support
|
150
164
|
puts Rainbow("=" * 80).red
|
151
165
|
end
|
152
166
|
# rubocop:enable Metrics/AbcSize
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: react_on_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 16.0.1.rc.
|
4
|
+
version: 16.0.1.rc.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Gordon
|
@@ -133,6 +133,11 @@ files:
|
|
133
133
|
- SUMMARY.md
|
134
134
|
- TODO.md
|
135
135
|
- app/helpers/react_on_rails_helper.rb
|
136
|
+
- bin/lefthook/check-trailing-newlines
|
137
|
+
- bin/lefthook/get-changed-files
|
138
|
+
- bin/lefthook/prettier-format
|
139
|
+
- bin/lefthook/ruby-autofix
|
140
|
+
- bin/lefthook/ruby-lint
|
136
141
|
- docker-compose.yml
|
137
142
|
- eslint.config.ts
|
138
143
|
- knip.ts
|
@@ -237,7 +242,6 @@ files:
|
|
237
242
|
- lib/tasks/doctor.rake
|
238
243
|
- lib/tasks/generate_packs.rake
|
239
244
|
- lib/tasks/locale.rake
|
240
|
-
- package-lock.json
|
241
245
|
- react_on_rails.gemspec
|
242
246
|
- tsconfig.eslint.json
|
243
247
|
- tsconfig.json
|