Skip to content

Commit 27644c0

Browse files
docs: simplify server_bundle_output_path configuration documentation
- Focus on key message that default will change to "ssr-generated" - Note that warning will be shown if left as nil - Remove unnecessary implementation details about fallback order - Simplify enforcement requirements Co-authored-by: Justin Gordon <[email protected]>
1 parent 524249a commit 27644c0

File tree

13 files changed

+69
-215
lines changed

13 files changed

+69
-215
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ Changes since the last non-beta release.
5151

5252
- **Non-Packer Environment Compatibility**: Fixed potential NoMethodError when using bundle path resolution in environments without Shakapacker
5353
- **Server Bundle Detection**: Improved server bundle detection to work correctly with both `server_bundle_js_file` and `rsc_bundle_js_file` configurations
54+
- **Shakapacker version requirements**: Fixed inconsistent version requirements between basic pack generation (6.5.1+) and advanced auto-bundling features (7.0.0+). Added backward compatibility for users on Shakapacker 6.5.1-6.9.x while providing clear upgrade guidance for advanced features. Added new constants `MINIMUM_SHAKAPACKER_VERSION_FOR_AUTO_BUNDLING` and improved version checking performance with caching. [PR 1798](https://github.com/shakacode/react_on_rails/pull/1798)
55+
56+
#### Code Cleanup
57+
58+
- **PackerUtils abstraction removal**: Removed unnecessary `PackerUtils.packer` abstraction method and replaced all calls with direct `::Shakapacker` usage. This simplifies the codebase by eliminating an abstraction layer that was originally created to support multiple webpack tools but is no longer needed since we only support Shakapacker. All tests updated accordingly. [PR 1798](https://github.com/shakacode/react_on_rails/pull/1798) by [claude-code](https://claude.ai/code)
5459

5560
### [16.0.1-rc.2] - 2025-09-20
5661

lib/generators/react_on_rails/base_generator.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def add_hello_world_route
2424
end
2525

2626
def create_react_directories
27-
# Create auto-registration directory structure for non-Redux components only
27+
# Create auto-bundling directory structure for non-Redux components only
2828
# Redux components handle their own directory structure
2929
return if options.redux?
3030

lib/generators/react_on_rails/react_with_redux_generator.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class ReactWithReduxGenerator < Rails::Generators::Base
1919
aliases: "-T"
2020

2121
def create_redux_directories
22-
# Create auto-registration directory structure for Redux
22+
# Create auto-bundling directory structure for Redux
2323
empty_directory("app/javascript/src/HelloWorldApp/ror_components")
2424

2525
# Create Redux support directories within the component directory
@@ -31,7 +31,7 @@ def copy_base_files
3131
base_js_path = "redux/base"
3232
ext = component_extension(options)
3333

34-
# Copy Redux-connected component to auto-registration structure
34+
# Copy Redux-connected component to auto-bundling structure
3535
copy_file("#{base_js_path}/app/javascript/bundles/HelloWorld/startup/HelloWorldApp.client.#{ext}",
3636
"app/javascript/src/HelloWorldApp/ror_components/HelloWorldApp.client.#{ext}")
3737
copy_file("#{base_js_path}/app/javascript/bundles/HelloWorld/startup/HelloWorldApp.server.#{ext}",

lib/react_on_rails/configuration.rb

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ def validate_generated_component_packs_loading_strategy
186186
1. Use :sync or :defer loading strategy instead of :async
187187
2. Upgrade to Shakapacker v8.2.0 or above to enable async script loading
188188
MSG
189-
if PackerUtils.shakapacker_version_requirement_met?("8.2.0")
189+
if ReactOnRails::PackerUtils.shakapacker_version_requirement_met?("8.2.0")
190190
self.generated_component_packs_loading_strategy ||= :async
191191
elsif generated_component_packs_loading_strategy.nil?
192192
Rails.logger.warn("**WARNING** #{msg}")
@@ -228,11 +228,8 @@ def check_autobundling_requirements
228228
raise_missing_components_subdirectory if auto_load_bundle && !components_subdirectory.present?
229229
return unless components_subdirectory.present?
230230

231-
ReactOnRails::PackerUtils.raise_shakapacker_not_installed unless ReactOnRails::PackerUtils.using_packer?
232231
ReactOnRails::PackerUtils.raise_shakapacker_version_incompatible_for_autobundling unless
233-
ReactOnRails::PackerUtils.shakapacker_version_requirement_met?(
234-
ReactOnRails::PacksGenerator::MINIMUM_SHAKAPACKER_VERSION
235-
)
232+
ReactOnRails::PackerUtils.supports_autobundling?
236233
ReactOnRails::PackerUtils.raise_nested_entries_disabled unless ReactOnRails::PackerUtils.nested_entries?
237234
end
238235

@@ -267,8 +264,6 @@ def adjust_precompile_task
267264
end
268265

269266
def error_if_using_packer_and_generated_assets_dir_not_match_public_output_path
270-
return unless ReactOnRails::PackerUtils.using_packer?
271-
272267
return if generated_assets_dir.blank?
273268

274269
packer_public_output_path = ReactOnRails::PackerUtils.packer_public_output_path
@@ -302,7 +297,7 @@ def check_server_render_method_is_only_execjs
302297
end
303298

304299
def ensure_generated_assets_dir_present
305-
return if generated_assets_dir.present? || ReactOnRails::PackerUtils.using_packer?
300+
return if generated_assets_dir.present?
306301

307302
self.generated_assets_dir = DEFAULT_GENERATED_ASSETS_DIR
308303
Rails.logger.warn "ReactOnRails: Set generated_assets_dir to default: #{DEFAULT_GENERATED_ASSETS_DIR}"
@@ -311,20 +306,13 @@ def ensure_generated_assets_dir_present
311306
def configure_generated_assets_dirs_deprecation
312307
return if generated_assets_dirs.blank?
313308

314-
if ReactOnRails::PackerUtils.using_packer?
315-
packer_public_output_path = ReactOnRails::PackerUtils.packer_public_output_path
316-
# rubocop:disable Layout/LineLength
317-
packer_name = "Shakapacker"
318-
319-
Rails.logger.warn "Error configuring config/initializers/react_on_rails. Define neither the generated_assets_dirs nor " \
320-
"the generated_assets_dir when using #{packer_name}. This is defined by " \
321-
"public_output_path specified in shakapacker.yml = #{packer_public_output_path}."
322-
# rubocop:enable Layout/LineLength
323-
return
324-
end
325-
326-
Rails.logger.warn "[DEPRECATION] ReactOnRails: Use config.generated_assets_dir rather than " \
327-
"generated_assets_dirs"
309+
# With Shakapacker always available:
310+
packer_public_output_path = ReactOnRails::PackerUtils.packer_public_output_path
311+
# rubocop:disable Layout/LineLength
312+
Rails.logger.warn "Error configuring config/initializers/react_on_rails. Define neither the generated_assets_dirs nor " \
313+
"the generated_assets_dir when using Shakapacker. This is defined by " \
314+
"public_output_path specified in shakapacker.yml = #{packer_public_output_path}."
315+
# rubocop:enable Layout/LineLength
328316
if generated_assets_dir.blank?
329317
self.generated_assets_dir = generated_assets_dirs
330318
else

lib/react_on_rails/packer_utils.rb

Lines changed: 17 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,16 @@
22

33
module ReactOnRails
44
module PackerUtils
5-
def self.using_packer?
6-
return @using_packer if defined?(@using_packer)
7-
8-
# Shakapacker is required by gemspec, but tests may mock gem_available? to return false
9-
@using_packer = ReactOnRails::Utils.gem_available?("shakapacker")
10-
end
11-
12-
def self.packer
13-
return nil unless using_packer?
14-
15-
require "shakapacker"
16-
::Shakapacker
17-
end
18-
195
def self.dev_server_running?
20-
return false unless using_packer?
21-
22-
packer.dev_server.running?
6+
Shakapacker.dev_server.running?
237
end
248

259
def self.dev_server_url
26-
"#{packer.dev_server.protocol}://#{packer.dev_server.host_with_port}"
10+
"#{Shakapacker.dev_server.protocol}://#{Shakapacker.dev_server.host_with_port}"
2711
end
2812

2913
def self.shakapacker_version
3014
return @shakapacker_version if defined?(@shakapacker_version)
31-
return nil unless ReactOnRails::Utils.gem_available?("shakapacker")
3215

3316
@shakapacker_version = Gem.loaded_specs["shakapacker"].version.to_s
3417
end
@@ -46,11 +29,15 @@ def self.shakapacker_version_requirement_met?(required_version)
4629
Gem::Version.new(shakapacker_version) >= Gem::Version.new(required_version)
4730
end
4831

32+
def self.supports_autobundling?
33+
shakapacker_version_requirement_met?(ReactOnRails::PacksGenerator::MINIMUM_SHAKAPACKER_VERSION)
34+
end
35+
4936
# This returns either a URL for the webpack-dev-server, non-server bundle or
5037
# the hashed server bundle if using the same bundle for the client.
5138
# Otherwise returns a file path.
5239
def self.bundle_js_uri_from_packer(bundle_name)
53-
hashed_bundle_name = packer.manifest.lookup!(bundle_name)
40+
hashed_bundle_name = Shakapacker.manifest.lookup!(bundle_name)
5441

5542
# Support for hashing the server-bundle and having that built
5643
# the webpack-dev-server is provided by the config value
@@ -59,7 +46,7 @@ def self.bundle_js_uri_from_packer(bundle_name)
5946
is_bundle_running_on_server = (bundle_name == ReactOnRails.configuration.server_bundle_js_file) ||
6047
(bundle_name == ReactOnRails.configuration.rsc_bundle_js_file)
6148

62-
if packer.dev_server.running? && (!is_bundle_running_on_server ||
49+
if Shakapacker.dev_server.running? && (!is_bundle_running_on_server ||
6350
ReactOnRails.configuration.same_bundle_for_client_and_server)
6451
"#{dev_server_url}#{hashed_bundle_name}"
6552
else
@@ -68,7 +55,7 @@ def self.bundle_js_uri_from_packer(bundle_name)
6855
end
6956

7057
def self.public_output_uri_path
71-
"#{packer.config.public_output_path.relative_path_from(packer.config.public_path)}/"
58+
"#{Shakapacker.config.public_output_path.relative_path_from(Shakapacker.config.public_path)}/"
7259
end
7360

7461
# The function doesn't ensure that the asset exists.
@@ -83,35 +70,35 @@ def self.asset_uri_from_packer(asset_name)
8370
end
8471

8572
def self.precompile?
86-
using_packer? ? ::Shakapacker.config.shakapacker_precompile? : false
73+
::Shakapacker.config.shakapacker_precompile?
8774
end
8875

8976
def self.packer_source_path
90-
packer.config.source_path
77+
Shakapacker.config.source_path
9178
end
9279

9380
def self.packer_source_entry_path
94-
packer.config.source_entry_path
81+
Shakapacker.config.source_entry_path
9582
end
9683

9784
def self.nested_entries?
98-
packer.config.nested_entries?
85+
Shakapacker.config.nested_entries?
9986
end
10087

10188
def self.packer_public_output_path
102-
packer.config.public_output_path.to_s
89+
Shakapacker.config.public_output_path.to_s
10390
end
10491

10592
def self.manifest_exists?
106-
packer.config.public_manifest_path.exist?
93+
Shakapacker.config.public_manifest_path.exist?
10794
end
10895

10996
def self.packer_source_path_explicit?
110-
packer.config.send(:data)[:source_path].present?
97+
Shakapacker.config.send(:data)[:source_path].present?
11198
end
11299

113100
def self.check_manifest_not_cached
114-
return unless using_packer? && packer.config.cache_manifest?
101+
return unless Shakapacker.config.cache_manifest?
115102

116103
msg = <<-MSG.strip_heredoc
117104
ERROR: you have enabled cache_manifest in the #{Rails.env} env when using the
@@ -153,15 +140,5 @@ def self.raise_shakapacker_version_incompatible_for_autobundling
153140

154141
raise ReactOnRails::Error, msg
155142
end
156-
157-
def self.raise_shakapacker_not_installed
158-
msg = <<~MSG
159-
**ERROR** ReactOnRails: Missing Shakapacker gem. Please upgrade to use Shakapacker \
160-
#{ReactOnRails::PacksGenerator::MINIMUM_SHAKAPACKER_VERSION} or above to use the \
161-
automated bundle generation feature.
162-
MSG
163-
164-
raise ReactOnRails::Error, msg
165-
end
166143
end
167144
end

lib/react_on_rails/system_checker.rb

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -618,14 +618,10 @@ def report_shakapacker_version_with_threshold
618618
version = shakapacker_match[1].strip
619619

620620
begin
621-
# Use proper semantic version comparison
622-
version_obj = Gem::Version.new(version)
623-
threshold_version = Gem::Version.new("8.2")
624-
625-
if version_obj >= threshold_version
626-
add_success("✅ Shakapacker #{version} (supports React on Rails auto-registration)")
621+
if ReactOnRails::PackerUtils.supports_autobundling?
622+
add_success("✅ Shakapacker #{version} (supports React on Rails auto-bundling)")
627623
else
628-
add_warning("⚠️ Shakapacker #{version} - Version 8.2+ needed for React on Rails auto-registration")
624+
add_warning("⚠️ Shakapacker #{version} - Version 8.2+ needed for React on Rails auto-bundling")
629625
end
630626
rescue ArgumentError
631627
# Fallback for invalid version strings

lib/react_on_rails/test_helper.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,7 @@ def self.ensure_assets_compiled(webpack_assets_status_checker: nil,
8686
puts
8787
@printed_once = true
8888

89-
if ReactOnRails::PackerUtils.using_packer? &&
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?
9190
msg = <<-MSG.strip_heredoc
9291
WARNING: Define config/shakapacker.yml to include sourcePath to configure
9392
the location of your JavaScript source for React on Rails.

lib/react_on_rails/test_helper/webpack_assets_status_checker.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@ def stale_generated_webpack_files
3131
end
3232

3333
def stale_generated_files(files)
34-
manifest_needed = ReactOnRails::PackerUtils.using_packer? &&
35-
!ReactOnRails::PackerUtils.manifest_exists?
34+
manifest_needed = !ReactOnRails::PackerUtils.manifest_exists?
3635

3736
return ["manifest.json"] if manifest_needed
3837

lib/react_on_rails/utils.rb

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -91,17 +91,17 @@ def self.bundle_js_file_path(bundle_name)
9191
# a. The webpack manifest plugin would have a race condition where the same manifest.json
9292
# is edited by both the webpack-dev-server
9393
# b. There is no good reason to hash the server bundle name.
94-
if ReactOnRails::PackerUtils.using_packer? && bundle_name != "manifest.json"
94+
if bundle_name == "manifest.json"
95+
# Default to the non-hashed name in the specified output directory, which, for legacy
96+
# React on Rails, this is the output directory picked up by the asset pipeline.
97+
# For Shakapacker, this is the public output path defined in the (shaka/web)packer.yml file.
98+
File.join(generated_assets_full_path, bundle_name)
99+
else
95100
begin
96101
ReactOnRails::PackerUtils.bundle_js_uri_from_packer(bundle_name)
97102
rescue Shakapacker::Manifest::MissingEntryError
98103
handle_missing_manifest_entry(bundle_name)
99104
end
100-
else
101-
# Default to the non-hashed name in the specified output directory, which, for legacy
102-
# React on Rails, this is the output directory picked up by the asset pipeline.
103-
# For Shakapacker, this is the public output path defined in the (shaka/web)packer.yml file.
104-
File.join(generated_assets_full_path, bundle_name)
105105
end
106106
end
107107

@@ -113,10 +113,8 @@ def self.bundle_js_file_path(bundle_name)
113113
# Build fallback locations conditionally based on packer availability
114114
fallback_locations = []
115115

116-
# 1. Environment-specific path (e.g., public/webpack/test) - only if using packer
117-
if ReactOnRails::PackerUtils.using_packer?
118-
fallback_locations << File.join(ReactOnRails::PackerUtils.packer_public_output_path, bundle_name)
119-
end
116+
# 1. Environment-specific path (e.g., public/webpack/test)
117+
fallback_locations << File.join(ReactOnRails::PackerUtils.packer_public_output_path, bundle_name)
120118

121119
# 2. Standard Shakapacker location (public/packs)
122120
fallback_locations << File.join("public", "packs", bundle_name)
@@ -171,11 +169,7 @@ def self.react_client_manifest_file_path
171169
return @react_client_manifest_path if @react_client_manifest_path && !Rails.env.development?
172170

173171
file_name = ReactOnRails.configuration.react_client_manifest_file
174-
@react_client_manifest_path = if ReactOnRails::PackerUtils.using_packer?
175-
ReactOnRails::PackerUtils.asset_uri_from_packer(file_name)
176-
else
177-
File.join(generated_assets_full_path, file_name)
178-
end
172+
@react_client_manifest_path = ReactOnRails::PackerUtils.asset_uri_from_packer(file_name)
179173
end
180174

181175
# React Server Manifest is generated by the server bundle.
@@ -217,26 +211,16 @@ def self.prepend_cd_node_modules_directory(cmd)
217211
end
218212

219213
def self.source_path
220-
if ReactOnRails::PackerUtils.using_packer?
221-
ReactOnRails::PackerUtils.packer_source_path
222-
else
223-
ReactOnRails.configuration.node_modules_location
224-
end
214+
ReactOnRails::PackerUtils.packer_source_path
225215
end
226216

227217
def self.using_packer_source_path_is_not_defined_and_custom_node_modules?
228-
return false unless ReactOnRails::PackerUtils.using_packer?
229-
230218
!ReactOnRails::PackerUtils.packer_source_path_explicit? &&
231219
ReactOnRails.configuration.node_modules_location.present?
232220
end
233221

234222
def self.public_bundles_full_path
235-
if ReactOnRails::PackerUtils.using_packer?
236-
ReactOnRails::PackerUtils.packer_public_output_path
237-
else
238-
File.expand_path(ReactOnRails.configuration.generated_assets_dir)
239-
end
223+
ReactOnRails::PackerUtils.packer_public_output_path
240224
end
241225

242226
# DEPRECATED: Use public_bundles_full_path for clarity about public vs private bundle paths

0 commit comments

Comments
 (0)