react_on_rails 16.4.0 → 16.5.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/generator_messages.rb +20 -18
- data/lib/generators/react_on_rails/install_generator.rb +128 -12
- data/lib/generators/react_on_rails/pro_generator.rb +1 -1
- data/lib/generators/react_on_rails/pro_setup.rb +3 -2
- data/lib/generators/react_on_rails/react_with_redux_generator.rb +2 -1
- data/lib/generators/react_on_rails/rsc_generator.rb +1 -1
- data/lib/generators/react_on_rails/templates/base/base/bin/dev +1 -1
- data/lib/generators/react_on_rails/templates/pro/base/client/node-renderer.js +8 -4
- data/lib/generators/react_on_rails/templates/pro/base/config/initializers/react_on_rails_pro.rb.tt +1 -1
- data/lib/generators/react_on_rails/templates/rsc/base/app/controllers/hello_server_controller.rb.tt +1 -1
- data/lib/generators/react_on_rails/templates/rsc/base/app/javascript/src/HelloServer/components/HelloServer.jsx +1 -1
- data/lib/generators/react_on_rails/templates/rsc/base/app/javascript/src/HelloServer/components/HelloServer.tsx +1 -1
- data/lib/generators/react_on_rails/templates/rsc/base/app/views/hello_server/index.html.erb +1 -1
- data/lib/generators/react_on_rails/templates/rsc/base/config/webpack/rscWebpackConfig.js.tt +1 -1
- data/lib/react_on_rails/config_path_resolver.rb +50 -0
- data/lib/react_on_rails/configuration.rb +1 -1
- data/lib/react_on_rails/dev/process_manager.rb +16 -1
- data/lib/react_on_rails/dev/server_manager.rb +2 -2
- data/lib/react_on_rails/doctor.rb +389 -25
- data/lib/react_on_rails/git_utils.rb +95 -23
- data/lib/react_on_rails/packer_utils.rb +1 -1
- data/lib/react_on_rails/packs_generator.rb +3 -3
- data/lib/react_on_rails/react_component/render_options.rb +48 -0
- data/lib/react_on_rails/server_rendering_js_code.rb +1 -1
- data/lib/react_on_rails/system_checker.rb +42 -19
- data/lib/react_on_rails/utils.rb +1 -1
- data/lib/react_on_rails/version.rb +1 -1
- data/lib/react_on_rails/version_synchronizer.rb +250 -0
- data/lib/tasks/generate_packs.rake +3 -3
- data/lib/tasks/sync_versions.rake +23 -0
- data/rakelib/examples_config.yml +1 -1
- data/rakelib/update_changelog.rake +3 -3
- data/react_on_rails.gemspec +1 -1
- data/sig/react_on_rails/dev/process_manager.rbs +2 -0
- metadata +6 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 14bbaccde12f9bb4f998ade94c02d95d27e1df386a9dfaf887fefb0f073070e0
|
|
4
|
+
data.tar.gz: 952bf7eb1d5694d86b74dd654ab2cb10fd7490207d6be3c66ac6ea4866802eee
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3bdbf4f3343cf568ea879a13d0902d650379016004832c44affd1498ac8c0be881de9e7d4bb42ecd883f095f5697518dfcc773d7d79b61c4250026457100d9cd
|
|
7
|
+
data.tar.gz: 920530b24dbe7d23af418d53ad564e9f75bbf0f21fcc03851b89de03994d6a1e910fdaeb962da9eb4f66eed0cc37f28a9048fd2dcf3d208c9422843a7208fe4c
|
data/Gemfile.lock
CHANGED
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
require "rainbow"
|
|
4
4
|
|
|
5
5
|
module GeneratorMessages
|
|
6
|
+
PRO_UPGRADE_HINT = "\n\n 💎 For RSC, streaming SSR, and 10-100x faster SSR, try React on Rails Pro:" \
|
|
7
|
+
"\n #{Rainbow('https://reactonrails.com/docs/pro/upgrading-to-pro/').cyan.underline}".freeze
|
|
8
|
+
|
|
6
9
|
class << self
|
|
7
10
|
def output
|
|
8
11
|
@output ||= []
|
|
@@ -40,14 +43,16 @@ module GeneratorMessages
|
|
|
40
43
|
@output = []
|
|
41
44
|
end
|
|
42
45
|
|
|
43
|
-
def helpful_message_after_installation(component_name: "HelloWorld", route: "hello_world",
|
|
44
|
-
shakapacker_just_installed: false)
|
|
46
|
+
def helpful_message_after_installation(component_name: "HelloWorld", route: "hello_world", pro: false,
|
|
47
|
+
rsc: false, shakapacker_just_installed: false)
|
|
45
48
|
process_manager_section = build_process_manager_section
|
|
46
49
|
testing_section = build_testing_section
|
|
47
50
|
package_manager = detect_package_manager
|
|
48
51
|
shakapacker_status = build_shakapacker_status_section(shakapacker_just_installed: shakapacker_just_installed)
|
|
49
52
|
render_example = build_render_example(component_name: component_name, route: route, rsc: rsc)
|
|
50
53
|
render_label = build_render_label(route: route, rsc: rsc)
|
|
54
|
+
# rsc guard is defensive; callers via install_generator already pass pro: true when rsc is set
|
|
55
|
+
pro_hint = pro || rsc ? "" : PRO_UPGRADE_HINT
|
|
51
56
|
|
|
52
57
|
<<~MSG
|
|
53
58
|
|
|
@@ -61,13 +66,16 @@ module GeneratorMessages
|
|
|
61
66
|
1. Install dependencies:
|
|
62
67
|
#{Rainbow("bundle && #{package_manager} install").cyan}
|
|
63
68
|
|
|
64
|
-
2.
|
|
69
|
+
2. Prepare database:
|
|
70
|
+
#{Rainbow('bin/rails db:prepare').cyan}
|
|
71
|
+
|
|
72
|
+
3. Start the app:
|
|
65
73
|
./bin/dev # HMR (Hot Module Replacement) mode
|
|
66
74
|
./bin/dev static # Static bundles (no HMR, faster initial load)
|
|
67
75
|
./bin/dev prod # Production-like mode for testing
|
|
68
76
|
./bin/dev help # See all available options
|
|
69
77
|
|
|
70
|
-
|
|
78
|
+
4. Visit: #{Rainbow(route ? "http://localhost:3000/#{route}" : 'http://localhost:3000').cyan.underline}
|
|
71
79
|
✨ KEY FEATURES:
|
|
72
80
|
─────────────────────────────────────────────────────────────────────────
|
|
73
81
|
• Auto-registration enabled - Your layout only needs:
|
|
@@ -79,16 +87,19 @@ module GeneratorMessages
|
|
|
79
87
|
|
|
80
88
|
📚 LEARN MORE:
|
|
81
89
|
─────────────────────────────────────────────────────────────────────────
|
|
82
|
-
• Documentation: #{Rainbow('https://
|
|
90
|
+
• Documentation: #{Rainbow('https://reactonrails.com/docs/').cyan.underline}
|
|
83
91
|
• Webpack customization: #{Rainbow('https://github.com/shakacode/shakapacker#webpack-configuration').cyan.underline}
|
|
84
92
|
|
|
85
|
-
💡 TIP: Run 'bin/dev help' for development server options and troubleshooting#{testing_section}
|
|
93
|
+
💡 TIP: Run 'bin/dev help' for development server options and troubleshooting#{testing_section}#{pro_hint}
|
|
86
94
|
MSG
|
|
87
95
|
end
|
|
88
96
|
|
|
89
97
|
# Uses relative lockfile paths resolved against Dir.pwd, so callers must invoke
|
|
90
98
|
# this while the current working directory is the target Rails app root.
|
|
91
99
|
def detect_package_manager
|
|
100
|
+
env_package_manager = ENV.fetch("REACT_ON_RAILS_PACKAGE_MANAGER", nil)&.strip&.downcase
|
|
101
|
+
return env_package_manager if %w[npm pnpm yarn bun].include?(env_package_manager)
|
|
102
|
+
|
|
92
103
|
# Check for lock files to determine package manager
|
|
93
104
|
return "yarn" if File.exist?("yarn.lock")
|
|
94
105
|
return "pnpm" if File.exist?("pnpm-lock.yaml")
|
|
@@ -133,10 +144,7 @@ module GeneratorMessages
|
|
|
133
144
|
end
|
|
134
145
|
|
|
135
146
|
def build_testing_section
|
|
136
|
-
|
|
137
|
-
has_spec_files = File.exist?("spec/rails_helper.rb") || File.exist?("spec/spec_helper.rb")
|
|
138
|
-
|
|
139
|
-
return "" if has_spec_files
|
|
147
|
+
return "" if File.exist?("spec/rails_helper.rb") || File.exist?("spec/spec_helper.rb")
|
|
140
148
|
|
|
141
149
|
<<~TESTING
|
|
142
150
|
|
|
@@ -160,7 +168,6 @@ module GeneratorMessages
|
|
|
160
168
|
|
|
161
169
|
def build_shakapacker_status_section(shakapacker_just_installed: false)
|
|
162
170
|
version_warning = check_shakapacker_version_warning
|
|
163
|
-
|
|
164
171
|
if shakapacker_just_installed
|
|
165
172
|
base = <<~SHAKAPACKER
|
|
166
173
|
|
|
@@ -179,18 +186,13 @@ module GeneratorMessages
|
|
|
179
186
|
end
|
|
180
187
|
|
|
181
188
|
def check_shakapacker_version_warning
|
|
182
|
-
# Try to detect Shakapacker version from Gemfile.lock
|
|
183
189
|
return "" unless File.exist?("Gemfile.lock")
|
|
184
190
|
|
|
185
|
-
|
|
186
|
-
shakapacker_match = gemfile_lock_content.match(/shakapacker \((\d+\.\d+\.\d+)\)/)
|
|
187
|
-
|
|
191
|
+
shakapacker_match = File.read("Gemfile.lock").match(/shakapacker \((\d+\.\d+\.\d+)\)/)
|
|
188
192
|
return "" unless shakapacker_match
|
|
189
193
|
|
|
190
194
|
version = shakapacker_match[1]
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
if major_version < 8
|
|
195
|
+
if version.split(".").first.to_i < 8
|
|
194
196
|
<<~WARNING
|
|
195
197
|
|
|
196
198
|
⚠️ #{Rainbow('IMPORTANT: Upgrade Recommended').yellow.bold}
|
|
@@ -79,6 +79,49 @@ module ReactOnRails
|
|
|
79
79
|
# Removed: --skip-shakapacker-install (Shakapacker is now a required dependency)
|
|
80
80
|
|
|
81
81
|
SHAKAPACKER_YML_PATH = "config/shakapacker.yml"
|
|
82
|
+
# Matches the stock `bin/dev` written by Rails 8.x. Rails 7.1 commonly
|
|
83
|
+
# generated a foreman-based shell script instead, which stock_rails_bin_dev?
|
|
84
|
+
# also recognizes so the React on Rails template can replace either variant.
|
|
85
|
+
STOCK_RAILS_BIN_DEV = <<~RUBY
|
|
86
|
+
#!/usr/bin/env ruby
|
|
87
|
+
exec "./bin/rails", "server", *ARGV
|
|
88
|
+
RUBY
|
|
89
|
+
# Recognize only known legacy Rails foreman templates. Any other variant is
|
|
90
|
+
# treated as customized so install does not overwrite app-specific logic.
|
|
91
|
+
LEGACY_FOREMAN_BIN_DEV_TEMPLATES = [
|
|
92
|
+
<<~BASH,
|
|
93
|
+
#!/usr/bin/env bash
|
|
94
|
+
if ! gem list foreman -i --silent; then
|
|
95
|
+
gem install foreman
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
exec foreman start -f Procfile.dev "$@"
|
|
99
|
+
BASH
|
|
100
|
+
<<~SH,
|
|
101
|
+
#!/usr/bin/env sh
|
|
102
|
+
if ! gem list foreman -i --silent; then
|
|
103
|
+
gem install foreman
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
exec foreman start -f Procfile.dev "$@"
|
|
107
|
+
SH
|
|
108
|
+
<<~BASH,
|
|
109
|
+
#!/usr/bin/env bash
|
|
110
|
+
if ! gem list foreman -i --silent; then
|
|
111
|
+
gem install foreman
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
exec foreman start -f Procfile.dev $@
|
|
115
|
+
BASH
|
|
116
|
+
<<~SH
|
|
117
|
+
#!/usr/bin/env sh
|
|
118
|
+
if ! gem list foreman -i --silent; then
|
|
119
|
+
gem install foreman
|
|
120
|
+
fi
|
|
121
|
+
|
|
122
|
+
exec foreman start -f Procfile.dev $@
|
|
123
|
+
SH
|
|
124
|
+
].map { |template| template.gsub("\r\n", "\n").strip }.freeze
|
|
82
125
|
|
|
83
126
|
# Main generator entry point
|
|
84
127
|
#
|
|
@@ -188,10 +231,28 @@ module ReactOnRails
|
|
|
188
231
|
# js(.coffee) are not checked by this method, but instead produce warning messages
|
|
189
232
|
# and allow the build to continue
|
|
190
233
|
def installation_prerequisites_met?
|
|
191
|
-
#
|
|
192
|
-
#
|
|
193
|
-
|
|
194
|
-
|
|
234
|
+
# Non-blocking: warn about dirty worktree but don't prevent installation.
|
|
235
|
+
# A clean tree makes the generator diff easier to review, but blocking would
|
|
236
|
+
# be too strict for a generator that creates many new files.
|
|
237
|
+
has_worktree_issues = ReactOnRails::GitUtils.warn_if_uncommitted_changes(
|
|
238
|
+
GeneratorMessages, git_installed: cli_exists?("git")
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
# missing_pro_gem? may auto-install the gem (mutating Gemfile), so only run
|
|
242
|
+
# it on a clean worktree. On a dirty tree, use the read-only pro_gem_installed?
|
|
243
|
+
# check to catch a missing gem without triggering auto-install.
|
|
244
|
+
if has_worktree_issues && use_pro? && !pro_gem_installed?
|
|
245
|
+
GeneratorMessages.add_error(<<~MSG.strip)
|
|
246
|
+
🚫 react_on_rails_pro gem is required for #{options[:rsc] ? '--rsc' : '--pro'} but is not installed.
|
|
247
|
+
Auto-install was skipped because the worktree has uncommitted changes.
|
|
248
|
+
Please add it manually:
|
|
249
|
+
gem 'react_on_rails_pro', '~> #{recommended_pro_gem_version}'
|
|
250
|
+
Then run: bundle install
|
|
251
|
+
MSG
|
|
252
|
+
return false
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
!(missing_node? || missing_package_manager? || (!has_worktree_issues && missing_pro_gem?))
|
|
195
256
|
end
|
|
196
257
|
|
|
197
258
|
def missing_node?
|
|
@@ -277,13 +338,23 @@ module ReactOnRails
|
|
|
277
338
|
end
|
|
278
339
|
|
|
279
340
|
def add_bin_scripts
|
|
341
|
+
replace_stock_rails_bin_dev!
|
|
342
|
+
|
|
280
343
|
# Copy bin scripts from templates
|
|
281
344
|
template_bin_path = "#{__dir__}/templates/base/base/bin"
|
|
282
|
-
|
|
345
|
+
directory_options = {}
|
|
346
|
+
directory_options[:exclude_pattern] = %r{/dev(?:\.tt)?\z} if preserve_existing_bin_dev?
|
|
347
|
+
directory template_bin_path, "bin", directory_options
|
|
283
348
|
|
|
284
349
|
# For --rsc without --redux, hello_world doesn't exist — update DEFAULT_ROUTE
|
|
285
350
|
if use_rsc? && !options.redux?
|
|
286
|
-
|
|
351
|
+
if preserve_existing_bin_dev?
|
|
352
|
+
say_status :warn,
|
|
353
|
+
'Custom bin/dev detected: update DEFAULT_ROUTE to "hello_server" manually for --rsc',
|
|
354
|
+
:yellow
|
|
355
|
+
else
|
|
356
|
+
gsub_file "bin/dev", 'DEFAULT_ROUTE = "hello_world"', 'DEFAULT_ROUTE = "hello_server"'
|
|
357
|
+
end
|
|
287
358
|
end
|
|
288
359
|
|
|
289
360
|
# `directory` and `gsub_file` above are Thor actions that already honor
|
|
@@ -294,13 +365,48 @@ module ReactOnRails
|
|
|
294
365
|
end
|
|
295
366
|
|
|
296
367
|
# Make these and only these files executable
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
368
|
+
files_to_become_executable = bin_scripts_to_chmod(template_bin_path)
|
|
369
|
+
File.chmod(0o755, *files_to_become_executable)
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
def replace_stock_rails_bin_dev!
|
|
373
|
+
@preserve_existing_bin_dev = false
|
|
374
|
+
|
|
375
|
+
unless stock_rails_bin_dev?
|
|
376
|
+
if File.exist?("bin/dev")
|
|
377
|
+
say_status :skip, "bin/dev exists but does not match a stock Rails template; keeping existing file", :yellow
|
|
378
|
+
@preserve_existing_bin_dev = true
|
|
379
|
+
end
|
|
380
|
+
return
|
|
300
381
|
end
|
|
301
|
-
files_to_become_executable = files_to_copy.map { |filename| "bin/#{filename}" }
|
|
302
382
|
|
|
303
|
-
|
|
383
|
+
if options[:pretend] || options[:skip]
|
|
384
|
+
say_status :skip, "Detected stock Rails bin/dev; leaving existing file in place for --pretend/--skip", :yellow
|
|
385
|
+
@preserve_existing_bin_dev = true
|
|
386
|
+
return
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
say_status :replace, "Detected stock Rails bin/dev; installing React on Rails bin/dev", :yellow
|
|
390
|
+
remove_file "bin/dev", verbose: false
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
def preserve_existing_bin_dev?
|
|
394
|
+
# Set by replace_stock_rails_bin_dev! which always runs first via add_bin_scripts.
|
|
395
|
+
# Explicitly coerce to boolean so nil (before initialization) is treated as false.
|
|
396
|
+
!!@preserve_existing_bin_dev
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
def bin_scripts_to_chmod(template_bin_path)
|
|
400
|
+
files = Dir.children(template_bin_path)
|
|
401
|
+
files.reject! { |f| f == "dev" } if preserve_existing_bin_dev?
|
|
402
|
+
files.map { |filename| "bin/#{filename}" }
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
def stock_rails_bin_dev?
|
|
406
|
+
return false unless File.exist?("bin/dev")
|
|
407
|
+
|
|
408
|
+
content = normalize_bin_dev_content(File.read("bin/dev"))
|
|
409
|
+
content == normalize_bin_dev_content(STOCK_RAILS_BIN_DEV) || legacy_foreman_bin_dev?(content)
|
|
304
410
|
end
|
|
305
411
|
|
|
306
412
|
def add_post_install_message
|
|
@@ -322,6 +428,7 @@ module ReactOnRails
|
|
|
322
428
|
GeneratorMessages.add_info(GeneratorMessages.helpful_message_after_installation(
|
|
323
429
|
component_name: component_name,
|
|
324
430
|
route: route,
|
|
431
|
+
pro: use_pro?,
|
|
325
432
|
rsc: use_rsc?,
|
|
326
433
|
shakapacker_just_installed: shakapacker_just_installed?
|
|
327
434
|
))
|
|
@@ -411,7 +518,16 @@ module ReactOnRails
|
|
|
411
518
|
end
|
|
412
519
|
|
|
413
520
|
def cli_exists?(command)
|
|
414
|
-
|
|
521
|
+
which_command = ReactOnRails::Utils.running_on_windows? ? "where" : "which"
|
|
522
|
+
system(which_command, command, out: File::NULL, err: File::NULL)
|
|
523
|
+
end
|
|
524
|
+
|
|
525
|
+
def normalize_bin_dev_content(content)
|
|
526
|
+
content.gsub("\r\n", "\n").strip
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
def legacy_foreman_bin_dev?(content)
|
|
530
|
+
LEGACY_FOREMAN_BIN_DEV_TEMPLATES.include?(content)
|
|
415
531
|
end
|
|
416
532
|
|
|
417
533
|
def shakapacker_binaries_exist?
|
|
@@ -78,8 +78,9 @@ module ReactOnRails
|
|
|
78
78
|
|
|
79
79
|
Then run: bundle install
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
No license needed for evaluation or non-production use.
|
|
82
|
+
Free or low-cost production licenses available for startups and small companies.
|
|
83
|
+
Get started: https://pro.reactonrails.com/
|
|
83
84
|
MSG
|
|
84
85
|
true
|
|
85
86
|
end
|
|
@@ -99,7 +99,8 @@ module ReactOnRails
|
|
|
99
99
|
|
|
100
100
|
# Append Redux-specific post-install instructions
|
|
101
101
|
GeneratorMessages.add_info(
|
|
102
|
-
GeneratorMessages.helpful_message_after_installation(component_name: "HelloWorldApp", route: "hello_world"
|
|
102
|
+
GeneratorMessages.helpful_message_after_installation(component_name: "HelloWorldApp", route: "hello_world",
|
|
103
|
+
pro: Gem.loaded_specs.key?("react_on_rails_pro"))
|
|
103
104
|
)
|
|
104
105
|
end
|
|
105
106
|
|
|
@@ -92,7 +92,7 @@ module ReactOnRails
|
|
|
92
92
|
2. Visit http://localhost:3000/hello_server to see RSC in action
|
|
93
93
|
3. The RSC bundle watcher will compile server components
|
|
94
94
|
|
|
95
|
-
Documentation: https://
|
|
95
|
+
Documentation: https://reactonrails.com/docs/pro/react-server-components/
|
|
96
96
|
MSG
|
|
97
97
|
end
|
|
98
98
|
end
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
# 2. Remove precompile_hook from config/shakapacker.yml if present
|
|
36
36
|
# 3. Uncomment the run_precompile_tasks call near the bottom of this file
|
|
37
37
|
#
|
|
38
|
-
# See documentation: https://
|
|
38
|
+
# See documentation: https://reactonrails.com/docs/building-features/extensible-precompile-pattern
|
|
39
39
|
#
|
|
40
40
|
# def run_precompile_tasks
|
|
41
41
|
# require_relative "../config/environment"
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
|
-
const { reactOnRailsProNodeRenderer } = require('react-on-rails-pro-node-renderer');
|
|
2
|
+
const { reactOnRailsProNodeRenderer, parseWorkersCount } = require('react-on-rails-pro-node-renderer');
|
|
3
3
|
|
|
4
4
|
const { env } = process;
|
|
5
|
+
const configuredWorkersCount =
|
|
6
|
+
parseWorkersCount(env.RENDERER_WORKERS_COUNT) ?? parseWorkersCount(env.NODE_RENDERER_CONCURRENCY);
|
|
5
7
|
|
|
6
8
|
const config = {
|
|
7
9
|
serverBundleCachePath: path.resolve(__dirname, '../.node-renderer-bundles'),
|
|
@@ -12,8 +14,10 @@ const config = {
|
|
|
12
14
|
password: env.RENDERER_PASSWORD || 'devPassword',
|
|
13
15
|
|
|
14
16
|
// Number of Node.js worker threads for SSR rendering
|
|
15
|
-
// Set
|
|
16
|
-
|
|
17
|
+
// Set RENDERER_WORKERS_COUNT env var to override (e.g., for production tuning)
|
|
18
|
+
// Set to 0 for single-process mode (useful for debugging).
|
|
19
|
+
// Legacy fallback: NODE_RENDERER_CONCURRENCY
|
|
20
|
+
workersCount: configuredWorkersCount ?? 3,
|
|
17
21
|
|
|
18
22
|
// If set to true, `supportModules` enables the server-bundle code to call a default set of NodeJS modules
|
|
19
23
|
// that get added to the VM context: { Buffer, process, setTimeout, setInterval, clearTimeout, clearInterval }.
|
|
@@ -34,7 +38,7 @@ const config = {
|
|
|
34
38
|
// Renderer detects a total number of CPUs on virtual hostings like Heroku or CircleCI instead
|
|
35
39
|
// of CPUs number allocated for current container. This results in spawning many workers while
|
|
36
40
|
// only 1-2 of them really needed.
|
|
37
|
-
if (env.CI) {
|
|
41
|
+
if (env.CI && configuredWorkersCount == null) {
|
|
38
42
|
config.workersCount = 2;
|
|
39
43
|
}
|
|
40
44
|
|
data/lib/generators/react_on_rails/templates/pro/base/config/initializers/react_on_rails_pro.rb.tt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# See https://
|
|
3
|
+
# See https://reactonrails.com/docs/configuration/configuration-pro
|
|
4
4
|
# License: Set REACT_ON_RAILS_PRO_LICENSE environment variable
|
|
5
5
|
ReactOnRailsPro.configure do |config|
|
|
6
6
|
config.server_renderer = "NodeRenderer"
|
data/lib/generators/react_on_rails/templates/rsc/base/app/controllers/hello_server_controller.rb.tt
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
# - Automatic hydration on the client
|
|
11
11
|
#
|
|
12
12
|
# For more information, see:
|
|
13
|
-
# https://
|
|
13
|
+
# https://reactonrails.com/docs/pro/react-server-components/
|
|
14
14
|
|
|
15
15
|
class HelloServerController < ApplicationController
|
|
16
16
|
layout "<%= config[:layout_name] %>"
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
// 4. Streaming — wrapped in <Suspense>, this component streams HTML as it resolves
|
|
10
10
|
//
|
|
11
11
|
// For more information, see:
|
|
12
|
-
// https://
|
|
12
|
+
// https://reactonrails.com/docs/pro/react-server-components/
|
|
13
13
|
|
|
14
14
|
import React from 'react';
|
|
15
15
|
import LikeButton from './LikeButton';
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
// 4. Streaming — wrapped in <Suspense>, this component streams HTML as it resolves
|
|
10
10
|
//
|
|
11
11
|
// For more information, see:
|
|
12
|
-
// https://
|
|
12
|
+
// https://reactonrails.com/docs/pro/react-server-components/
|
|
13
13
|
|
|
14
14
|
import React from 'react';
|
|
15
15
|
import LikeButton from './LikeButton';
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
|
|
31
31
|
<p style="margin-top: 16px;">
|
|
32
32
|
<strong>Learn more:</strong>
|
|
33
|
-
<a href="https://
|
|
33
|
+
<a href="https://reactonrails.com/docs/pro/react-server-components/">
|
|
34
34
|
React Server Components Documentation
|
|
35
35
|
</a>
|
|
36
36
|
</p>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// React Server Components webpack configuration
|
|
2
2
|
// This creates the RSC bundle based on the server webpack config
|
|
3
|
-
// See: https://
|
|
3
|
+
// See: https://reactonrails.com/docs/pro/react-server-components/
|
|
4
4
|
|
|
5
5
|
const serverWebpackModule = require('./serverWebpackConfig');
|
|
6
6
|
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ReactOnRails
|
|
4
|
+
module ConfigPathResolver
|
|
5
|
+
private
|
|
6
|
+
|
|
7
|
+
def resolved_package_json_path
|
|
8
|
+
node_modules_location = ReactOnRails.configuration.node_modules_location.to_s
|
|
9
|
+
return "package.json" if node_modules_location.empty? || node_modules_location == Rails.root.to_s
|
|
10
|
+
|
|
11
|
+
Rails.root.join(node_modules_location, "package.json").to_s
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def resolved_webpack_config_path
|
|
15
|
+
webpack_config_candidates.find { |path| File.exist?(path) }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def webpack_config_candidates
|
|
19
|
+
candidates = []
|
|
20
|
+
|
|
21
|
+
shakapacker_config_dir = shakapacker_webpack_config_directory
|
|
22
|
+
if shakapacker_config_dir
|
|
23
|
+
candidates.concat(%w[js ts cjs mjs].flat_map do |ext|
|
|
24
|
+
[
|
|
25
|
+
File.join(shakapacker_config_dir, "webpack.config.#{ext}"),
|
|
26
|
+
File.join(shakapacker_config_dir, "rspack.config.#{ext}")
|
|
27
|
+
]
|
|
28
|
+
end)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
candidates << "config/webpack/webpack.config.js"
|
|
32
|
+
candidates << "config/webpack/webpack.config.ts"
|
|
33
|
+
candidates << "config/rspack/rspack.config.js"
|
|
34
|
+
candidates << "config/rspack/rspack.config.ts"
|
|
35
|
+
candidates.uniq
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def shakapacker_webpack_config_directory
|
|
39
|
+
require "shakapacker"
|
|
40
|
+
path = Shakapacker.config.assets_bundler_config_path.to_s
|
|
41
|
+
return nil if path.empty?
|
|
42
|
+
|
|
43
|
+
directory = File.dirname(path)
|
|
44
|
+
rails_root = Rails.root.to_s
|
|
45
|
+
directory.start_with?("#{rails_root}/") ? directory.sub("#{rails_root}/", "") : directory
|
|
46
|
+
rescue LoadError, StandardError
|
|
47
|
+
nil
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -463,7 +463,7 @@ module ReactOnRails
|
|
|
463
463
|
msg = <<~MSG
|
|
464
464
|
**ERROR** ReactOnRails: auto_load_bundle is set to true, yet components_subdirectory is not configured.\
|
|
465
465
|
Please set components_subdirectory to the desired directory. For more information, please see \
|
|
466
|
-
https://
|
|
466
|
+
https://reactonrails.com/docs/guides/file-system-based-automated-bundle-generation.md
|
|
467
467
|
MSG
|
|
468
468
|
|
|
469
469
|
raise ReactOnRails::Error, msg
|
|
@@ -8,6 +8,14 @@ module ReactOnRails
|
|
|
8
8
|
# Timeout for version check operations to prevent hanging
|
|
9
9
|
VERSION_CHECK_TIMEOUT = 5
|
|
10
10
|
|
|
11
|
+
# Env vars set after Bundler.setup that must survive with_unbundled_env.
|
|
12
|
+
# with_unbundled_env restores the pre-Bundler env snapshot, so any var
|
|
13
|
+
# set at runtime (e.g. PORT by PortSelector) is lost. We capture them
|
|
14
|
+
# before entering the block and pass them explicitly to system().
|
|
15
|
+
# This follows the same pattern used by Rails' bundle_command (railties),
|
|
16
|
+
# Spring's process spawning, and this codebase's own PackGenerator.
|
|
17
|
+
ENV_KEYS_TO_PRESERVE = %w[PORT SHAKAPACKER_DEV_SERVER_PORT].freeze
|
|
18
|
+
|
|
11
19
|
class << self
|
|
12
20
|
# Check if a process is available and usable in the current execution context
|
|
13
21
|
# This accounts for bundler context where system commands might be intercepted
|
|
@@ -103,8 +111,9 @@ module ReactOnRails
|
|
|
103
111
|
# This allows using system-installed processes even when they're not in the Gemfile
|
|
104
112
|
def run_process_outside_bundle(process, args)
|
|
105
113
|
if defined?(Bundler)
|
|
114
|
+
env_overrides = preserve_runtime_env_vars
|
|
106
115
|
with_unbundled_context do
|
|
107
|
-
system(process, *args)
|
|
116
|
+
system(env_overrides, process, *args)
|
|
108
117
|
end
|
|
109
118
|
else
|
|
110
119
|
# Fallback if Bundler is not available
|
|
@@ -168,6 +177,12 @@ module ReactOnRails
|
|
|
168
177
|
MSG
|
|
169
178
|
end
|
|
170
179
|
|
|
180
|
+
def preserve_runtime_env_vars
|
|
181
|
+
ENV_KEYS_TO_PRESERVE.each_with_object({}) do |key, hash|
|
|
182
|
+
hash[key] = ENV[key] if ENV[key]
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
171
186
|
def valid_procfile_path?(procfile)
|
|
172
187
|
# Reject paths with shell metacharacters
|
|
173
188
|
return false if procfile.match?(/[;&|`$(){}\[\]<>]/)
|
|
@@ -457,7 +457,7 @@ module ReactOnRails
|
|
|
457
457
|
puts Rainbow(" 1. Upgrade to Shakapacker 9.4.0 or later:").cyan
|
|
458
458
|
puts Rainbow(" bundle update shakapacker").cyan.bold
|
|
459
459
|
puts Rainbow(" 2. Or switch to a script-based hook with a self-guard.").cyan
|
|
460
|
-
puts Rainbow(" See: https://
|
|
460
|
+
puts Rainbow(" See: https://reactonrails.com/docs/building-features/process-managers").cyan
|
|
461
461
|
puts ""
|
|
462
462
|
end
|
|
463
463
|
# rubocop:enable Metrics/AbcSize
|
|
@@ -889,7 +889,7 @@ module ReactOnRails
|
|
|
889
889
|
#{Rainbow('📖 DOCUMENTATION:').cyan.bold}
|
|
890
890
|
#{Rainbow('•').yellow} #{Rainbow('Testing & dev server guide:').white} #{Rainbow('docs/oss/building-features/dev-server-and-testing.md').green}
|
|
891
891
|
#{Rainbow('•').yellow} #{Rainbow('Testing configuration:').white} #{Rainbow('docs/oss/building-features/testing-configuration.md').green}
|
|
892
|
-
#{Rainbow('•').yellow} #{Rainbow('Full docs:').white} #{Rainbow('https://
|
|
892
|
+
#{Rainbow('•').yellow} #{Rainbow('Full docs:').white} #{Rainbow('https://reactonrails.com/docs/').cyan.underline}
|
|
893
893
|
TROUBLESHOOTING
|
|
894
894
|
end
|
|
895
895
|
# rubocop:enable Metrics/AbcSize
|