Skip to content

precompile_hook detection always returns false due to regex mismatch #2279

@ihabadham

Description

@ihabadham

Environment

  1. Ruby version: 3.3.7
  2. Rails version: 8.0.4
  3. Shakapacker version: 9.4.0
  4. React on Rails version: 16.2.0.rc.0

Summary

The shakapacker_precompile_hook_configured? detection method always returns false even when precompile_hook is properly configured, because the regex looks for react_on_rails:generate_packs but the generator template uses generate_packs_if_stale.

Expected behavior

When precompile_hook: 'bin/shakapacker-precompile-hook' is configured in shakapacker.yml, the detection should return true:

ReactOnRails::PackerUtils.shakapacker_precompile_hook_configured?
# => true

Actual behavior

Detection always returns false:

ReactOnRails::PackerUtils.shakapacker_precompile_hook_configured?
# => false

Root Cause

In packer_utils.rb:204-219, the detection checks if the hook script contains the string react_on_rails:generate_packs:

def self.hook_contains_generate_packs?(hook_value)
  # ...
  return true if hook_value.to_s.match?(/\breact_on_rails:generate_packs\b/)
  # ...
  script_contents = File.read(script_path)
  script_contents.match?(/\breact_on_rails:generate_packs\b/)
end

But the generator template (templates/base/base/bin/shakapacker-precompile-hook) uses:

ReactOnRails::PacksGenerator.instance.generate_packs_if_stale

These strings don't match, so detection fails.

Steps to Reproduce

# After running generator with precompile_hook properly configured:
rails runner "
  puts 'Hook value: ' + ReactOnRails::PackerUtils.shakapacker_precompile_hook_value.inspect
  puts 'Detection: ' + ReactOnRails::PackerUtils.shakapacker_precompile_hook_configured?.to_s
  
  content = File.read('bin/shakapacker-precompile-hook')
  puts 'Contains react_on_rails:generate_packs: ' + content.include?('react_on_rails:generate_packs').to_s
  puts 'Contains generate_packs_if_stale: ' + content.include?('generate_packs_if_stale').to_s
"
# Output:
# Hook value: "bin/shakapacker-precompile-hook"
# Detection: false
# Contains react_on_rails:generate_packs: false
# Contains generate_packs_if_stale: true

Impact

Low severity for standard Shakapacker flow because:

  • The detection is only used in bin/dev (to skip redundant generation) and adjust_precompile_task
  • adjust_precompile_task returns early for standard flow (build_production_command.blank?)
  • bin/dev just does redundant (but harmless) pack generation

Higher severity for custom build_production_command scenarios:

  • Detection fails → fallback runs generate_packs rake task
  • But hook also runs → potential double pack generation

Suggested Fix

Update the regex to also match generate_packs_if_stale:

def self.hook_contains_generate_packs?(hook_value)
  return false if hook_value.blank?
  
  pattern = /\b(react_on_rails:generate_packs|generate_packs_if_stale)\b/
  
  return true if hook_value.to_s.match?(pattern)
  
  script_path = resolve_hook_script_path(hook_value)
  return false unless script_path && File.exist?(script_path)
  
  script_contents = File.read(script_path)
  script_contents.match?(pattern)
rescue StandardError
  false
end

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions