Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion lib/generators/react_on_rails/base_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,16 @@ def copy_base_files
app/views/layouts/hello_world.html.erb
Procfile.dev
Procfile.dev-static-assets
Procfile.dev-prod-assets]
Procfile.dev-prod-assets
bin/shakapacker-precompile-hook]
base_templates = %w[config/initializers/react_on_rails.rb]
base_files.each { |file| copy_file("#{base_path}#{file}", file) }
base_templates.each do |file|
template("#{base_path}/#{file}.tt", file)
end

# Make the hook script executable
File.chmod(0o755, "bin/shakapacker-precompile-hook") if File.exist?("bin/shakapacker-precompile-hook")
end

def copy_js_bundle_files
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

# Shakapacker precompile hook for React on Rails
#
# This script runs before webpack compilation to generate pack files
# for auto-bundled components. It's called automatically by Shakapacker
# when configured in config/shakapacker.yml:
# precompile_hook: 'bin/shakapacker-precompile-hook'

require_relative "../config/environment"

begin
puts Rainbow("🔄 Running React on Rails precompile hook...").cyan
ReactOnRails::PacksGenerator.instance.generate_packs_if_stale
rescue StandardError => e
warn Rainbow("❌ Error in precompile hook: #{e.message}").red
warn e.backtrace.first(5).join("\n")
exit 1
end
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ default: &default
# Raises an error if there is a mismatch in the shakapacker gem and npm package being used
ensure_consistent_versioning: true

# Hook to run before webpack compilation (e.g., for generating dynamic entry points)
# SECURITY: Only reference trusted scripts within your project. The hook command will be
# validated to ensure it points to a file within the project root.
precompile_hook: 'bin/shakapacker-precompile-hook'

# Select whether the compiler will use SHA digest ('digest' option) or most recent modified timestamp ('mtime') to determine freshness
compiler_strategy: digest

Expand Down
6 changes: 5 additions & 1 deletion lib/react_on_rails/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,11 @@ def adjust_precompile_task
raise(ReactOnRails::Error, compile_command_conflict_message) if ReactOnRails::PackerUtils.precompile?

precompile_tasks = lambda {
Rake::Task["react_on_rails:generate_packs"].invoke
# Skip generate_packs if shakapacker has a precompile hook configured
unless ReactOnRails::PackerUtils.shakapacker_precompile_hook_configured?
Rake::Task["react_on_rails:generate_packs"].invoke
end

Rake::Task["react_on_rails:assets:webpack"].invoke

# VERSIONS is per the shakacode/shakapacker clean method definition.
Expand Down
6 changes: 6 additions & 0 deletions lib/react_on_rails/dev/pack_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ module Dev
class PackGenerator
class << self
def generate(verbose: false)
# Skip if shakapacker has a precompile hook configured
if ReactOnRails::PackerUtils.shakapacker_precompile_hook_configured?
puts "⏭️ Skipping pack generation (handled by shakapacker precompile hook)" if verbose
return
end

if verbose
puts "📦 Generating React on Rails packs..."
success = system "bundle exec rake react_on_rails:generate_packs"
Expand Down
13 changes: 13 additions & 0 deletions lib/react_on_rails/packer_utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -166,5 +166,18 @@ def self.raise_shakapacker_version_incompatible_for_basic_pack_generation

raise ReactOnRails::Error, msg
end

# Check if shakapacker.yml has a precompile_hook configured
# This prevents react_on_rails from running generate_packs redundantly
def self.shakapacker_precompile_hook_configured?
return false unless defined?(::Shakapacker)

config_data = ::Shakapacker.config.send(:data)
hook = config_data[:precompile_hook]

hook.present?
rescue StandardError
false
end
end
end
20 changes: 20 additions & 0 deletions spec/dummy/bin/shakapacker-precompile-hook
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

# Shakapacker precompile hook for React on Rails
#
# This script runs before webpack compilation to generate pack files
# for auto-bundled components. It's called automatically by Shakapacker
# when configured in config/shakapacker.yml:
# precompile_hook: 'bin/shakapacker-precompile-hook'

require_relative "../config/environment"

begin
puts Rainbow("🔄 Running React on Rails precompile hook...").cyan
ReactOnRails::PacksGenerator.instance.generate_packs_if_stale
rescue StandardError => e
warn Rainbow("❌ Error in precompile hook: #{e.message}").red
warn e.backtrace.first(5).join("\n")
exit 1
end
5 changes: 5 additions & 0 deletions spec/dummy/config/shakapacker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ default: &default
cache_manifest: false
nested_entries: true

# Hook to run before webpack compilation (e.g., for generating dynamic entry points)
# SECURITY: Only reference trusted scripts within your project. The hook command will be
# validated to ensure it points to a file within the project root.
precompile_hook: 'bin/shakapacker-precompile-hook'

development:
<<: *default
# Turn this to true if you want to use the rails/shakapacker check that the test
Expand Down
Loading