react_on_rails 16.6.0 → 16.7.0.rc.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/.rubocop.yml +1 -0
- data/Gemfile.development_dependencies +2 -2
- data/Gemfile.lock +2 -14
- data/Rakefile +0 -6
- data/Steepfile +4 -0
- data/lib/generators/react_on_rails/base_generator.rb +4 -4
- data/lib/generators/react_on_rails/demo_page_config.rb +3 -3
- data/lib/generators/react_on_rails/dev_tests_generator.rb +1 -1
- data/lib/generators/react_on_rails/generator_helper.rb +6 -65
- data/lib/generators/react_on_rails/generator_messages/ci_section.rb +42 -0
- data/lib/generators/react_on_rails/generator_messages/package_manager_detection.rb +194 -0
- data/lib/generators/react_on_rails/generator_messages/shakapacker_status_section.rb +61 -0
- data/lib/generators/react_on_rails/generator_messages.rb +22 -79
- data/lib/generators/react_on_rails/install_generator.rb +243 -28
- data/lib/generators/react_on_rails/js_dependency_manager.rb +7 -4
- data/lib/generators/react_on_rails/pro/USAGE +1 -1
- data/lib/generators/react_on_rails/pro_generator.rb +206 -183
- data/lib/generators/react_on_rails/pro_setup.rb +102 -26
- data/lib/generators/react_on_rails/react_with_redux_generator.rb +3 -2
- data/lib/generators/react_on_rails/templates/base/base/.env.example +25 -0
- data/lib/generators/react_on_rails/templates/base/base/.github/workflows/ci.yml.tt +86 -0
- data/lib/generators/react_on_rails/templates/base/base/Procfile.dev +4 -3
- data/lib/generators/react_on_rails/templates/base/base/babel.config.js.tt +1 -1
- data/lib/generators/react_on_rails/templates/base/base/bin/switch-bundler +2 -2
- data/lib/generators/react_on_rails/templates/base/base/config/webpack/ServerClientOrBoth.js.tt +1 -1
- data/lib/generators/react_on_rails/templates/base/base/config/webpack/clientWebpackConfig.js.tt +1 -1
- data/lib/generators/react_on_rails/templates/base/base/config/webpack/commonWebpackConfig.js.tt +2 -2
- data/lib/generators/react_on_rails/templates/base/base/config/webpack/development.js.tt +1 -1
- data/lib/generators/react_on_rails/templates/base/base/config/webpack/production.js.tt +1 -1
- data/lib/generators/react_on_rails/templates/base/base/config/webpack/serverWebpackConfig.js.tt +6 -5
- data/lib/generators/react_on_rails/templates/base/base/config/webpack/test.js.tt +1 -1
- 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/pro/base/{client → renderer}/node-renderer.js +1 -0
- data/lib/react_on_rails/config_path_resolver.rb +101 -4
- data/lib/react_on_rails/configuration.rb +22 -0
- data/lib/react_on_rails/dev/file_manager.rb +135 -8
- data/lib/react_on_rails/dev/port_selector.rb +259 -7
- data/lib/react_on_rails/dev/process_manager.rb +29 -2
- data/lib/react_on_rails/dev/server_manager.rb +607 -39
- data/lib/react_on_rails/doctor.rb +513 -45
- data/lib/react_on_rails/helper.rb +3 -11
- data/lib/react_on_rails/js_code_builder.rb +66 -0
- data/lib/react_on_rails/length_prefixed_parser.rb +142 -0
- data/lib/react_on_rails/packs_generator.rb +65 -12
- data/lib/react_on_rails/pro_migration.rb +175 -0
- data/lib/react_on_rails/render_request.rb +74 -0
- data/lib/react_on_rails/rendering_strategy/exec_js_strategy.rb +29 -0
- data/lib/react_on_rails/rendering_strategy.rb +44 -0
- data/lib/react_on_rails/server_rendering_pool/ruby_embedded_java_script.rb +33 -22
- data/lib/react_on_rails/system_checker.rb +44 -23
- data/lib/react_on_rails/utils.rb +5 -0
- data/lib/react_on_rails/version.rb +1 -1
- data/lib/react_on_rails.rb +3 -0
- data/rakelib/run_rspec.rake +0 -5
- data/rakelib/shakapacker_examples.rake +66 -23
- data/react_on_rails.gemspec +18 -8
- data/sig/react_on_rails/js_code_builder.rbs +11 -0
- data/sig/react_on_rails/render_request.rbs +28 -0
- data/sig/react_on_rails/rendering_strategy/exec_js_strategy.rbs +11 -0
- data/sig/react_on_rails/rendering_strategy.rbs +7 -0
- data/sig/react_on_rails.rbs +6 -0
- metadata +31 -10
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require "open-uri"
|
|
4
4
|
require "execjs"
|
|
5
|
+
require "react_on_rails/length_prefixed_parser"
|
|
5
6
|
|
|
6
7
|
module ReactOnRails
|
|
7
8
|
module ServerRenderingPool
|
|
@@ -79,11 +80,14 @@ module ReactOnRails
|
|
|
79
80
|
raise ReactOnRails::Error, msg, err.backtrace
|
|
80
81
|
end
|
|
81
82
|
|
|
82
|
-
return
|
|
83
|
+
return parse_render_result(result, render_options) unless render_options.streaming?
|
|
83
84
|
|
|
84
|
-
# Streamed
|
|
85
|
-
#
|
|
86
|
-
result.transform
|
|
85
|
+
# Streamed chunks are Hashes (from LengthPrefixedParser in stream_request.rb).
|
|
86
|
+
# Just replay console messages and pass through.
|
|
87
|
+
result.transform do |chunk|
|
|
88
|
+
replay_console_to_rails_logger(chunk, render_options)
|
|
89
|
+
chunk
|
|
90
|
+
end
|
|
87
91
|
end
|
|
88
92
|
|
|
89
93
|
def trace_js_code_used(msg, js_code, file_name = "tmp/server-generated.js", force: false)
|
|
@@ -224,26 +228,33 @@ module ReactOnRails
|
|
|
224
228
|
raise ReactOnRails::Error, msg
|
|
225
229
|
end
|
|
226
230
|
|
|
227
|
-
def
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
231
|
+
def parse_render_result(result_string, render_options)
|
|
232
|
+
# Auto-detect format: length-prefixed (contains tab) or legacy JSON.
|
|
233
|
+
# ExecJS with older bundles may return JSON; node renderer returns length-prefixed.
|
|
234
|
+
result = if result_string.to_s.include?("\t")
|
|
235
|
+
ReactOnRails::LengthPrefixedParser.parse_one_chunk_result(result_string)
|
|
236
|
+
else
|
|
237
|
+
JSON.parse(result_string.to_s)
|
|
238
|
+
end
|
|
239
|
+
replay_console_to_rails_logger(result, render_options)
|
|
240
|
+
result
|
|
241
|
+
rescue StandardError => e
|
|
242
|
+
raise ReactOnRails::JsonParseError.new(parse_error: e, json: result_string)
|
|
243
|
+
end
|
|
234
244
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
+
def replay_console_to_rails_logger(result, render_options)
|
|
246
|
+
return unless render_options.logging_on_server
|
|
247
|
+
|
|
248
|
+
console_script = result["consoleReplayScript"]
|
|
249
|
+
return if console_script.nil? || console_script.empty?
|
|
250
|
+
|
|
251
|
+
# Regular expression to match console.log or console.error calls with SERVER prefix
|
|
252
|
+
re = /console\.(?:log|error|info|warn)\.apply\(console, \["\[SERVER\] (?<msg>.*)"\]\);/
|
|
253
|
+
console_script.split("\n").each do |line|
|
|
254
|
+
match = re.match(line)
|
|
255
|
+
# Log matched messages to Rails logger with react_on_rails prefix
|
|
256
|
+
Rails.logger.info { "[react_on_rails] #{match[:msg]}" } if match
|
|
245
257
|
end
|
|
246
|
-
result
|
|
247
258
|
end
|
|
248
259
|
end
|
|
249
260
|
# rubocop:enable Metrics/ClassLength
|
|
@@ -15,6 +15,7 @@ module ReactOnRails
|
|
|
15
15
|
attr_reader :messages
|
|
16
16
|
|
|
17
17
|
SUPPORTED_ASSETS_BUNDLERS = %w[webpack rspack].freeze
|
|
18
|
+
PackageManagerDetection = Struct.new(:manager, :lockfile_scan_blocked, keyword_init: true)
|
|
18
19
|
|
|
19
20
|
def initialize
|
|
20
21
|
@messages = []
|
|
@@ -115,7 +116,8 @@ module ReactOnRails
|
|
|
115
116
|
end
|
|
116
117
|
|
|
117
118
|
# Detect which package manager is actually being used
|
|
118
|
-
|
|
119
|
+
package_manager_detection = detect_package_manager_from_lockfile
|
|
120
|
+
used_manager = package_manager_detection.manager
|
|
119
121
|
if used_manager
|
|
120
122
|
version_info = get_package_manager_version(used_manager)
|
|
121
123
|
deprecation_note = get_deprecation_note(used_manager, version_info)
|
|
@@ -124,7 +126,9 @@ module ReactOnRails
|
|
|
124
126
|
add_success(message)
|
|
125
127
|
else
|
|
126
128
|
add_success("✅ Package managers available: #{available_managers.join(', ')}")
|
|
127
|
-
|
|
129
|
+
unless package_manager_detection.lockfile_scan_blocked
|
|
130
|
+
add_info("ℹ️ No lock file detected - run npm/yarn/pnpm install to establish which manager is used")
|
|
131
|
+
end
|
|
128
132
|
end
|
|
129
133
|
true
|
|
130
134
|
end
|
|
@@ -192,8 +196,8 @@ module ReactOnRails
|
|
|
192
196
|
end
|
|
193
197
|
|
|
194
198
|
def check_react_on_rails_npm_package
|
|
195
|
-
package_json_path =
|
|
196
|
-
return unless
|
|
199
|
+
package_json_path = package_json_path_for("react-on-rails npm package")
|
|
200
|
+
return unless package_json_path
|
|
197
201
|
|
|
198
202
|
package_json = JSON.parse(File.read(package_json_path))
|
|
199
203
|
package_name, npm_version = react_on_rails_npm_package_details(package_json)
|
|
@@ -213,8 +217,8 @@ module ReactOnRails
|
|
|
213
217
|
end
|
|
214
218
|
|
|
215
219
|
def check_package_version_sync
|
|
216
|
-
package_json_path =
|
|
217
|
-
return unless
|
|
220
|
+
package_json_path = package_json_path_for("React on Rails package version sync")
|
|
221
|
+
return unless package_json_path
|
|
218
222
|
|
|
219
223
|
begin
|
|
220
224
|
package_json = JSON.parse(File.read(package_json_path))
|
|
@@ -282,9 +286,10 @@ module ReactOnRails
|
|
|
282
286
|
|
|
283
287
|
# React dependencies validation
|
|
284
288
|
def check_react_dependencies
|
|
285
|
-
|
|
289
|
+
package_json_path = package_json_path_for("React dependencies")
|
|
290
|
+
return unless package_json_path
|
|
286
291
|
|
|
287
|
-
package_json = parse_package_json
|
|
292
|
+
package_json = parse_package_json(package_json_path)
|
|
288
293
|
return unless package_json
|
|
289
294
|
|
|
290
295
|
# Check core React dependencies
|
|
@@ -444,17 +449,33 @@ module ReactOnRails
|
|
|
444
449
|
status.success?
|
|
445
450
|
end
|
|
446
451
|
|
|
447
|
-
def
|
|
448
|
-
# Check for lock files to
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
"
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
452
|
+
def detect_package_manager_from_lockfile
|
|
453
|
+
# Check for lock files next to the configured package.json to support
|
|
454
|
+
# legacy apps that keep their JS package tree under client/.
|
|
455
|
+
package_root = resolved_package_root
|
|
456
|
+
package_json_path = package_json_path_for(
|
|
457
|
+
"package manager",
|
|
458
|
+
package_root
|
|
459
|
+
)
|
|
460
|
+
# If package.json cannot be read, the configured package root is broken
|
|
461
|
+
# enough that detecting a stray lockfile would be misleading. Block the
|
|
462
|
+
# scan so check_package_manager does not suggest installing lockfiles.
|
|
463
|
+
# Covers both cases handled by package_json_path_for: a missing package
|
|
464
|
+
# root directory and an existing directory without a package.json.
|
|
465
|
+
return PackageManagerDetection.new(manager: nil, lockfile_scan_blocked: true) unless package_json_path
|
|
466
|
+
|
|
467
|
+
manager = if File.exist?(File.join(package_root, "yarn.lock"))
|
|
468
|
+
"yarn"
|
|
469
|
+
elsif File.exist?(File.join(package_root, "pnpm-lock.yaml"))
|
|
470
|
+
"pnpm"
|
|
471
|
+
elsif File.exist?(File.join(package_root, "bun.lock")) ||
|
|
472
|
+
File.exist?(File.join(package_root, "bun.lockb"))
|
|
473
|
+
"bun"
|
|
474
|
+
elsif File.exist?(File.join(package_root, "package-lock.json"))
|
|
475
|
+
"npm"
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
PackageManagerDetection.new(manager: manager, lockfile_scan_blocked: false)
|
|
458
479
|
end
|
|
459
480
|
|
|
460
481
|
def get_package_manager_version(manager)
|
|
@@ -717,8 +738,8 @@ module ReactOnRails
|
|
|
717
738
|
end
|
|
718
739
|
# rubocop:enable Metrics/CyclomaticComplexity
|
|
719
740
|
|
|
720
|
-
def parse_package_json
|
|
721
|
-
JSON.parse(File.read(
|
|
741
|
+
def parse_package_json(package_json_path)
|
|
742
|
+
JSON.parse(File.read(package_json_path))
|
|
722
743
|
rescue Errno::ENOENT, JSON::ParserError
|
|
723
744
|
add_warning("⚠️ Could not parse package.json to check React dependencies")
|
|
724
745
|
nil
|
|
@@ -814,8 +835,8 @@ module ReactOnRails
|
|
|
814
835
|
end
|
|
815
836
|
|
|
816
837
|
def report_webpack_version
|
|
817
|
-
package_json_path =
|
|
818
|
-
return unless
|
|
838
|
+
package_json_path = package_json_path_for("Webpack version")
|
|
839
|
+
return unless package_json_path
|
|
819
840
|
|
|
820
841
|
begin
|
|
821
842
|
package_json = JSON.parse(File.read(package_json_path))
|
data/lib/react_on_rails/utils.rb
CHANGED
|
@@ -161,6 +161,11 @@ module ReactOnRails
|
|
|
161
161
|
(/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
|
|
162
162
|
end
|
|
163
163
|
|
|
164
|
+
def self.command_available?(command)
|
|
165
|
+
which_command = running_on_windows? ? "where" : "which"
|
|
166
|
+
!!system(which_command, command, out: File::NULL, err: File::NULL)
|
|
167
|
+
end
|
|
168
|
+
|
|
164
169
|
def self.rails_version_less_than(version)
|
|
165
170
|
@rails_version_less_than ||= {}
|
|
166
171
|
|
data/lib/react_on_rails.rb
CHANGED
|
@@ -12,6 +12,9 @@ require "react_on_rails/version_checker"
|
|
|
12
12
|
require "react_on_rails/configuration"
|
|
13
13
|
require "react_on_rails/server_rendering_pool"
|
|
14
14
|
require "react_on_rails/server_rendering_js_code"
|
|
15
|
+
require "react_on_rails/render_request"
|
|
16
|
+
require "react_on_rails/js_code_builder"
|
|
17
|
+
require "react_on_rails/rendering_strategy"
|
|
15
18
|
require "react_on_rails/engine"
|
|
16
19
|
require "react_on_rails/react_component/render_options"
|
|
17
20
|
require "react_on_rails/version_syntax_converter"
|
data/rakelib/run_rspec.rake
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "coveralls/rake/task" if ENV["USE_COVERALLS"] == "TRUE"
|
|
4
|
-
|
|
5
3
|
require "pathname"
|
|
6
4
|
require "yaml"
|
|
7
5
|
|
|
@@ -141,8 +139,6 @@ namespace :run_rspec do
|
|
|
141
139
|
pinned_version_examples.each { |example_type| Rake::Task[example_type.rspec_task_name].invoke }
|
|
142
140
|
end
|
|
143
141
|
|
|
144
|
-
Coveralls::RakeTask.new if ENV["USE_COVERALLS"] == "TRUE"
|
|
145
|
-
|
|
146
142
|
desc "run all tests no examples"
|
|
147
143
|
task all_but_examples: %i[gem dummy_no_turbolinks dummy js_tests] do
|
|
148
144
|
puts "Completed all RSpec tests"
|
|
@@ -209,7 +205,6 @@ def run_tests_in(dir, options = {})
|
|
|
209
205
|
env_tokens = []
|
|
210
206
|
env_tokens << options.fetch(:env_vars, "").strip unless options.fetch(:env_vars, "").strip.empty?
|
|
211
207
|
env_tokens << "TEST_ENV_COMMAND_NAME=\"#{command_name}\""
|
|
212
|
-
env_tokens << "COVERAGE=true" if ENV["USE_COVERALLS"]
|
|
213
208
|
|
|
214
209
|
env_vars = env_tokens.join(" ")
|
|
215
210
|
command = "#{env_vars} bundle exec rspec #{rspec_args}"
|
|
@@ -64,6 +64,38 @@ namespace :shakapacker_examples do # rubocop:disable Metrics/BlockLength
|
|
|
64
64
|
fallback_match&.[](1)
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
+
def local_react_on_rails_package_ref(dir)
|
|
68
|
+
package_dir = File.expand_path("../packages/react-on-rails", gem_root)
|
|
69
|
+
relative_package_dir = Pathname(package_dir).relative_path_from(Pathname(dir)).to_s
|
|
70
|
+
"file:#{relative_package_dir}"
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Makes generated examples use the local monorepo package for react-on-rails.
|
|
74
|
+
# This ensures CI validates the package code in this branch rather than a
|
|
75
|
+
# potentially stale published npm version.
|
|
76
|
+
def pin_react_on_rails_to_local_package(dir)
|
|
77
|
+
package_json_path = File.join(dir, "package.json")
|
|
78
|
+
return unless File.exist?(package_json_path)
|
|
79
|
+
|
|
80
|
+
begin
|
|
81
|
+
package_json = JSON.parse(File.read(package_json_path))
|
|
82
|
+
rescue JSON::ParserError => e
|
|
83
|
+
puts " ERROR: Failed to parse #{package_json_path}: #{e.message}"
|
|
84
|
+
raise
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
deps = package_json["dependencies"]
|
|
88
|
+
return unless deps&.key?("react-on-rails")
|
|
89
|
+
|
|
90
|
+
local_package_ref = local_react_on_rails_package_ref(dir)
|
|
91
|
+
|
|
92
|
+
return if deps["react-on-rails"] == local_package_ref
|
|
93
|
+
|
|
94
|
+
puts " Pinning react-on-rails npm dependency from #{deps['react-on-rails']} to #{local_package_ref}"
|
|
95
|
+
deps["react-on-rails"] = local_package_ref
|
|
96
|
+
File.write(package_json_path, "#{JSON.pretty_generate(package_json)}\n")
|
|
97
|
+
end
|
|
98
|
+
|
|
67
99
|
# Updates React-related dependencies to a specific version
|
|
68
100
|
def update_react_dependencies(deps, react_version)
|
|
69
101
|
return unless deps
|
|
@@ -115,6 +147,37 @@ namespace :shakapacker_examples do # rubocop:disable Metrics/BlockLength
|
|
|
115
147
|
puts " React: #{react_version}"
|
|
116
148
|
end
|
|
117
149
|
|
|
150
|
+
def install_local_react_on_rails_package(dir, legacy_peer_deps: false)
|
|
151
|
+
legacy_peer_deps_flag = legacy_peer_deps ? "--legacy-peer-deps " : ""
|
|
152
|
+
sh_in_dir(dir,
|
|
153
|
+
"npm install react-on-rails@#{local_react_on_rails_package_ref(dir)} " \
|
|
154
|
+
"#{legacy_peer_deps_flag}--install-links")
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def install_example_node_dependencies(example_type)
|
|
158
|
+
pin_shakapacker_npm_version(example_type.dir)
|
|
159
|
+
pin_react_on_rails_to_local_package(example_type.dir)
|
|
160
|
+
|
|
161
|
+
if example_type.pinned_react_version?
|
|
162
|
+
# Use --legacy-peer-deps to avoid peer dependency conflicts when
|
|
163
|
+
# react-on-rails expects newer React versions.
|
|
164
|
+
sh_in_dir(example_type.dir, "npm install --legacy-peer-deps --install-links")
|
|
165
|
+
# Explicit re-install is required because npm install --install-links does not
|
|
166
|
+
# reliably copy a file: dependency that was just pinned in the same session.
|
|
167
|
+
install_local_react_on_rails_package(example_type.dir, legacy_peer_deps: true)
|
|
168
|
+
# Regenerate Shakapacker binstubs after downgrading from 9.x to 8.2.x
|
|
169
|
+
# The binstub format may differ between major versions.
|
|
170
|
+
unbundled_sh_in_dir(example_type.dir, "bundle exec rake shakapacker:binstubs")
|
|
171
|
+
else
|
|
172
|
+
# Use --install-links to copy file: dependencies instead of symlinking,
|
|
173
|
+
# preventing duplicate React instances from webpack resolving through symlinks.
|
|
174
|
+
sh_in_dir(example_type.dir, "npm install --install-links")
|
|
175
|
+
# Explicit re-install is required because npm install --install-links does not
|
|
176
|
+
# reliably copy a file: dependency that was just pinned in the same session.
|
|
177
|
+
install_local_react_on_rails_package(example_type.dir)
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
118
181
|
# Define tasks for each example type
|
|
119
182
|
ExampleType.all[:shakapacker_examples].each do |example_type| # rubocop:disable Metrics/BlockLength
|
|
120
183
|
relative_gem_root = Pathname(gem_root).relative_path_from(Pathname(example_type.dir))
|
|
@@ -150,7 +213,7 @@ namespace :shakapacker_examples do # rubocop:disable Metrics/BlockLength
|
|
|
150
213
|
# Use unbundled_sh_in_dir to ensure the generator uses the example app's
|
|
151
214
|
# gem versions, not the parent workspace's cached bundle context.
|
|
152
215
|
unbundled_sh_in_dir(example_type.dir, generator_commands)
|
|
153
|
-
# Re-run bundle install since dev_tests generator adds rspec-rails and
|
|
216
|
+
# Re-run bundle install since dev_tests generator adds rspec-rails and simplecov to Gemfile
|
|
154
217
|
bundle_install_in(example_type.dir)
|
|
155
218
|
|
|
156
219
|
# Apply specific React version for compatibility testing examples
|
|
@@ -158,29 +221,9 @@ namespace :shakapacker_examples do # rubocop:disable Metrics/BlockLength
|
|
|
158
221
|
apply_react_version(example_type.dir, example_type.react_version_string)
|
|
159
222
|
# Re-run bundle install to ensure dependencies are resolved correctly
|
|
160
223
|
bundle_install_in(example_type.dir)
|
|
161
|
-
# Pin the npm shakapacker version to exactly match the installed gem version.
|
|
162
|
-
# shakapacker:install may add "^X.Y.Z" to package.json, which allows npm to
|
|
163
|
-
# resolve a newer minor version (e.g., 9.6.0 when gem is 9.5.0), causing
|
|
164
|
-
# Shakapacker's gem/npm version consistency check to fail.
|
|
165
|
-
pin_shakapacker_npm_version(example_type.dir)
|
|
166
|
-
# Use --legacy-peer-deps to avoid peer dependency conflicts when
|
|
167
|
-
# react-on-rails expects newer React versions
|
|
168
|
-
# Use --install-links to copy file: dependencies instead of symlinking,
|
|
169
|
-
# preventing duplicate React instances from webpack resolving through symlinks
|
|
170
|
-
sh_in_dir(example_type.dir, "npm install --legacy-peer-deps --install-links")
|
|
171
|
-
# Regenerate Shakapacker binstubs after downgrading from 9.x to 8.2.x
|
|
172
|
-
# The binstub format may differ between major versions
|
|
173
|
-
unbundled_sh_in_dir(example_type.dir, "bundle exec rake shakapacker:binstubs")
|
|
174
|
-
else
|
|
175
|
-
# Pin the npm shakapacker version to exactly match the installed gem version.
|
|
176
|
-
# shakapacker:install may add "^X.Y.Z" to package.json, which allows npm to
|
|
177
|
-
# resolve a newer minor version (e.g., 9.6.0 when gem is 9.5.0), causing
|
|
178
|
-
# Shakapacker's gem/npm version consistency check to fail.
|
|
179
|
-
pin_shakapacker_npm_version(example_type.dir)
|
|
180
|
-
# Use --install-links to copy file: dependencies instead of symlinking,
|
|
181
|
-
# preventing duplicate React instances from webpack resolving through symlinks
|
|
182
|
-
sh_in_dir(example_type.dir, "npm install --install-links")
|
|
183
224
|
end
|
|
225
|
+
# Pin npm package versions and install node dependencies for generated example.
|
|
226
|
+
install_example_node_dependencies(example_type)
|
|
184
227
|
# Generate the component packs after running the generator to ensure all
|
|
185
228
|
# auto-bundled components have corresponding pack files created.
|
|
186
229
|
# Use unbundled_sh_in_dir to ensure we're using the generated app's Gemfile
|
data/react_on_rails.gemspec
CHANGED
|
@@ -13,8 +13,16 @@ Gem::Specification.new do |s|
|
|
|
13
13
|
|
|
14
14
|
s.summary = "Rails with react server rendering with webpack. "
|
|
15
15
|
s.description = "See README.md"
|
|
16
|
-
s.homepage = "https://
|
|
16
|
+
s.homepage = "https://reactonrails.com/docs/"
|
|
17
17
|
s.license = "MIT"
|
|
18
|
+
s.metadata = {
|
|
19
|
+
"bug_tracker_uri" => "https://github.com/shakacode/react_on_rails/issues",
|
|
20
|
+
"changelog_uri" => "https://github.com/shakacode/react_on_rails/blob/main/CHANGELOG.md",
|
|
21
|
+
"documentation_uri" => "https://reactonrails.com/docs/",
|
|
22
|
+
"homepage_uri" => "https://reactonrails.com/docs/",
|
|
23
|
+
"rubygems_mfa_required" => "true",
|
|
24
|
+
"source_code_uri" => "https://github.com/shakacode/react_on_rails/tree/main/react_on_rails"
|
|
25
|
+
}
|
|
18
26
|
|
|
19
27
|
s.files = Dir.chdir(__dir__) do
|
|
20
28
|
`git ls-files -z`.split("\x0").reject do |f|
|
|
@@ -37,12 +45,14 @@ Gem::Specification.new do |s|
|
|
|
37
45
|
s.add_dependency "shakapacker", ">= 6.0"
|
|
38
46
|
|
|
39
47
|
s.add_development_dependency "gem-release"
|
|
40
|
-
s.post_install_message =
|
|
41
|
-
--------------------------------------------------------------------------------
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
48
|
+
s.post_install_message = <<~MESSAGE
|
|
49
|
+
--------------------------------------------------------------------------------
|
|
50
|
+
Need React Server Components, streaming SSR, caching, or faster Node-based SSR?
|
|
51
|
+
React on Rails Pro is free to try in development, CI/CD, and staging.
|
|
52
|
+
Compare OSS vs Pro: https://reactonrails.com/docs/getting-started/oss-vs-pro/
|
|
53
|
+
Pro quick start: https://reactonrails.com/docs/getting-started/pro-quick-start/
|
|
54
|
+
Contact ShakaCode: https://www.shakacode.com/contact/
|
|
55
|
+
--------------------------------------------------------------------------------
|
|
56
|
+
MESSAGE
|
|
47
57
|
end
|
|
48
58
|
# rubocop:enable Metrics/BlockLength
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module ReactOnRails
|
|
2
|
+
class JsCodeBuilder
|
|
3
|
+
def build: (RenderRequest render_request) -> String
|
|
4
|
+
def build_sections: (RenderRequest render_request) -> Array[String?]
|
|
5
|
+
def rails_context_section: (RenderRequest render_request) -> String
|
|
6
|
+
def store_initialization_section: (RenderRequest render_request) -> String?
|
|
7
|
+
def props_section: (RenderRequest render_request) -> String
|
|
8
|
+
def render_call_section: (RenderRequest render_request) -> String
|
|
9
|
+
def wrap_in_iife: (String body, RenderRequest render_request) -> String
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module ReactOnRails
|
|
2
|
+
class RenderRequest
|
|
3
|
+
attr_reader component_name: String
|
|
4
|
+
attr_reader props: Hash[untyped, untyped] | String
|
|
5
|
+
attr_reader rails_context: Hash[untyped, untyped]
|
|
6
|
+
attr_reader store_initializations: String?
|
|
7
|
+
attr_reader render_options: untyped
|
|
8
|
+
|
|
9
|
+
def initialize: (
|
|
10
|
+
component_name: String,
|
|
11
|
+
props: Hash[untyped, untyped] | String,
|
|
12
|
+
rails_context: Hash[untyped, untyped],
|
|
13
|
+
store_initializations: String?,
|
|
14
|
+
render_options: untyped
|
|
15
|
+
) -> void
|
|
16
|
+
|
|
17
|
+
def to_js: () -> String
|
|
18
|
+
def props_string: () -> String
|
|
19
|
+
def rails_context_json: () -> String
|
|
20
|
+
def dom_id: () -> String
|
|
21
|
+
def streaming?: () -> bool
|
|
22
|
+
def rsc_payload_streaming?: () -> bool
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def validate_server_bundle_configured!: () -> void
|
|
27
|
+
end
|
|
28
|
+
end
|
data/sig/react_on_rails.rbs
CHANGED
|
@@ -9,6 +9,12 @@ module ReactOnRails
|
|
|
9
9
|
def self.configure: () { (Configuration) -> void } -> void
|
|
10
10
|
def self.configuration: () -> Configuration
|
|
11
11
|
|
|
12
|
+
def self.rendering_strategy: () -> RenderingStrategy
|
|
13
|
+
def self.rendering_strategy=: (RenderingStrategy strategy) -> RenderingStrategy
|
|
14
|
+
|
|
15
|
+
def self.js_code_builder: () -> JsCodeBuilder
|
|
16
|
+
def self.js_code_builder=: (JsCodeBuilder builder) -> JsCodeBuilder
|
|
17
|
+
|
|
12
18
|
# Error classes are defined in separate RBS files:
|
|
13
19
|
# - sig/react_on_rails/prerender_error.rbs
|
|
14
20
|
# - sig/react_on_rails/json_parse_error.rbs
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: react_on_rails
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 16.
|
|
4
|
+
version: 16.7.0.rc.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Justin Gordon
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-05-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: addressable
|
|
@@ -130,6 +130,9 @@ files:
|
|
|
130
130
|
- lib/generators/react_on_rails/dev_tests_generator.rb
|
|
131
131
|
- lib/generators/react_on_rails/generator_helper.rb
|
|
132
132
|
- lib/generators/react_on_rails/generator_messages.rb
|
|
133
|
+
- lib/generators/react_on_rails/generator_messages/ci_section.rb
|
|
134
|
+
- lib/generators/react_on_rails/generator_messages/package_manager_detection.rb
|
|
135
|
+
- lib/generators/react_on_rails/generator_messages/shakapacker_status_section.rb
|
|
133
136
|
- lib/generators/react_on_rails/install_generator.rb
|
|
134
137
|
- lib/generators/react_on_rails/js_dependency_manager.rb
|
|
135
138
|
- lib/generators/react_on_rails/pro/USAGE
|
|
@@ -143,6 +146,7 @@ files:
|
|
|
143
146
|
- lib/generators/react_on_rails/templates/.eslintrc
|
|
144
147
|
- lib/generators/react_on_rails/templates/base/base/.dev-services.yml.example
|
|
145
148
|
- lib/generators/react_on_rails/templates/base/base/.env.example
|
|
149
|
+
- lib/generators/react_on_rails/templates/base/base/.github/workflows/ci.yml.tt
|
|
146
150
|
- lib/generators/react_on_rails/templates/base/base/Procfile.dev
|
|
147
151
|
- lib/generators/react_on_rails/templates/base/base/Procfile.dev-prod-assets
|
|
148
152
|
- lib/generators/react_on_rails/templates/base/base/Procfile.dev-static-assets
|
|
@@ -185,8 +189,8 @@ files:
|
|
|
185
189
|
- lib/generators/react_on_rails/templates/dev_tests/spec/spec_helper.rb
|
|
186
190
|
- lib/generators/react_on_rails/templates/dev_tests/spec/system/hello_server_spec.rb
|
|
187
191
|
- lib/generators/react_on_rails/templates/dev_tests/spec/system/hello_world_spec.rb
|
|
188
|
-
- lib/generators/react_on_rails/templates/pro/base/client/node-renderer.js
|
|
189
192
|
- lib/generators/react_on_rails/templates/pro/base/config/initializers/react_on_rails_pro.rb.tt
|
|
193
|
+
- lib/generators/react_on_rails/templates/pro/base/renderer/node-renderer.js
|
|
190
194
|
- lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/actions/helloWorldActionCreators.js
|
|
191
195
|
- lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/actions/helloWorldActionCreators.ts
|
|
192
196
|
- lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/components/HelloWorld.jsx
|
|
@@ -230,8 +234,10 @@ files:
|
|
|
230
234
|
- lib/react_on_rails/error.rb
|
|
231
235
|
- lib/react_on_rails/git_utils.rb
|
|
232
236
|
- lib/react_on_rails/helper.rb
|
|
237
|
+
- lib/react_on_rails/js_code_builder.rb
|
|
233
238
|
- lib/react_on_rails/json_output.rb
|
|
234
239
|
- lib/react_on_rails/json_parse_error.rb
|
|
240
|
+
- lib/react_on_rails/length_prefixed_parser.rb
|
|
235
241
|
- lib/react_on_rails/locales/base.rb
|
|
236
242
|
- lib/react_on_rails/locales/to_js.rb
|
|
237
243
|
- lib/react_on_rails/locales/to_json.rb
|
|
@@ -239,7 +245,11 @@ files:
|
|
|
239
245
|
- lib/react_on_rails/packs_generator.rb
|
|
240
246
|
- lib/react_on_rails/prerender_error.rb
|
|
241
247
|
- lib/react_on_rails/pro_helper.rb
|
|
248
|
+
- lib/react_on_rails/pro_migration.rb
|
|
242
249
|
- lib/react_on_rails/react_component/render_options.rb
|
|
250
|
+
- lib/react_on_rails/render_request.rb
|
|
251
|
+
- lib/react_on_rails/rendering_strategy.rb
|
|
252
|
+
- lib/react_on_rails/rendering_strategy/exec_js_strategy.rb
|
|
243
253
|
- lib/react_on_rails/server_rendering_js_code.rb
|
|
244
254
|
- lib/react_on_rails/server_rendering_pool.rb
|
|
245
255
|
- lib/react_on_rails/server_rendering_pool/ruby_embedded_java_script.rb
|
|
@@ -287,25 +297,36 @@ files:
|
|
|
287
297
|
- sig/react_on_rails/generators/js_dependency_manager.rbs
|
|
288
298
|
- sig/react_on_rails/git_utils.rbs
|
|
289
299
|
- sig/react_on_rails/helper.rbs
|
|
300
|
+
- sig/react_on_rails/js_code_builder.rbs
|
|
290
301
|
- sig/react_on_rails/json_parse_error.rbs
|
|
291
302
|
- sig/react_on_rails/locales.rbs
|
|
292
303
|
- sig/react_on_rails/packer_utils.rbs
|
|
293
304
|
- sig/react_on_rails/prerender_error.rbs
|
|
305
|
+
- sig/react_on_rails/render_request.rbs
|
|
306
|
+
- sig/react_on_rails/rendering_strategy.rbs
|
|
307
|
+
- sig/react_on_rails/rendering_strategy/exec_js_strategy.rbs
|
|
294
308
|
- sig/react_on_rails/server_rendering_pool.rbs
|
|
295
309
|
- sig/react_on_rails/smart_error.rbs
|
|
296
310
|
- sig/react_on_rails/test_helper.rbs
|
|
297
311
|
- sig/react_on_rails/utils.rbs
|
|
298
312
|
- sig/react_on_rails/version_checker.rbs
|
|
299
|
-
homepage: https://
|
|
313
|
+
homepage: https://reactonrails.com/docs/
|
|
300
314
|
licenses:
|
|
301
315
|
- MIT
|
|
302
|
-
metadata:
|
|
303
|
-
|
|
304
|
-
|
|
316
|
+
metadata:
|
|
317
|
+
bug_tracker_uri: https://github.com/shakacode/react_on_rails/issues
|
|
318
|
+
changelog_uri: https://github.com/shakacode/react_on_rails/blob/main/CHANGELOG.md
|
|
319
|
+
documentation_uri: https://reactonrails.com/docs/
|
|
320
|
+
homepage_uri: https://reactonrails.com/docs/
|
|
321
|
+
rubygems_mfa_required: 'true'
|
|
322
|
+
source_code_uri: https://github.com/shakacode/react_on_rails/tree/main/react_on_rails
|
|
323
|
+
post_install_message: |
|
|
305
324
|
--------------------------------------------------------------------------------
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
325
|
+
Need React Server Components, streaming SSR, caching, or faster Node-based SSR?
|
|
326
|
+
React on Rails Pro is free to try in development, CI/CD, and staging.
|
|
327
|
+
Compare OSS vs Pro: https://reactonrails.com/docs/getting-started/oss-vs-pro/
|
|
328
|
+
Pro quick start: https://reactonrails.com/docs/getting-started/pro-quick-start/
|
|
329
|
+
Contact ShakaCode: https://www.shakacode.com/contact/
|
|
309
330
|
--------------------------------------------------------------------------------
|
|
310
331
|
rdoc_options: []
|
|
311
332
|
require_paths:
|