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
@@ -40,7 +40,9 @@ module ReactOnRails
|
|
40
40
|
if installation_prerequisites_met? || options.ignore_warnings?
|
41
41
|
invoke_generators
|
42
42
|
add_bin_scripts
|
43
|
-
|
43
|
+
# Only add the post install message if not using Redux
|
44
|
+
# Redux generator handles its own messages
|
45
|
+
add_post_install_message unless options.redux?
|
44
46
|
else
|
45
47
|
error = <<~MSG.strip
|
46
48
|
🚫 React on Rails generator prerequisites not met!
|
@@ -77,6 +79,14 @@ module ReactOnRails
|
|
77
79
|
else
|
78
80
|
invoke "react_on_rails:react_no_redux", [], { typescript: options.typescript? }
|
79
81
|
end
|
82
|
+
setup_react_dependencies
|
83
|
+
end
|
84
|
+
|
85
|
+
def setup_react_dependencies
|
86
|
+
@added_dependencies_to_package_json ||= false
|
87
|
+
@ran_direct_installs ||= false
|
88
|
+
add_js_dependencies
|
89
|
+
install_js_dependencies if @added_dependencies_to_package_json && !@ran_direct_installs
|
80
90
|
end
|
81
91
|
|
82
92
|
# NOTE: other requirements for existing files such as .gitignore or application.
|
@@ -410,6 +420,134 @@ module ReactOnRails
|
|
410
420
|
puts Rainbow("✅ Created tsconfig.json").green
|
411
421
|
end
|
412
422
|
|
423
|
+
def add_js_dependencies
|
424
|
+
add_react_on_rails_package
|
425
|
+
add_react_dependencies
|
426
|
+
add_css_dependencies
|
427
|
+
add_dev_dependencies
|
428
|
+
end
|
429
|
+
|
430
|
+
def add_react_on_rails_package
|
431
|
+
major_minor_patch_only = /\A\d+\.\d+\.\d+\z/
|
432
|
+
|
433
|
+
# Try to use package_json gem first, fall back to direct npm commands
|
434
|
+
react_on_rails_pkg = if ReactOnRails::VERSION.match?(major_minor_patch_only)
|
435
|
+
["react-on-rails@#{ReactOnRails::VERSION}"]
|
436
|
+
else
|
437
|
+
puts "Adding the latest react-on-rails NPM module. " \
|
438
|
+
"Double check this is correct in package.json"
|
439
|
+
["react-on-rails"]
|
440
|
+
end
|
441
|
+
|
442
|
+
puts "Installing React on Rails package..."
|
443
|
+
if add_npm_dependencies(react_on_rails_pkg)
|
444
|
+
@added_dependencies_to_package_json = true
|
445
|
+
return
|
446
|
+
end
|
447
|
+
|
448
|
+
puts "Using direct npm commands as fallback"
|
449
|
+
success = system("npm", "install", *react_on_rails_pkg)
|
450
|
+
@ran_direct_installs = true if success
|
451
|
+
handle_npm_failure("react-on-rails package", react_on_rails_pkg) unless success
|
452
|
+
end
|
453
|
+
|
454
|
+
def add_react_dependencies
|
455
|
+
puts "Installing React dependencies..."
|
456
|
+
react_deps = %w[
|
457
|
+
react
|
458
|
+
react-dom
|
459
|
+
@babel/preset-react
|
460
|
+
prop-types
|
461
|
+
babel-plugin-transform-react-remove-prop-types
|
462
|
+
babel-plugin-macros
|
463
|
+
]
|
464
|
+
if add_npm_dependencies(react_deps)
|
465
|
+
@added_dependencies_to_package_json = true
|
466
|
+
return
|
467
|
+
end
|
468
|
+
|
469
|
+
success = system("npm", "install", *react_deps)
|
470
|
+
@ran_direct_installs = true if success
|
471
|
+
handle_npm_failure("React dependencies", react_deps) unless success
|
472
|
+
end
|
473
|
+
|
474
|
+
def add_css_dependencies
|
475
|
+
puts "Installing CSS handling dependencies..."
|
476
|
+
css_deps = %w[
|
477
|
+
css-loader
|
478
|
+
css-minimizer-webpack-plugin
|
479
|
+
mini-css-extract-plugin
|
480
|
+
style-loader
|
481
|
+
]
|
482
|
+
if add_npm_dependencies(css_deps)
|
483
|
+
@added_dependencies_to_package_json = true
|
484
|
+
return
|
485
|
+
end
|
486
|
+
|
487
|
+
success = system("npm", "install", *css_deps)
|
488
|
+
@ran_direct_installs = true if success
|
489
|
+
handle_npm_failure("CSS dependencies", css_deps) unless success
|
490
|
+
end
|
491
|
+
|
492
|
+
def add_dev_dependencies
|
493
|
+
puts "Installing development dependencies..."
|
494
|
+
dev_deps = %w[
|
495
|
+
@pmmmwh/react-refresh-webpack-plugin
|
496
|
+
react-refresh
|
497
|
+
]
|
498
|
+
if add_npm_dependencies(dev_deps, dev: true)
|
499
|
+
@added_dependencies_to_package_json = true
|
500
|
+
return
|
501
|
+
end
|
502
|
+
|
503
|
+
success = system("npm", "install", "--save-dev", *dev_deps)
|
504
|
+
@ran_direct_installs = true if success
|
505
|
+
handle_npm_failure("development dependencies", dev_deps, dev: true) unless success
|
506
|
+
end
|
507
|
+
|
508
|
+
def install_js_dependencies
|
509
|
+
# Detect which package manager to use
|
510
|
+
success = if File.exist?(File.join(destination_root, "yarn.lock"))
|
511
|
+
system("yarn", "install")
|
512
|
+
elsif File.exist?(File.join(destination_root, "pnpm-lock.yaml"))
|
513
|
+
system("pnpm", "install")
|
514
|
+
elsif File.exist?(File.join(destination_root, "package-lock.json")) ||
|
515
|
+
File.exist?(File.join(destination_root, "package.json"))
|
516
|
+
# Use npm for package-lock.json or as default fallback
|
517
|
+
system("npm", "install")
|
518
|
+
else
|
519
|
+
true # No package manager detected, skip
|
520
|
+
end
|
521
|
+
|
522
|
+
unless success
|
523
|
+
GeneratorMessages.add_warning(<<~MSG.strip)
|
524
|
+
⚠️ JavaScript dependencies installation failed.
|
525
|
+
|
526
|
+
This could be due to network issues or missing package manager.
|
527
|
+
You can install dependencies manually later by running:
|
528
|
+
• npm install (if using npm)
|
529
|
+
• yarn install (if using yarn)
|
530
|
+
• pnpm install (if using pnpm)
|
531
|
+
MSG
|
532
|
+
end
|
533
|
+
|
534
|
+
success
|
535
|
+
end
|
536
|
+
|
537
|
+
def handle_npm_failure(dependency_type, packages, dev: false)
|
538
|
+
install_command = dev ? "npm install --save-dev" : "npm install"
|
539
|
+
GeneratorMessages.add_warning(<<~MSG.strip)
|
540
|
+
⚠️ Failed to install #{dependency_type}.
|
541
|
+
|
542
|
+
The following packages could not be installed automatically:
|
543
|
+
#{packages.map { |pkg| " • #{pkg}" }.join("\n")}
|
544
|
+
|
545
|
+
This could be due to network issues or missing package manager.
|
546
|
+
You can install them manually later by running:
|
547
|
+
#{install_command} #{packages.join(' ')}
|
548
|
+
MSG
|
549
|
+
end
|
550
|
+
|
413
551
|
# Removed: Shakapacker auto-installation logic (now explicit dependency)
|
414
552
|
|
415
553
|
# Removed: Shakapacker 8+ is now required as explicit dependency
|
@@ -19,7 +19,7 @@ module ReactOnRails
|
|
19
19
|
aliases: "-T"
|
20
20
|
|
21
21
|
def create_redux_directories
|
22
|
-
# Create auto-
|
22
|
+
# Create auto-bundling directory structure for Redux
|
23
23
|
empty_directory("app/javascript/src/HelloWorldApp/ror_components")
|
24
24
|
|
25
25
|
# Create Redux support directories within the component directory
|
@@ -31,7 +31,7 @@ module ReactOnRails
|
|
31
31
|
base_js_path = "redux/base"
|
32
32
|
ext = component_extension(options)
|
33
33
|
|
34
|
-
# Copy Redux-connected component to auto-
|
34
|
+
# Copy Redux-connected component to auto-bundling structure
|
35
35
|
copy_file("#{base_js_path}/app/javascript/bundles/HelloWorld/startup/HelloWorldApp.client.#{ext}",
|
36
36
|
"app/javascript/src/HelloWorldApp/ror_components/HelloWorldApp.client.#{ext}")
|
37
37
|
copy_file("#{base_js_path}/app/javascript/bundles/HelloWorld/startup/HelloWorldApp.server.#{ext}",
|
@@ -89,6 +89,13 @@ module ReactOnRails
|
|
89
89
|
install_packages_with_fallback(regular_packages, dev: false, package_manager: package_manager)
|
90
90
|
end
|
91
91
|
|
92
|
+
def add_redux_specific_messages
|
93
|
+
# Append Redux-specific post-install instructions
|
94
|
+
GeneratorMessages.add_info(
|
95
|
+
GeneratorMessages.helpful_message_after_installation(component_name: "HelloWorldApp", route: "hello_world")
|
96
|
+
)
|
97
|
+
end
|
98
|
+
|
92
99
|
private
|
93
100
|
|
94
101
|
def install_packages_with_fallback(packages, dev:, package_manager:)
|
@@ -132,14 +139,6 @@ module ReactOnRails
|
|
132
139
|
when "yarn", "bun" then "--dev"
|
133
140
|
end
|
134
141
|
end
|
135
|
-
|
136
|
-
def add_redux_specific_messages
|
137
|
-
# Override the generic messages with Redux-specific instructions
|
138
|
-
GeneratorMessages.output.clear
|
139
|
-
GeneratorMessages.add_info(
|
140
|
-
GeneratorMessages.helpful_message_after_installation(component_name: "HelloWorldApp", route: "hello_world")
|
141
|
-
)
|
142
|
-
end
|
143
142
|
end
|
144
143
|
end
|
145
144
|
end
|
data/lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt
CHANGED
@@ -24,8 +24,8 @@ ReactOnRails.configure do |config|
|
|
24
24
|
# to automatically refresh your webpack assets on every test run.
|
25
25
|
#
|
26
26
|
# Alternately, you can remove the `ReactOnRails::TestHelper.configure_rspec_to_compile_assets`
|
27
|
-
# and set the config
|
28
|
-
config.build_test_command = "RAILS_ENV=test bin
|
27
|
+
# and set the config/shakapacker.yml option for test to true.
|
28
|
+
config.build_test_command = "RAILS_ENV=test bin/shakapacker"
|
29
29
|
|
30
30
|
################################################################################
|
31
31
|
################################################################################
|
@@ -43,6 +43,15 @@ ReactOnRails.configure do |config|
|
|
43
43
|
#
|
44
44
|
config.server_bundle_js_file = "server-bundle.js"
|
45
45
|
|
46
|
+
# Configure where server bundles are output. Defaults to "ssr-generated".
|
47
|
+
# This should match your webpack configuration for server bundles.
|
48
|
+
config.server_bundle_output_path = "ssr-generated"
|
49
|
+
|
50
|
+
# Enforce that server bundles are only loaded from private (non-public) directories.
|
51
|
+
# When true, server bundles will only be loaded from the configured server_bundle_output_path.
|
52
|
+
# This is recommended for production to prevent server-side code from being exposed.
|
53
|
+
config.enforce_private_server_bundles = true
|
54
|
+
|
46
55
|
################################################################################
|
47
56
|
################################################################################
|
48
57
|
# FILE SYSTEM BASED COMPONENT REGISTRY
|
data/lib/generators/react_on_rails/templates/base/base/config/webpack/serverWebpackConfig.js.tt
CHANGED
@@ -44,13 +44,14 @@ const configureServer = () => {
|
|
44
44
|
|
45
45
|
// Custom output for the server-bundle that matches the config in
|
46
46
|
// config/initializers/react_on_rails.rb
|
47
|
+
// Server bundles are output to a private directory (not public) for security
|
47
48
|
serverWebpackConfig.output = {
|
48
49
|
filename: 'server-bundle.js',
|
49
50
|
globalObject: 'this',
|
50
51
|
// If using the React on Rails Pro node server renderer, uncomment the next line
|
51
52
|
// libraryTarget: 'commonjs2',
|
52
|
-
path:
|
53
|
-
publicPath
|
53
|
+
path: require('path').resolve(__dirname, '../../ssr-generated'),
|
54
|
+
// No publicPath needed since server bundles are not served via web
|
54
55
|
// https://webpack.js.org/configuration/output/#outputglobalobject
|
55
56
|
};
|
56
57
|
|
@@ -52,8 +52,13 @@ module ReactOnRails
|
|
52
52
|
# If exceeded, an error will be thrown for server-side rendered components not registered on the client.
|
53
53
|
# Set to 0 to disable the timeout and wait indefinitely for component registration.
|
54
54
|
component_registry_timeout: DEFAULT_COMPONENT_REGISTRY_TIMEOUT,
|
55
|
-
generated_component_packs_loading_strategy: nil
|
55
|
+
generated_component_packs_loading_strategy: nil,
|
56
|
+
server_bundle_output_path: "ssr-generated",
|
57
|
+
enforce_private_server_bundles: false
|
56
58
|
)
|
59
|
+
# TODO: Add automatic detection of server_bundle_output_path from shakapacker.yml
|
60
|
+
# See feature/shakapacker-yml-integration branch for implementation
|
61
|
+
# Requires Shakapacker v8.5.0+ and semantic version checking
|
57
62
|
end
|
58
63
|
|
59
64
|
class Configuration
|
@@ -68,7 +73,8 @@ module ReactOnRails
|
|
68
73
|
:same_bundle_for_client_and_server, :rendering_props_extension,
|
69
74
|
:make_generated_server_bundle_the_entrypoint,
|
70
75
|
:generated_component_packs_loading_strategy, :immediate_hydration, :rsc_bundle_js_file,
|
71
|
-
:react_client_manifest_file, :react_server_client_manifest_file, :component_registry_timeout
|
76
|
+
:react_client_manifest_file, :react_server_client_manifest_file, :component_registry_timeout,
|
77
|
+
:server_bundle_output_path, :enforce_private_server_bundles
|
72
78
|
|
73
79
|
# rubocop:disable Metrics/AbcSize
|
74
80
|
def initialize(node_modules_location: nil, server_bundle_js_file: nil, prerender: nil,
|
@@ -85,7 +91,7 @@ module ReactOnRails
|
|
85
91
|
random_dom_id: nil, server_render_method: nil, rendering_props_extension: nil,
|
86
92
|
components_subdirectory: nil, auto_load_bundle: nil, immediate_hydration: nil,
|
87
93
|
rsc_bundle_js_file: nil, react_client_manifest_file: nil, react_server_client_manifest_file: nil,
|
88
|
-
component_registry_timeout: nil)
|
94
|
+
component_registry_timeout: nil, server_bundle_output_path: nil, enforce_private_server_bundles: nil)
|
89
95
|
self.node_modules_location = node_modules_location.present? ? node_modules_location : Rails.root
|
90
96
|
self.generated_assets_dirs = generated_assets_dirs
|
91
97
|
self.generated_assets_dir = generated_assets_dir
|
@@ -130,6 +136,8 @@ module ReactOnRails
|
|
130
136
|
self.defer_generated_component_packs = defer_generated_component_packs
|
131
137
|
self.immediate_hydration = immediate_hydration
|
132
138
|
self.generated_component_packs_loading_strategy = generated_component_packs_loading_strategy
|
139
|
+
self.server_bundle_output_path = server_bundle_output_path
|
140
|
+
self.enforce_private_server_bundles = enforce_private_server_bundles
|
133
141
|
end
|
134
142
|
# rubocop:enable Metrics/AbcSize
|
135
143
|
|
@@ -139,13 +147,13 @@ module ReactOnRails
|
|
139
147
|
ensure_webpack_generated_files_exists
|
140
148
|
configure_generated_assets_dirs_deprecation
|
141
149
|
configure_skip_display_none_deprecation
|
142
|
-
ensure_generated_assets_dir_present
|
143
150
|
check_server_render_method_is_only_execjs
|
144
151
|
error_if_using_packer_and_generated_assets_dir_not_match_public_output_path
|
145
152
|
# check_deprecated_settings
|
146
153
|
adjust_precompile_task
|
147
154
|
check_component_registry_timeout
|
148
155
|
validate_generated_component_packs_loading_strategy
|
156
|
+
validate_enforce_private_server_bundles
|
149
157
|
end
|
150
158
|
|
151
159
|
private
|
@@ -180,7 +188,7 @@ module ReactOnRails
|
|
180
188
|
1. Use :sync or :defer loading strategy instead of :async
|
181
189
|
2. Upgrade to Shakapacker v8.2.0 or above to enable async script loading
|
182
190
|
MSG
|
183
|
-
if PackerUtils.
|
191
|
+
if PackerUtils.supports_async_loading?
|
184
192
|
self.generated_component_packs_loading_strategy ||= :async
|
185
193
|
elsif generated_component_packs_loading_strategy.nil?
|
186
194
|
Rails.logger.warn("**WARNING** #{msg}")
|
@@ -194,15 +202,40 @@ module ReactOnRails
|
|
194
202
|
raise ReactOnRails::Error, "generated_component_packs_loading_strategy must be either :async, :defer, or :sync"
|
195
203
|
end
|
196
204
|
|
205
|
+
def validate_enforce_private_server_bundles
|
206
|
+
return unless enforce_private_server_bundles
|
207
|
+
|
208
|
+
# Check if server_bundle_output_path is nil
|
209
|
+
if server_bundle_output_path.nil?
|
210
|
+
raise ReactOnRails::Error, "enforce_private_server_bundles is set to true, but " \
|
211
|
+
"server_bundle_output_path is nil. Please set server_bundle_output_path " \
|
212
|
+
"to a directory outside of the public directory."
|
213
|
+
end
|
214
|
+
|
215
|
+
# Check if server_bundle_output_path is inside public directory
|
216
|
+
# Skip validation if Rails.root is not available (e.g., in tests)
|
217
|
+
return unless defined?(Rails) && Rails.root
|
218
|
+
|
219
|
+
public_path = Rails.root.join("public").to_s
|
220
|
+
server_output_path = File.expand_path(server_bundle_output_path, Rails.root.to_s)
|
221
|
+
|
222
|
+
return unless server_output_path.start_with?(public_path)
|
223
|
+
|
224
|
+
raise ReactOnRails::Error, "enforce_private_server_bundles is set to true, but " \
|
225
|
+
"server_bundle_output_path (#{server_bundle_output_path}) is inside " \
|
226
|
+
"the public directory. Please set it to a directory outside of public."
|
227
|
+
end
|
228
|
+
|
229
|
+
def check_minimum_shakapacker_version
|
230
|
+
ReactOnRails::PackerUtils.raise_shakapacker_version_incompatible_for_basic_pack_generation unless
|
231
|
+
ReactOnRails::PackerUtils.supports_basic_pack_generation?
|
232
|
+
end
|
233
|
+
|
197
234
|
def check_autobundling_requirements
|
198
|
-
raise_missing_components_subdirectory
|
199
|
-
return unless components_subdirectory.present?
|
235
|
+
raise_missing_components_subdirectory unless components_subdirectory.present?
|
200
236
|
|
201
|
-
ReactOnRails::PackerUtils.raise_shakapacker_not_installed unless ReactOnRails::PackerUtils.using_packer?
|
202
237
|
ReactOnRails::PackerUtils.raise_shakapacker_version_incompatible_for_autobundling unless
|
203
|
-
ReactOnRails::PackerUtils.
|
204
|
-
ReactOnRails::PacksGenerator::MINIMUM_SHAKAPACKER_VERSION
|
205
|
-
)
|
238
|
+
ReactOnRails::PackerUtils.supports_autobundling?
|
206
239
|
ReactOnRails::PackerUtils.raise_nested_entries_disabled unless ReactOnRails::PackerUtils.nested_entries?
|
207
240
|
end
|
208
241
|
|
@@ -221,8 +254,8 @@ module ReactOnRails
|
|
221
254
|
# We set it very big so that it is not used, and then clean just
|
222
255
|
# removes files older than 1 hour.
|
223
256
|
versions = 100_000
|
224
|
-
puts "Invoking task
|
225
|
-
Rake::Task["
|
257
|
+
puts "Invoking task shakapacker:clean from React on Rails"
|
258
|
+
Rake::Task["shakapacker:clean"].invoke(versions)
|
226
259
|
}
|
227
260
|
|
228
261
|
if Rake::Task.task_defined?("assets:precompile")
|
@@ -237,22 +270,20 @@ module ReactOnRails
|
|
237
270
|
end
|
238
271
|
|
239
272
|
def error_if_using_packer_and_generated_assets_dir_not_match_public_output_path
|
240
|
-
return unless ReactOnRails::PackerUtils.using_packer?
|
241
|
-
|
242
273
|
return if generated_assets_dir.blank?
|
243
274
|
|
244
275
|
packer_public_output_path = ReactOnRails::PackerUtils.packer_public_output_path
|
245
276
|
|
246
277
|
if File.expand_path(generated_assets_dir) == packer_public_output_path.to_s
|
247
278
|
Rails.logger.warn("You specified generated_assets_dir in `config/initializers/react_on_rails.rb` " \
|
248
|
-
"with
|
279
|
+
"with Shakapacker. " \
|
249
280
|
"Remove this line from your configuration file.")
|
250
281
|
else
|
251
282
|
msg = <<~MSG
|
252
|
-
Error configuring /config/initializers/react_on_rails.rb: You are using
|
283
|
+
Error configuring /config/initializers/react_on_rails.rb: You are using Shakapacker
|
253
284
|
and your specified value for generated_assets_dir = #{generated_assets_dir}
|
254
285
|
that does not match the value for public_output_path specified in
|
255
|
-
|
286
|
+
shakapacker.yml = #{packer_public_output_path}. You should remove the configuration
|
256
287
|
value for "generated_assets_dir" from your config/initializers/react_on_rails.rb file.
|
257
288
|
MSG
|
258
289
|
raise ReactOnRails::Error, msg
|
@@ -271,37 +302,21 @@ module ReactOnRails
|
|
271
302
|
raise ReactOnRails::Error, msg
|
272
303
|
end
|
273
304
|
|
274
|
-
def ensure_generated_assets_dir_present
|
275
|
-
return if generated_assets_dir.present? || ReactOnRails::PackerUtils.using_packer?
|
276
|
-
|
277
|
-
self.generated_assets_dir = DEFAULT_GENERATED_ASSETS_DIR
|
278
|
-
Rails.logger.warn "ReactOnRails: Set generated_assets_dir to default: #{DEFAULT_GENERATED_ASSETS_DIR}"
|
279
|
-
end
|
280
|
-
|
281
305
|
def configure_generated_assets_dirs_deprecation
|
282
306
|
return if generated_assets_dirs.blank?
|
283
307
|
|
284
|
-
|
285
|
-
packer_public_output_path = ReactOnRails::PackerUtils.packer_public_output_path
|
286
|
-
# rubocop:disable Layout/LineLength
|
287
|
-
packer_name = ReactOnRails::PackerUtils.packer_type&.upcase_first
|
308
|
+
packer_public_output_path = ReactOnRails::PackerUtils.packer_public_output_path
|
288
309
|
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
310
|
+
msg = <<~MSG
|
311
|
+
ReactOnRails Configuration Warning: The 'generated_assets_dirs' configuration option is no longer supported.
|
312
|
+
Since Shakapacker is now required, public asset paths are automatically determined from your shakapacker.yml configuration.
|
313
|
+
Please remove 'config.generated_assets_dirs' from your config/initializers/react_on_rails.rb file.
|
314
|
+
Public assets will be loaded from: #{packer_public_output_path}
|
315
|
+
If you need to customize the public output path, configure it in config/shakapacker.yml under 'public_output_path'.
|
316
|
+
Note: Private server bundles are configured separately via server_bundle_output_path.
|
317
|
+
MSG
|
295
318
|
|
296
|
-
Rails.logger.warn
|
297
|
-
"generated_assets_dirs"
|
298
|
-
if generated_assets_dir.blank?
|
299
|
-
self.generated_assets_dir = generated_assets_dirs
|
300
|
-
else
|
301
|
-
Rails.logger.warn "[DEPRECATION] ReactOnRails. You have both generated_assets_dirs and " \
|
302
|
-
"generated_assets_dir defined. Define ONLY generated_assets_dir if NOT using Shakapacker " \
|
303
|
-
"and define neither if using Webpacker"
|
304
|
-
end
|
319
|
+
Rails.logger.warn msg
|
305
320
|
end
|
306
321
|
|
307
322
|
def ensure_webpack_generated_files_exists
|
@@ -333,17 +348,15 @@ module ReactOnRails
|
|
333
348
|
end
|
334
349
|
|
335
350
|
def compile_command_conflict_message
|
336
|
-
packer_name = ReactOnRails::PackerUtils.packer_type.upcase_first
|
337
|
-
packer_type = ReactOnRails::PackerUtils.packer_type
|
338
351
|
<<~MSG
|
339
352
|
|
340
|
-
React on Rails and
|
353
|
+
React on Rails and Shakapacker error in configuration!
|
341
354
|
In order to use config/react_on_rails.rb config.build_production_command,
|
342
|
-
you must edit config
|
343
|
-
'
|
355
|
+
you must edit config/shakapacker.yml to include this value in the default configuration:
|
356
|
+
'shakapacker_precompile: false'
|
344
357
|
|
345
358
|
Alternatively, remove the config/react_on_rails.rb config.build_production_command and the
|
346
|
-
default bin
|
359
|
+
default bin/shakapacker script will be used for assets:precompile.
|
347
360
|
|
348
361
|
MSG
|
349
362
|
end
|
@@ -7,7 +7,12 @@ module ReactOnRails
|
|
7
7
|
def initialize(parse_error:, json:)
|
8
8
|
@json = json
|
9
9
|
@original_error = parse_error
|
10
|
-
|
10
|
+
message = <<~MSG
|
11
|
+
#{parse_error.message}
|
12
|
+
|
13
|
+
#{Utils.default_troubleshooting_section}
|
14
|
+
MSG
|
15
|
+
super(message)
|
11
16
|
end
|
12
17
|
|
13
18
|
def to_honeybadger_context
|
@@ -1,44 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "shakapacker"
|
4
|
+
|
3
5
|
module ReactOnRails
|
4
6
|
module PackerUtils
|
5
|
-
def self.using_packer?
|
6
|
-
using_shakapacker_const?
|
7
|
-
end
|
8
|
-
|
9
|
-
def self.using_shakapacker_const?
|
10
|
-
return @using_shakapacker_const if defined?(@using_shakapacker_const)
|
11
|
-
|
12
|
-
@using_shakapacker_const = ReactOnRails::Utils.gem_available?("shakapacker") &&
|
13
|
-
shakapacker_version_requirement_met?("8.2.0")
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.packer_type
|
17
|
-
return "shakapacker" if using_shakapacker_const?
|
18
|
-
|
19
|
-
nil
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.packer
|
23
|
-
return nil unless using_packer?
|
24
|
-
|
25
|
-
require "shakapacker"
|
26
|
-
::Shakapacker
|
27
|
-
end
|
28
|
-
|
29
7
|
def self.dev_server_running?
|
30
|
-
|
31
|
-
|
32
|
-
packer.dev_server.running?
|
8
|
+
Shakapacker.dev_server.running?
|
33
9
|
end
|
34
10
|
|
35
11
|
def self.dev_server_url
|
36
|
-
"#{
|
12
|
+
"#{Shakapacker.dev_server.protocol}://#{Shakapacker.dev_server.host_with_port}"
|
37
13
|
end
|
38
14
|
|
39
15
|
def self.shakapacker_version
|
40
16
|
return @shakapacker_version if defined?(@shakapacker_version)
|
41
|
-
return nil unless ReactOnRails::Utils.gem_available?("shakapacker")
|
42
17
|
|
43
18
|
@shakapacker_version = Gem.loaded_specs["shakapacker"].version.to_s
|
44
19
|
end
|
@@ -53,14 +28,28 @@ module ReactOnRails
|
|
53
28
|
end
|
54
29
|
|
55
30
|
def self.shakapacker_version_requirement_met?(required_version)
|
56
|
-
|
31
|
+
@version_checks ||= {}
|
32
|
+
@version_checks[required_version] ||= Gem::Version.new(shakapacker_version) >= Gem::Version.new(required_version)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.supports_async_loading?
|
36
|
+
shakapacker_version_requirement_met?("8.2.0")
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.supports_basic_pack_generation?
|
40
|
+
shakapacker_version_requirement_met?(ReactOnRails::PacksGenerator::MINIMUM_SHAKAPACKER_VERSION)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.supports_autobundling?
|
44
|
+
min_version = ReactOnRails::PacksGenerator::MINIMUM_SHAKAPACKER_VERSION_FOR_AUTO_BUNDLING
|
45
|
+
::Shakapacker.config.respond_to?(:nested_entries?) && shakapacker_version_requirement_met?(min_version)
|
57
46
|
end
|
58
47
|
|
59
48
|
# This returns either a URL for the webpack-dev-server, non-server bundle or
|
60
49
|
# the hashed server bundle if using the same bundle for the client.
|
61
50
|
# Otherwise returns a file path.
|
62
51
|
def self.bundle_js_uri_from_packer(bundle_name)
|
63
|
-
hashed_bundle_name =
|
52
|
+
hashed_bundle_name = ::Shakapacker.manifest.lookup!(bundle_name)
|
64
53
|
|
65
54
|
# Support for hashing the server-bundle and having that built
|
66
55
|
# the webpack-dev-server is provided by the config value
|
@@ -69,7 +58,7 @@ module ReactOnRails
|
|
69
58
|
is_bundle_running_on_server = (bundle_name == ReactOnRails.configuration.server_bundle_js_file) ||
|
70
59
|
(bundle_name == ReactOnRails.configuration.rsc_bundle_js_file)
|
71
60
|
|
72
|
-
if
|
61
|
+
if ::Shakapacker.dev_server.running? && (!is_bundle_running_on_server ||
|
73
62
|
ReactOnRails.configuration.same_bundle_for_client_and_server)
|
74
63
|
"#{dev_server_url}#{hashed_bundle_name}"
|
75
64
|
else
|
@@ -78,7 +67,7 @@ module ReactOnRails
|
|
78
67
|
end
|
79
68
|
|
80
69
|
def self.public_output_uri_path
|
81
|
-
"#{
|
70
|
+
"#{::Shakapacker.config.public_output_path.relative_path_from(::Shakapacker.config.public_path)}/"
|
82
71
|
end
|
83
72
|
|
84
73
|
# The function doesn't ensure that the asset exists.
|
@@ -93,42 +82,40 @@ module ReactOnRails
|
|
93
82
|
end
|
94
83
|
|
95
84
|
def self.precompile?
|
96
|
-
|
97
|
-
|
98
|
-
false
|
85
|
+
::Shakapacker.config.shakapacker_precompile?
|
99
86
|
end
|
100
87
|
|
101
88
|
def self.packer_source_path
|
102
|
-
|
89
|
+
::Shakapacker.config.source_path
|
103
90
|
end
|
104
91
|
|
105
92
|
def self.packer_source_entry_path
|
106
|
-
|
93
|
+
::Shakapacker.config.source_entry_path
|
107
94
|
end
|
108
95
|
|
109
96
|
def self.nested_entries?
|
110
|
-
|
97
|
+
::Shakapacker.config.nested_entries?
|
111
98
|
end
|
112
99
|
|
113
100
|
def self.packer_public_output_path
|
114
|
-
|
101
|
+
::Shakapacker.config.public_output_path.to_s
|
115
102
|
end
|
116
103
|
|
117
104
|
def self.manifest_exists?
|
118
|
-
|
105
|
+
::Shakapacker.config.public_manifest_path.exist?
|
119
106
|
end
|
120
107
|
|
121
108
|
def self.packer_source_path_explicit?
|
122
|
-
|
109
|
+
::Shakapacker.config.send(:data)[:source_path].present?
|
123
110
|
end
|
124
111
|
|
125
112
|
def self.check_manifest_not_cached
|
126
|
-
return unless
|
113
|
+
return unless ::Shakapacker.config.cache_manifest?
|
127
114
|
|
128
115
|
msg = <<-MSG.strip_heredoc
|
129
116
|
ERROR: you have enabled cache_manifest in the #{Rails.env} env when using the
|
130
117
|
ReactOnRails::TestHelper.configure_rspec_to_compile_assets helper
|
131
|
-
To fix this: edit your config
|
118
|
+
To fix this: edit your config/shakapacker.yml file and set cache_manifest to false for test.
|
132
119
|
MSG
|
133
120
|
puts wrap_message(msg)
|
134
121
|
exit!
|
@@ -149,7 +136,7 @@ module ReactOnRails
|
|
149
136
|
def self.raise_nested_entries_disabled
|
150
137
|
msg = <<~MSG
|
151
138
|
**ERROR** ReactOnRails: `nested_entries` is configured to be disabled in shakapacker. Please update \
|
152
|
-
config
|
139
|
+
config/shakapacker.yml to enable nested entries. for more information read
|
153
140
|
https://www.shakacode.com/react-on-rails/docs/guides/file-system-based-automated-bundle-generation.md#enable-nested_entries-for-shakapacker
|
154
141
|
MSG
|
155
142
|
|
@@ -158,19 +145,19 @@ module ReactOnRails
|
|
158
145
|
|
159
146
|
def self.raise_shakapacker_version_incompatible_for_autobundling
|
160
147
|
msg = <<~MSG
|
161
|
-
**ERROR** ReactOnRails: Please upgrade Shakapacker to version #{ReactOnRails::PacksGenerator::
|
162
|
-
above to use the automated bundle generation feature
|
163
|
-
#{ReactOnRails::PackerUtils.shakapacker_version}.
|
148
|
+
**ERROR** ReactOnRails: Please upgrade ::Shakapacker to version #{ReactOnRails::PacksGenerator::MINIMUM_SHAKAPACKER_VERSION_FOR_AUTO_BUNDLING} or \
|
149
|
+
above to use the automated bundle generation feature (which requires nested_entries support). \
|
150
|
+
The currently installed version is #{ReactOnRails::PackerUtils.shakapacker_version}. \
|
151
|
+
Basic pack generation requires ::Shakapacker #{ReactOnRails::PacksGenerator::MINIMUM_SHAKAPACKER_VERSION} or above.
|
164
152
|
MSG
|
165
153
|
|
166
154
|
raise ReactOnRails::Error, msg
|
167
155
|
end
|
168
156
|
|
169
|
-
def self.
|
157
|
+
def self.raise_shakapacker_version_incompatible_for_basic_pack_generation
|
170
158
|
msg = <<~MSG
|
171
|
-
**ERROR** ReactOnRails:
|
172
|
-
|
173
|
-
automated bundle generation feature.
|
159
|
+
**ERROR** ReactOnRails: Please upgrade ::Shakapacker to version #{ReactOnRails::PacksGenerator::MINIMUM_SHAKAPACKER_VERSION} or \
|
160
|
+
above to use basic pack generation features. The currently installed version is #{ReactOnRails::PackerUtils.shakapacker_version}.
|
174
161
|
MSG
|
175
162
|
|
176
163
|
raise ReactOnRails::Error, msg
|