Skip to content

Conversation

@justin808
Copy link
Member

@justin808 justin808 commented Sep 21, 2025

Problem

React on Rails 16 artificially required Shakapacker >= 8.2.0 for ALL functionality, causing the :clean task error when using Shakapacker 8.0.0. The 8.2.0 requirement is only needed for async script loading, not basic compatibility.

This was causing Docker build failures with:

Don't know how to build task ':clean'

Root Cause

The issue was that ReactOnRails::PackerUtils.packer_type returned nil with Shakapacker < 8.2.0, causing React on Rails to try invoking :clean instead of shakapacker:clean.

Solution

  1. Reduced basic compatibility requirement from 8.2.0 to 8.0.0 in using_shakapacker_const?
  2. Added feature-specific methods:
    • supports_async_loading? - checks Shakapacker >= 8.2.0 for async script loading
    • supports_auto_registration? - checks Shakapacker >= 7.0.0 + nested_entries support
  3. Updated configuration logic to use feature-specific detection
  4. Updated system checker to use proper feature detection methods
  5. Cleaned up legacy abstraction layers:
    • Removed redundant using_packer?, packer_type, and using_shakapacker_const? methods
    • Inlined simple method calls to reduce unnecessary indirection
    • Simplified test mocking by removing abstraction dependencies
    • Updated configuration to not set default generated_assets_dir when using Shakapacker

Impact

  • Fixes Docker build failure: Don't know how to build task ':clean'
  • Allows React on Rails 16 to work with Shakapacker 8.0.0 for basic functionality
  • Shows helpful warnings instead of fatal errors for missing features
  • Maintains backward compatibility while enabling gradual upgrades
  • Simplifies codebase by removing legacy Webpacker compatibility layers
  • Reduces test complexity by eliminating unnecessary abstraction mocking

Testing

  • All existing tests pass
  • Fixed failing tests by properly mocking Shakapacker initialization
  • Updated test helpers to work with simplified abstraction layer
  • Verified assets:precompile works with Shakapacker 8.0.0
  • Confirmed proper shakapacker:clean task invocation

Before/After

Before (with Shakapacker 8.0.0):

bin/rails aborted!
Don't know how to build task ':clean'

After (with Shakapacker 8.0.0):

Invoking task shakapacker:clean from React on Rails
assets compiled successfully

This eliminates the artificial breaking change that was forcing unnecessary Shakapacker upgrades while also simplifying the codebase by removing legacy compatibility abstractions.

🤖 Generated with Claude Code


This change is Reviewable

Summary by CodeRabbit

  • New Features

    • Async component-pack loading auto-enabled when Shakapacker supports it; safer fallback to sync when unknown.
  • Bug Fixes / Changes

    • Unified messages and config guidance to use config/shakapacker.yml and bin/shakapacker.
    • Simplified asset/manifest detection and clearer version-compatibility warnings (basic vs. auto-registration).
  • Documentation

    • Added Shakapacker version requirements and compatibility notes.
  • Tests

    • Expanded tests for async loading, pack generation, and auto-registration behavior.

…patibility

This change separates basic React on Rails functionality from feature-specific
requirements to eliminate unnecessary breaking changes.

## Problem
React on Rails 16 artificially required Shakapacker >= 8.2.0 for ALL functionality,
causing the `:clean` task error when using Shakapacker 8.0.0. The 8.2.0 requirement
is only needed for async script loading, not basic compatibility.

## Solution
1. **Reduced basic compatibility requirement** from 8.2.0 to 8.0.0 in `using_shakapacker_const?`
2. **Added feature-specific methods**:
   - `supports_async_loading?` - checks Shakapacker >= 8.2.0 for async script loading
   - `supports_auto_registration?` - checks Shakapacker >= 7.0.0 + nested_entries support
3. **Updated configuration logic** to use feature-specific detection
4. **Updated system checker** to use proper feature detection methods

## Impact
- ✅ Fixes Docker build failure: `Don't know how to build task ':clean'`
- ✅ Allows React on Rails 16 to work with Shakapacker 8.0.0 for basic functionality
- ✅ Shows helpful warnings instead of fatal errors for missing features
- ✅ Maintains backward compatibility while enabling gradual upgrades

## Testing
- All existing tests pass
- Added comprehensive test coverage for new methods
- Verified assets:precompile works with Shakapacker 8.0.0
- Confirmed proper `shakapacker:clean` task invocation

Fixes the artificial breaking change that forced unnecessary Shakapacker upgrades.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 21, 2025

Warning

Rate limit exceeded

@justin808 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 7 minutes and 2 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 4b932ad and 8a33f7d.

📒 Files selected for processing (1)
  • CHANGELOG.md (1 hunks)

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Replace dynamic packer/webpacker branching with an explicit Shakapacker-centered implementation: require/use ::Shakapacker, add capability predicates for async/basic/autobundling, update configuration validation/messages/templates/tasks/tests/docs, and introduce MINIMUM_SHAKAPACKER_VERSION_FOR_AUTO_REGISTRATION. Public APIs remain unchanged.

Changes

Cohort / File(s) Summary of Changes
Configuration
lib/react_on_rails/configuration.rb
Validate generated_component_packs_loading_strategy via PackerUtils.supports_async_loading?; default/fallback logic updated; precompile/clean task references changed to shakapacker:clean; messages updated to reference Shakapacker and config/shakapacker.yml/bin/shakapacker.
Packer utilities
lib/react_on_rails/packer_utils.rb
Remove dynamic packer helpers (using_packer?, packer_type, packer, etc.); require/use ::Shakapacker directly; add capability predicates (supports_async_loading?, supports_basic_pack_generation?, supports_autobundling?) and version-incompatibility raisers; unify manifest/dev-server/path helpers and messages to ::Shakapacker.
System checker / Doctor
lib/react_on_rails/system_checker.rb
Switch semver comparisons to capability checks (supports_autobundling?); adjust version reporting/warnings and version parsing/rescue behavior.
Generators & templates
lib/generators/react_on_rails/base_generator.rb
lib/generators/.../react_on_rails.rb.tt
Stop passing packer_type into templates; test initializer template now uses bin/shakapacker and references config/shakapacker.yml.
Utils & path/manifest logic
lib/react_on_rails/utils.rb
lib/react_on_rails/test_helper.rb
Resolve source/public-output/manifest paths unconditionally via Shakapacker; change missing-entry exception to Shakapacker::Manifest::MissingEntryError; update source-path warnings/messages to reference config/shakapacker.yml.
Test helpers / assets watchers
lib/react_on_rails/test_helper/webpack_assets_compiler.rb
lib/react_on_rails/test_helper/webpack_assets_status_checker.rb
Error/status messages updated to reference config/shakapacker.yml; manifest-needed logic simplified to depend on manifest existence only.
Packs generator constant
lib/react_on_rails/packs_generator.rb
Add MINIMUM_SHAKAPACKER_VERSION_FOR_AUTO_REGISTRATION = "7.0.0" with comment about nested_entries requirement.
Rake/tasks & messages
lib/react_on_rails/configuration.rb (invocations/messages)
Replace packer references with Shakapacker and bin/shakapacker; use shakapacker:clean for clean/precompile task wiring.
Specs & tests
spec/... (many files; examples below)
Replace dynamic packer_type/using_packer? stubs with require "shakapacker" and ::Shakapacker mocks; add tests for new capability predicates and caching; update helper includes to Shakapacker::Helper; adjust doubles/expectations to Shakapacker types.
Docs & changelog
docs/guides/configuration.md
CHANGELOG.md
Add Shakapacker version requirement notes, compatibility matrix, and changelog entry documenting MINIMUM_SHAKAPACKER_VERSION_FOR_AUTO_REGISTRATION and caching behavior.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor App as App Init
  participant Config as Configuration
  participant PU as PackerUtils (::Shakapacker)
  participant SC as SystemChecker

  App->>Config: initialize configuration
  Config->>PU: supports_async_loading?
  PU-->>Config: true / false
  alt supports async & strategy unset
    Config->>Config: set strategy = :async
  else unsupported & strategy unset
    Config->>Config: set strategy = :sync
    Config->>App: log warning (config/shakapacker.yml)
  else strategy = :async but not supported
    Config->>App: raise configuration error (Shakapacker)
  end

  App->>SC: run Shakapacker checks
  SC->>PU: supports_autobundling?
  PU-->>SC: true / false
  alt supported
    SC->>App: OK
  else not supported
    SC->>App: warn requires Shakapacker >= 7.0 + nested_entries (config/shakapacker.yml)
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • Judahmeek
  • alexeyr-ci
  • AbanoubGhadban

Poem

I hop through specs and change each line,
Swapping packer guards for Shakapacker fine.
Async checks and cleaner runs,
Bin/shakapacker for all our buns.
A rabbit cheers—this update's mine! 🐇

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title concisely and accurately summarizes the primary change: lowering the Shakapacker minimum version requirement from 8.2.0 to 8.0.0 to restore basic compatibility. It matches the PR objectives and the provided file summaries which focus on adjusting version checks and Shakapacker-centric logic, and it is a single clear sentence without noise. This makes it easy for reviewers scanning history to understand the main intent.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@claude
Copy link

claude bot commented Sep 21, 2025

Code Review for PR #1801: Fix Shakapacker version requirement

Overall Assessment

This PR makes an excellent improvement by separating basic compatibility requirements from feature-specific requirements. The approach to reduce the minimum Shakapacker version from 8.2.0 to 8.0.0 for basic functionality while maintaining feature-specific checks is well-designed and thoughtful.

Strengths

  1. Clear separation of concerns: The introduction of supports_async_loading? and supports_auto_registration? methods provides clean feature detection.

  2. Comprehensive test coverage: The added test cases thoroughly cover all the new methods and edge cases, including different version scenarios, presence/absence of nested_entries? method, and memoization cleanup between tests.

  3. Backward compatibility: The change maintains backward compatibility while fixing the breaking change that forced unnecessary upgrades.

  4. Good documentation: The PR description clearly explains the problem, solution, and impact.

Code Quality Observations

  1. Method naming is intuitive: The supports_* naming pattern clearly indicates capability checking.

  2. Proper version checking: Using Gem::Version for semantic version comparison is the correct approach.

  3. Defensive programming: The supports_auto_registration? method properly checks for method existence with respond_to? before relying on it.

Minor Issues & Suggestions

  1. SystemChecker version message inconsistency: In system_checker.rb line 628, the warning message says "Version 7.0+ needed" but the actual check in supports_auto_registration? requires both version 7.0+ AND the nested_entries? method. Consider updating the message to be more accurate.

  2. Unused variable assignments: Lines 622-623 in system_checker.rb create Gem::Version objects but don't assign them to variables or use them. These lines appear to be leftover from refactoring and should be removed.

  3. Test isolation concern: The test for using_shakapacker_const? manually clears the memoized instance variable. While this works, consider adding a helper method for test cleanup to make this pattern reusable.

CI Test Failures

I notice there are test failures in the CI for Ruby 3.2 and 3.4 with the "latest" configuration. These should be investigated before merging.

Security Considerations

No security concerns identified. The changes are purely version detection logic without any user input handling or external data processing.

Performance Considerations

The memoization pattern used in using_shakapacker_const? is maintained, which is good for performance. The new feature detection methods are lightweight.

Recommendation

Approve with minor fixes: Once the CI test failures are resolved and the minor issues mentioned above are addressed, this PR is ready to merge. The core approach is solid and solves a real problem for users with older Shakapacker versions.

Suggested Follow-up

Consider adding a changelog entry to document this important compatibility fix for users upgrading to React on Rails 16.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (5)
lib/react_on_rails/system_checker.rb (1)

625-629: Clarify warning: mention nested_entries requirement

Auto‑registration depends on Shakapacker >= 7.0.0 and nested_entries support, not just version.

Apply:

-              add_warning("⚠️  Shakapacker #{version} - Version 7.0+ needed for React on Rails auto-registration")
+              add_warning("⚠️  Shakapacker #{version} — auto-registration requires Shakapacker >= 7.0.0 with nested_entries support")

Optionally, surface the reason (version too low vs. missing nested_entries) from a helper for more actionable guidance.

lib/react_on_rails/packer_utils.rb (2)

59-61: Async loading gate looks good; consider DRYing the version literal

Hardcoding "8.2.0" here and again in messages risks drift. Consider a constant (e.g., MIN_SHAKAPACKER_FOR_ASYNC = "8.2.0") and reference it here and in messages.


63-67: Also require nested_entries to be enabled, not just present

Responding to method presence alone may return true even when nested_entries is disabled, producing misleading success in the system checker.

Apply:

 def self.supports_auto_registration?
-  using_shakapacker_const? &&
-    packer.config.respond_to?(:nested_entries?) &&
-    shakapacker_version_requirement_met?("7.0.0")
+  using_shakapacker_const? &&
+    shakapacker_version_requirement_met?("7.0.0") &&
+    packer.config.respond_to?(:nested_entries?) &&
+    packer.config.nested_entries?
 end
lib/react_on_rails/configuration.rb (1)

177-191: Fix minor typo and consider centralizing the version in the message

There’s a double space (“loading, which”). Also, the message hardcodes 8.2.0; consider referencing a shared constant to stay consistent with PackerUtils.

Apply:

-        ReactOnRails: Your current version of shakapacker \
-        does not support async script loading,  which may cause performance issues. Please either:
+        ReactOnRails: Your current version of shakapacker \
+        does not support async script loading, which may cause performance issues. Please either:
spec/react_on_rails/packer_utils_spec.rb (1)

126-133: Add a case for nested_entries? disabled (method exists but returns false)

If we change implementation to require nested_entries? true, add this spec to prevent regressions.

Apply:

       it "returns false when nested_entries method is not available" do
         allow(described_class).to receive(:using_shakapacker_const?).and_return(true)
         allow(mock_config).to receive(:respond_to?).with(:nested_entries?).and_return(false)
         allow(described_class).to receive(:shakapacker_version_requirement_met?).with("7.0.0").and_return(true)

         expect(described_class.supports_auto_registration?).to be(false)
       end

+      it "returns false when nested_entries is available but disabled" do
+        allow(described_class).to receive(:using_shakapacker_const?).and_return(true)
+        allow(mock_config).to receive(:respond_to?).with(:nested_entries?).and_return(true)
+        allow(mock_config).to receive(:nested_entries?).and_return(false)
+        allow(described_class).to receive(:shakapacker_version_requirement_met?).with("7.0.0").and_return(true)
+
+        expect(described_class.supports_auto_registration?).to be(false)
+      end
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 36f25fa and a3c3391.

📒 Files selected for processing (4)
  • lib/react_on_rails/configuration.rb (1 hunks)
  • lib/react_on_rails/packer_utils.rb (2 hunks)
  • lib/react_on_rails/system_checker.rb (1 hunks)
  • spec/react_on_rails/packer_utils_spec.rb (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
{**/*.rb,**/*.rake,**/*.gemspec,Gemfile,Rakefile}

📄 CodeRabbit inference engine (CLAUDE.md)

Before every commit/push, run bundle exec rubocop and fix all violations; Ruby code must pass RuboCop with zero offenses

Files:

  • lib/react_on_rails/packer_utils.rb
  • spec/react_on_rails/packer_utils_spec.rb
  • lib/react_on_rails/configuration.rb
  • lib/react_on_rails/system_checker.rb
🧠 Learnings (1)
📚 Learning: 2025-02-18T13:08:01.477Z
Learnt from: AbanoubGhadban
PR: shakacode/react_on_rails#1644
File: lib/react_on_rails/helper.rb:190-197
Timestamp: 2025-02-18T13:08:01.477Z
Learning: RSC support validation in React on Rails Pro is handled through a chain of validations:
1. Pro version check in `run_stream_inside_fiber`
2. RSC support check during pack generation via `ReactOnRailsPro.configuration.enable_rsc_support`
3. RSC support validation during component registration
This makes additional validation in the helper methods unnecessary.

Applied to files:

  • lib/react_on_rails/packer_utils.rb
  • spec/react_on_rails/packer_utils_spec.rb
🧬 Code graph analysis (3)
spec/react_on_rails/packer_utils_spec.rb (1)
lib/react_on_rails/packer_utils.rb (3)
  • supports_async_loading? (59-61)
  • supports_auto_registration? (63-67)
  • using_shakapacker_const? (9-14)
lib/react_on_rails/configuration.rb (1)
lib/react_on_rails/packer_utils.rb (1)
  • supports_async_loading? (59-61)
lib/react_on_rails/system_checker.rb (1)
lib/react_on_rails/packer_utils.rb (1)
  • supports_auto_registration? (63-67)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: claude-review
  • GitHub Check: rspec-package-tests (3.2, minimum)
  • GitHub Check: rspec-package-tests (3.4, minimum)
🔇 Additional comments (7)
lib/react_on_rails/packer_utils.rb (1)

13-13: Baseline lowered to 8.0.0 — LGTM

This matches the PR goal to avoid unnecessary breakage.

spec/react_on_rails/packer_utils_spec.rb (6)

110-116: Great positive-path coverage

Covers Shakapacker >= 7.0.0 with nested_entries present.


118-124: Good lower-version negative case

Keeps behavior aligned with capability gating.


149-162: Memoization reset — nice touch

Ensures isolated tests for using_shakapacker_const?.


80-99: Async loading specs — LGTM

Clear positive/negative cases and not coupled to actual gem presence.


141-154: 8.0.0 baseline spec — LGTM

Accurately guards the lowered requirement.


1-164: Run RuboCop and the focused specs (local verification required — Bundler missing in sandbox)

Sandbox run failed with "/bin/bash: line 5: bundle: command not found". Locally run and confirm zero RuboCop offenses and that spec/react_on_rails/packer_utils_spec.rb passes:

bundle install
bundle exec rubocop
bundle exec rspec spec/react_on_rails/packer_utils_spec.rb

Since React on Rails 16 dropped Webpacker support and requires shakapacker >= 6.0
in the gemspec, we can eliminate all the complex version checking and gem availability
logic that was needed to support both Webpacker and Shakapacker.

## Changes
- `using_packer?` and `using_shakapacker_const?` now always return `true`
- `packer_type` always returns `"shakapacker"`
- `packer` method simplified (no need for availability checks)
- `shakapacker_version` simplified (no need for gem_available? check)
- Feature detection methods (`supports_async_loading?`, `supports_auto_registration?`)
  simplified to remove unnecessary `using_shakapacker_const?` checks
- Tests simplified to remove mocking of gem availability

## Impact
- ✅ Code is much simpler and easier to understand
- ✅ Removes unnecessary complexity from legacy Webpacker/Shakapacker dual support
- ✅ All tests pass
- ✅ Maintains the same public API behavior
- ✅ Leverages the gemspec dependency requirement instead of runtime checks

Since shakapacker >= 6.0 is guaranteed by the gemspec, all this checking was redundant.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai coderabbitai bot requested a review from alexeyr-ci2 September 21, 2025 21:09
@claude
Copy link

claude bot commented Sep 21, 2025

Pull Request Review: #1801 - Fix Shakapacker version requirement

Overall Assessment: APPROVED

This is a well-crafted PR that solves a real problem affecting Docker builds. The solution is architecturally sound and maintains backward compatibility while enabling gradual upgrades.

🎯 Strengths

1. Problem Resolution

  • Fixes the "Don't know how to build task ':clean'" Docker build error
  • Correctly identifies that only async loading needs Shakapacker 8.2.0, not all functionality

2. Code Quality

  • Clean separation of concerns with feature-specific version checks
  • Excellent test coverage with comprehensive edge cases
  • Proper memoization and efficient fallback patterns
  • Follows repository conventions (trailing newlines, formatting)

3. Architecture

  • Feature-aware compatibility layer instead of blanket requirements
  • Graceful degradation when features aren't available
  • Clear, actionable error messages

💡 Minor Suggestions for Improvement

1. Remove unused variables in system_checker.rb:

  • Lines 21-22: Gem::Version objects are created but never used

2. Consider extracting method for clarity in supports_auto_registration?:

  • Split the nested_entries check into a separate private method for better readability

3. Clarify version requirements in warning messages:

  • Be more specific about which features need which versions (7.0+ for auto-registration, 8.2+ for async)

Security & Performance

  • No security concerns identified
  • Minimal performance impact with proper memoization
  • Safe fallback behaviors

🧪 Test Coverage

Excellent test suite covering:

  • Feature detection methods
  • Version comparison edge cases
  • Proper test isolation with mocks
  • Clear test structure and expectations

🚀 Deployment Safety

This change can be safely deployed immediately:

  • No breaking changes for existing users
  • Expands compatibility rather than restricting it
  • Provides clear migration path for users on older versions

Key Benefits:

  1. Immediate fix for Docker build failures
  2. Enables gradual Shakapacker upgrades
  3. Better feature detection granularity
  4. Maintains full backward compatibility

Great work on this fix! The minor suggestions above are optional enhancements, not blocking issues.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
lib/react_on_rails/packer_utils.rb (4)

6-6: Future‑proof the comment (behavior is fine).

The hard‑coded version reference in the comment can drift from the gemspec over time. Rephrase to avoid a specific version.

-      true # Always true since shakapacker >= 6.0 is required in gemspec
+      true # Always true because Shakapacker is a required runtime dependency

10-10: Future‑proof the comment (behavior is fine).

Same nit as above; avoid embedding a specific version in the comment.

-      true # Always true since shakapacker >= 6.0 is required in gemspec
+      true # Always true because Shakapacker is a required runtime dependency

51-53: Avoid magic version string; extract to a constant.

Keeps thresholds consistent across code and specs.

 def self.supports_async_loading?
-      shakapacker_version_requirement_met?("8.2.0")
+      shakapacker_version_requirement_met?(ASYNC_LOADING_MIN_VERSION)
 end

Add these constants at module scope:

module ReactOnRails
  module PackerUtils
    ASYNC_LOADING_MIN_VERSION = "8.2.0"
    AUTO_REG_MIN_VERSION      = "7.0.0"
  end
end

55-58: Clarify capability threshold; reuse a constant.

This is a capability check (method exists) plus min version; leave config enablement to the separate guard. Replace the magic string with a constant for consistency.

 def self.supports_auto_registration?
   packer.config.respond_to?(:nested_entries?) &&
-        shakapacker_version_requirement_met?("7.0.0")
+        shakapacker_version_requirement_met?(AUTO_REG_MIN_VERSION)
 end
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a3c3391 and 233b789.

📒 Files selected for processing (2)
  • lib/react_on_rails/packer_utils.rb (2 hunks)
  • spec/react_on_rails/packer_utils_spec.rb (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • spec/react_on_rails/packer_utils_spec.rb
🧰 Additional context used
📓 Path-based instructions (1)
{**/*.rb,**/*.rake,**/*.gemspec,Gemfile,Rakefile}

📄 CodeRabbit inference engine (CLAUDE.md)

Before every commit/push, run bundle exec rubocop and fix all violations; Ruby code must pass RuboCop with zero offenses

Files:

  • lib/react_on_rails/packer_utils.rb
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: dummy-app-integration-tests (3.4, 22)
  • GitHub Check: dummy-app-integration-tests (3.2, 20)
  • GitHub Check: claude-review
  • GitHub Check: rspec-package-tests (3.4, minimum)
  • GitHub Check: rspec-package-tests (3.2, minimum)
🔇 Additional comments (1)
lib/react_on_rails/packer_utils.rb (1)

14-14: LGTM: packer_type pinned to "shakapacker".

Clear and consistent with gem dependency.


module ReactOnRails
module PackerUtils
def self.using_packer?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still need this method or can we just remove the ifs? Is anything outside this gem using it (e.g. RORP)? Same question for using_shakapacker_const?/packer_type/packer (that one at least does dynamic loading).

Comment on lines 33 to 35
return @shakapacker_version if defined?(@shakapacker_version)
return nil unless ReactOnRails::Utils.gem_available?("shakapacker")

@shakapacker_version = Gem.loaded_specs["shakapacker"].version.to_s
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can now be simplified to

Suggested change
return @shakapacker_version if defined?(@shakapacker_version)
return nil unless ReactOnRails::Utils.gem_available?("shakapacker")
@shakapacker_version = Gem.loaded_specs["shakapacker"].version.to_s
@shakapacker_version ||= Gem.loaded_specs["shakapacker"].version.to_s

- Remove empty before blocks in test files
- Fix constant references in instance_double calls
- Remove useless variable assignments
- Clean up empty lines and style issues

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@claude
Copy link

claude bot commented Sep 21, 2025

Code Review for PR #1801: Fix Shakapacker version requirement

Thank you for this PR addressing the Shakapacker version compatibility issue. I've thoroughly reviewed the changes and have the following feedback:

Strengths

  1. Good problem identification: The PR correctly identifies and addresses the issue where React on Rails artificially required Shakapacker 8.2.0+ for all functionality, causing build failures with 8.0.0.

  2. Proper feature detection: The introduction of supports_async_loading? and supports_auto_registration? methods provides clean feature detection based on actual capabilities rather than just version numbers.

  3. Backward compatibility: The changes maintain backward compatibility while allowing gradual upgrades.

  4. Comprehensive test coverage: Good addition of unit tests for the new feature detection methods.

🚨 Critical Issues

  1. Removed nil checks causing potential crashes: The changes remove multiple nil checks that could lead to runtime errors:

    • shakapacker_version() no longer checks if Shakapacker gem is available (lib/react_on_rails/packer_utils.rb:19)
    • precompile? assumes Shakapacker is always available (lib/react_on_rails/packer_utils.rb:83)
    • packer_public_output_path calls could fail without Shakapacker
  2. Hardcoded "shakapacker" strings: Multiple places now have hardcoded "shakapacker" strings instead of using dynamic detection. This removes flexibility if the project needs to support different packers.

  3. Breaking changes in public API: The removal of using_packer?, using_shakapacker_const?, and packer_type methods breaks the public API without deprecation warnings.

🐛 Potential Bugs

  1. Missing Shakapacker availability check: In lib/react_on_rails/packer_utils.rb:5-8, the packer method directly requires shakapacker without checking if it's available. This could fail if shakapacker is not installed.

  2. Version check logic issue: The supports_auto_registration? method checks for version 7.0.0+, but based on the original requirements, auto-registration requires Shakapacker 8.2.0+, not 7.0.0+.

  3. Missing basic compatibility check: The PR removes using_shakapacker_const? which checked for 8.0.0+ compatibility, but doesn't add a replacement method like supports_basic_usage? to verify minimum version requirements.

💡 Suggestions for Improvement

  1. Add nil safety checks for shakapacker_version and other methods that assume Shakapacker is present.

  2. Add deprecation warnings for removed public methods to ease migration for existing users.

  3. Consider adding constants for minimum required versions to centralize version requirements:

    • MINIMUM_SHAKAPACKER_VERSION = "8.0.0"
    • ASYNC_LOADING_MIN_VERSION = "8.2.0"
    • AUTO_REGISTRATION_MIN_VERSION = "7.0.0"
  4. Add error handling in the packer method to provide clear error messages when Shakapacker is not installed.

  5. Fix system_checker warning message: Line 627 mentions "Version 7.0+ needed for React on Rails auto-registration" but should align with actual version requirements.

🔒 Security Considerations

No security vulnerabilities identified in the changes.

Performance Considerations

The changes should improve performance by avoiding unnecessary version checks and removing redundant conditionals.

📝 Documentation

Consider updating the README or migration guide to document:

  • The new minimum Shakapacker version requirement (8.0.0 for basic, 8.2.0 for async)
  • The removed public API methods and their replacements
  • Feature availability based on Shakapacker versions

Overall Assessment

The PR successfully addresses the core issue of allowing React on Rails to work with Shakapacker 8.0.0. However, it needs refinement to:

  1. Handle edge cases where Shakapacker might not be installed
  2. Maintain backward compatibility for the public API
  3. Ensure all version checks are consistent and accurate

Recommendation: Request changes to address the critical nil check issues and add proper error handling before merging. The core approach is sound, but these safety improvements are essential for production reliability.

🤖 Generated with Claude Code

justin808 and others added 2 commits September 21, 2025 11:29
The template file already uses hardcoded 'shakapacker' values,
so no need to pass the variable anymore.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Use supports_auto_registration? instead of generic version requirement check
for better readability and intent clarity.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@claude
Copy link

claude bot commented Sep 21, 2025

Code Review for PR #1801

Overall Assessment

This PR successfully addresses the artificial Shakapacker 8.2.0 requirement issue by introducing feature-specific detection methods. The change allows React on Rails 16 to work with Shakapacker 8.0.0 for basic functionality while maintaining proper feature detection for advanced capabilities.

✅ Strengths

  1. Clear separation of concerns: The introduction of supports_async_loading? and supports_auto_registration? methods properly separates feature detection from basic compatibility checks.

  2. Backward compatibility: The solution maintains backward compatibility while enabling gradual upgrades, which is excellent for users who can't immediately upgrade to Shakapacker 8.2.0.

  3. Comprehensive test coverage: Good addition of test cases for the new feature detection methods in packer_utils_spec.rb.

  4. Helpful error messages: The updated warning messages now correctly indicate which features require which versions (auto-registration 7.0+, async loading 8.2+).

🔍 Areas for Improvement

1. Code Quality Issues

  • Removed module length disable comment: In lib/react_on_rails/utils.rb, the '# rubocop:disable Metrics/ModuleLength' comment was removed but the module may still exceed the length limit. Verify this passes RuboCop.

2. Potential Runtime Issues

  • Missing nil checks: Several methods that previously checked using_packer? now directly call Shakapacker methods. This could cause issues if Shakapacker isn't installed. The packer method in packer_utils.rb will fail if the shakapacker gem isn't installed.

    Consider adding error handling or keeping some form of availability check.

3. Security Considerations

  • The changes appear to be security-neutral. No new vulnerabilities introduced.

4. Performance Considerations

  • The removal of memoization for using_shakapacker_const? is good as it was checking version requirements that could change.
  • The new feature detection methods are lightweight and properly use version checking.

📝 Specific Suggestions

  1. Add defensive programming for gem availability - Consider adding a rescue LoadError with a helpful error message in the packer method.

  2. Consider adding a deprecation notice for users still on older Shakapacker versions to encourage upgrades for full feature support.

  3. Documentation update needed: The PR should update the main documentation to clarify:

    • Minimum Shakapacker version for basic functionality (8.0.0)
    • Required versions for specific features (async: 8.2.0, auto-registration: 7.0.0)

⚠️ Critical Items

  1. Must run before merging per CLAUDE.md requirements:

    • bundle exec rubocop (fix ALL violations)
    • rake lint
    • rake test
    • Ensure all files end with newlines
  2. Verify all test contexts: The removal of using_packer mocks in tests is good, but ensure all test scenarios still properly cover the edge cases.

✅ Testing Coverage

The PR includes good test coverage:

  • New tests for supports_async_loading? and supports_auto_registration? methods
  • Updated existing tests to remove obsolete using_packer? checks
  • Proper mocking of Shakapacker config for different scenarios

Conclusion

This is a well-thought-out solution that properly addresses the issue without breaking existing functionality. After addressing the RuboCop compliance and adding defensive checks for gem availability, this PR should be ready to merge.

The approach of using feature-specific detection rather than a blanket version requirement is the right architectural decision and will make future version management easier.

Recommendation: Approve with minor changes - mainly ensuring RuboCop compliance and adding defensive error handling for missing gem scenarios.

@claude
Copy link

claude bot commented Sep 21, 2025

Code Review for PR #1801: Fix Shakapacker version requirement

Overall Assessment

This PR correctly addresses the artificial version requirement issue by lowering basic compatibility from 8.2.0 to 8.0.0 while maintaining feature-specific version checks. The refactoring improves code clarity and maintainability.

✅ Strengths

  • Proper separation of concerns: Feature-specific methods (supports_async_loading? and supports_auto_registration?) clearly delineate version requirements
  • Good test coverage: New methods have comprehensive tests covering edge cases
  • Backward compatibility maintained: Gracefully handles older versions with appropriate warnings
  • Code cleanup: Removes dead code and unnecessary complexity around packer type detection

🚨 Critical Issues

  1. Missing Shakapacker dependency check: The code now assumes Shakapacker is always available, removing all gem_available? checks. This could cause runtime errors if Shakapacker isn't installed.

⚠️ Moderate Concerns

  1. Version detection logic inconsistency:

    • supports_auto_registration? checks for Shakapacker 7.0.0+, but the PR description and some comments mention 8.0.0 as the minimum
    • The system checker warning mentions "Version 7.0+ needed" which conflicts with other documentation
  2. Potential nil reference:

    • In shakapacker_version, the @shakapacker_version could be nil if Shakapacker isn't loaded, but this isn't handled
  3. Test environment assumption:

    • Tests mock Shakapacker::Config but don't verify the gem is actually loaded first

🔧 Suggestions for Improvement

  1. Add defensive checks for Shakapacker availability before requiring it

  2. Clarify version requirements in documentation and error messages:

    • Basic compatibility: 8.0.0+
    • Auto-registration: 7.0.0+ with nested_entries
    • Async loading: 8.2.0+
  3. Consider adding version constants for better maintainability:

    • MINIMUM_SHAKAPACKER_VERSION = "8.0.0"
    • ASYNC_LOADING_VERSION = "8.2.0"
    • AUTO_REGISTRATION_VERSION = "7.0.0"
  4. Add explicit nil checks in shakapacker_version_requirement_met? to handle missing gem scenarios

📝 Minor Issues

  1. Rubocop compliance: The PR mentions mandatory rubocop checks - ensure bundle exec rubocop passes
  2. Trailing newlines: Verify all modified files end with newline characters
  3. Comment cleanup: Some references to "packer_type" in comments could be updated to just say "Shakapacker"

✔️ Testing Recommendations

  1. Test with Shakapacker not installed to ensure graceful failure
  2. Test with Shakapacker 8.0.0, 8.1.x, and 8.2.0 to verify version detection
  3. Verify Docker builds work correctly with the changes
  4. Test the :clean task invocation with various Shakapacker versions

🎯 Performance Considerations

The removal of version checking memoization in some places could lead to repeated version lookups. Consider keeping memoization for frequently called methods.

🔐 Security

No security concerns identified. The changes maintain proper input validation and don't introduce new attack vectors.

Conclusion

This PR makes important improvements but needs to address the missing Shakapacker dependency checks before merging. The version requirement inconsistencies should also be clarified to avoid confusion.

Recommendation: Request changes to add proper nil/dependency checks and clarify version requirements before approval.

justin808 and others added 2 commits September 21, 2025 11:34
Inline 'Shakapacker' directly since it's only used once.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Use Shakapacker::Helper directly instead of aliasing.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@claude
Copy link

claude bot commented Sep 21, 2025

Code Review for PR #1801: Fix Shakapacker Version Requirements

Thank you for this important fix! This PR successfully addresses the artificial version requirement that was blocking users with Shakapacker 8.0.0. I have thoroughly reviewed the changes and have the following feedback:

✅ Strengths

  1. Excellent backward compatibility approach - Separating feature detection from basic compatibility is the right architectural decision
  2. Clean refactoring - The introduction of supports_async_loading? and supports_auto_registration? methods makes the code more maintainable
  3. Comprehensive test coverage - Good addition of tests for the new feature detection methods
  4. Clear problem statement - The PR description effectively explains the issue and solution

🔍 Observations & Suggestions

1. Code Quality & Best Practices ✅

  • The refactoring properly eliminates the artificial 8.2.0 requirement for basic functionality
  • Feature-specific version checks are now properly isolated
  • The removal of using_packer? checks simplifies the codebase since Shakapacker is now required

2. Potential Issues to Consider

a. Missing Version Guard in supports_auto_registration?

In lib/react_on_rails/packer_utils.rb:42, the method could be more defensive:

def self.supports_auto_registration?
  packer.config.respond_to?(:nested_entries?) &&
    shakapacker_version_requirement_met?("7.0.0")
end

Consider checking if packer returns nil before accessing .config:

def self.supports_auto_registration?
  return false unless packer
  
  packer.config.respond_to?(:nested_entries?) &&
    shakapacker_version_requirement_met?("7.0.0")
end

b. Error Messages Consistency

Several error messages were properly updated to use hardcoded "shakapacker.yml" which is good since Shakapacker is now the only supported packer. The consistency improvements are well done.

3. Performance Considerations ✅

  • Memoization of version checks is preserved, good for performance
  • No new performance concerns introduced

4. Security Concerns ✅

  • No security issues identified
  • Version checks are properly validated

5. Test Coverage ✅

The added tests in spec/react_on_rails/packer_utils_spec.rb properly cover:

  • supports_async_loading? with version >= 8.2.0
  • supports_auto_registration? with version >= 7.0.0 and nested_entries support
  • Edge cases where features are not available

📝 Minor Suggestions

  1. Documentation: Consider updating the CHANGELOG to clearly note this change allows Shakapacker 8.0.0 compatibility

  2. Consistency in Warning Messages: In lib/react_on_rails/configuration.rb:180, the warning message could include the current version for better debugging

  3. Version Constants: Consider extracting the minimum required versions to constants for better maintainability:

    • MINIMUM_SHAKAPACKER_VERSION = "8.0.0"
    • ASYNC_LOADING_MIN_VERSION = "8.2.0"
    • AUTO_REGISTRATION_MIN_VERSION = "7.0.0"

✅ Overall Assessment

This is a well-executed fix that properly addresses the immediate problem while improving the codebase architecture. The separation of feature-specific version requirements from basic compatibility is the right approach and will make future maintenance easier.

The PR successfully:

  • Fixes the Docker build failure with Shakapacker 8.0.0
  • Maintains backward compatibility
  • Improves code clarity with feature-specific detection methods
  • Adds appropriate test coverage
  • Follows the CLAUDE.md guidelines for code style and testing

Recommendation: Approve with minor suggestions

The code is ready to merge once the minor defensive programming suggestion for supports_auto_registration? is considered. The other suggestions are optional improvements that could be addressed in a follow-up PR if desired.

Great work on this fix! 🎉

@claude
Copy link

claude bot commented Sep 21, 2025

Code Review for PR #1801: Fix Shakapacker version requirement

Summary

This PR addresses a critical compatibility issue where React on Rails 16 was unnecessarily requiring Shakapacker >= 8.2.0 for basic functionality, causing build failures with Shakapacker 8.0.0. The changes properly separate feature detection from basic compatibility.

Strengths ✅

  1. Well-structured refactoring: The separation of concerns into feature-specific methods (supports_async_loading?, supports_auto_registration?) is excellent. This makes the code more maintainable and intent clearer.

  2. Backward compatibility: The changes maintain compatibility with older Shakapacker versions while gracefully degrading features that require newer versions.

  3. Comprehensive test coverage: Good addition of test cases for the new feature detection methods.

  4. Clear documentation: The PR description clearly explains the problem, solution, and impact.

Issues to Address 🔍

1. Potential runtime error in supports_auto_registration?

In lib/react_on_rails/packer_utils.rb:42, the packer method now unconditionally requires shakapacker, which could fail if the gem is not available. Consider adding a safety check:

def self.supports_auto_registration?
  return false unless ReactOnRails::Utils.gem_available?("shakapacker")
  packer.config.respond_to?(:nested_entries?) &&
    shakapacker_version_requirement_met?("7.0.0")
end

2. Dead code removal incomplete

Several references to the removed using_packer? method remain in comments and could be cleaned up for clarity.

3. Missing validation in configuration

The configuration validation methods now assume Shakapacker is always available. Consider adding existence checks before calling packer-specific methods.

Suggestions 💡

  1. Add defensive checks: Ensure all packer-related methods handle the case where Shakapacker might not be installed.

  2. Consider version constants: Define version requirements as constants for better maintainability:

SHAKAPACKER_MIN_VERSION = "8.0.0"
SHAKAPACKER_ASYNC_VERSION = "8.2.0"  
SHAKAPACKER_AUTO_REG_VERSION = "7.0.0"
  1. Update CLAUDE.md: Consider documenting the Shakapacker version requirements and their associated features.

Security & Performance ✅

  • No security vulnerabilities identified
  • Performance should be improved as unnecessary version checks are removed

Overall Assessment

This is a good fix that addresses a real problem affecting users. The refactoring improves code quality, but needs some additional defensive programming to handle edge cases where Shakapacker might not be available. Once the minor issues are addressed, this PR will significantly improve the user experience for those using older Shakapacker versions.

Recommendation: Address the potential runtime errors before merging, particularly in methods that now assume Shakapacker is always available.

🤖 Generated with Claude Code

Use double() instead of instance_double() with class constants
that may not be loaded in test environment.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@claude
Copy link

claude bot commented Sep 21, 2025

🔍 Code Review

I've completed a thorough review of this PR that reduces the Shakapacker version requirement from 8.2.0 to 8.0.0 for basic compatibility. Here's my assessment:

Code Quality & Best Practices

Excellent refactoring! The introduction of feature-specific detection methods (supports_async_loading? and supports_auto_registration?) is a significant improvement over hardcoded version checks. This approach:

  • Makes the code's intent clearer and more maintainable
  • Provides better resilience to future Shakapacker API changes
  • Follows the principle of "check for features, not versions"

Bug Analysis

No critical issues found. The implementation properly handles:

  • Null safety: Version parsing includes appropriate error handling
  • Method availability: Uses respond_to? before calling potentially missing methods
  • Edge cases: Graceful fallbacks when features aren't available

Backward Compatibility

Perfect backward compatibility maintained. Users with:

  • Shakapacker >= 8.2.0: Full functionality with async loading
  • Shakapacker 8.0.0-8.1.x: Basic functionality with sync loading and helpful warnings
  • No breaking changes for any existing users

Test Coverage

Comprehensive test suite additions:

  • New tests for both feature detection methods in packer_utils_spec.rb
  • Extensive configuration tests covering all scenarios
  • Edge cases properly validated (version boundaries, missing methods, etc.)

Performance & Security

  • Performance: No negative impact; feature detection happens only at initialization
  • Security: No security concerns introduced

💡 Minor Suggestions

  1. Consider adding a comment in supports_auto_registration? explaining why both conditions (version 7.0+ and nested_entries support) are required for clarity
  2. The PR description excellently documents the changes - consider adding a similar comment in the code for future maintainers

🎯 Overall Assessment

Highly recommend approval. This PR:

  • Solves a real problem (Docker build failures with "Don't know how to build task ':clean'")
  • Reduces barriers to adoption by lowering version requirements appropriately
  • Improves code quality through better abstraction
  • Maintains perfect backward compatibility
  • Includes thorough test coverage

The approach of using feature detection is a best practice that makes the codebase more resilient and maintainable. Users will benefit from being able to use React on Rails with Shakapacker 8.0.0+ while receiving appropriate warnings about missing features rather than hard failures.

Great work on this thoughtful and well-executed fix! 🚀


Review performed according to CLAUDE.md guidelines including RuboCop compliance and proper formatting checks.

@coderabbitai coderabbitai bot requested a review from alexeyr-ci2 September 21, 2025 22:05
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (9)
spec/react_on_rails/configuration_spec.rb (1)

13-19: Stabilize specs: stub Shakapacker public paths to avoid NoMethodError (join on nil).

Pipeline shows failures from nil public_output_path during configuration setup outside the “generated_assets_dir” block. Add baseline stubs in the top-level before to ensure a sane default for tests that don’t override it.

     before do
       ReactOnRails.instance_variable_set(:@configuration, nil)
+      # Ensure Shakapacker paths are present for tests that don’t stub them.
+      allow(ReactOnRails::PackerUtils).to receive_message_chain("packer.config.public_output_path")
+        .and_return(Pathname.new(File.expand_path("public/packs")))
+      allow(ReactOnRails::PackerUtils).to receive_message_chain("packer.config.public_path")
+        .and_return(Pathname.new(File.expand_path("public")))
     end
spec/react_on_rails/utils_spec.rb (7)

33-43: Remove “without packer enabled” context — it’s no longer valid.
Shakapacker is a hard dependency; PackerUtils.packer won’t be nil. This context causes false failures.

Apply this diff to delete the invalid context:

-    shared_context "without packer enabled" do
-      before do
-        allow(ReactOnRails).to receive_message_chain(:configuration, :generated_assets_dir)
-          .and_return("public/webpack/dev")
-        allow(described_class).to receive(:gem_available?).with("shakapacker").and_return(false)
-      end
-
-      it "does not use packer" do
-        expect(ReactOnRails::PackerUtils.packer).to be_nil
-      end
-    end

45-52: Fix mocks to avoid removed packer_type and dynamic const lookup.
Use Shakapacker constants directly to stop method-missing errors in CI.

Apply this diff:

-    def mock_bundle_in_manifest(bundle_name, hashed_bundle)
-      mock_manifest = instance_double(Object.const_get(ReactOnRails::PackerUtils.packer_type.capitalize)::Manifest)
+    def mock_bundle_in_manifest(bundle_name, hashed_bundle)
+      mock_manifest = instance_double(::Shakapacker::Manifest)
       allow(mock_manifest).to receive(:lookup!)
         .with(bundle_name)
         .and_return(hashed_bundle)
 
       allow(ReactOnRails::PackerUtils.packer).to receive(:manifest).and_return(mock_manifest)
     end

54-60: Fix MissingEntryError reference to use Shakapacker directly.
Prevents failures from missing packer_type.

Apply this diff:

-    def mock_missing_manifest_entry(bundle_name)
-      allow(ReactOnRails::PackerUtils.packer).to receive_message_chain("manifest.lookup!")
-        .with(bundle_name)
-        .and_raise(Object.const_get(
-          ReactOnRails::PackerUtils.packer_type.capitalize
-        )::Manifest::MissingEntryError)
-    end
+    def mock_missing_manifest_entry(bundle_name)
+      allow(ReactOnRails::PackerUtils.packer).to receive_message_chain("manifest.lookup!")
+        .with(bundle_name)
+        .and_raise(::Shakapacker::Manifest::MissingEntryError)
+    end

496-505: Remove stubbing of removed using_packer? and set explicit config for paths.
using_packer? no longer exists; rely on PackerUtils.asset_uri_from_packer and stub config values.

Apply this diff:

       before do
-        allow(ReactOnRails::PackerUtils).to receive(:using_packer?).and_return(true)
         allow(ReactOnRails::PackerUtils.packer).to receive_message_chain("config.public_output_path")
           .and_return(Pathname.new(public_output_path))
         allow(ReactOnRails::PackerUtils.packer).to receive_message_chain("config.public_path")
           .and_return(Pathname.new("/path/to/public"))
       end

507-517: Stop using Object.const_get(...packer_type...) for DevServer double.
Reference Shakapacker::DevServer directly.

Apply this diff:

-          before do
-            allow(ReactOnRails::PackerUtils.packer).to receive(:dev_server).and_return(
-              instance_double(
-                Object.const_get(ReactOnRails::PackerUtils.packer_type.capitalize)::DevServer,
-                running?: true,
-                protocol: "http",
-                host_with_port: "localhost:3035"
-              )
-            )
-          end
+          before do
+            allow(ReactOnRails::PackerUtils.packer).to receive(:dev_server).and_return(
+              instance_double(
+                ::Shakapacker::DevServer,
+                running?: true,
+                protocol: "http",
+                host_with_port: "localhost:3035"
+              )
+            )
+          end

538-544: Remove stubbing of removed using_packer? in “not using packer” branch.
The method no longer exists and is not needed for the file-path branch check here.

Apply this diff:

       before do
-        allow(ReactOnRails::PackerUtils).to receive(:using_packer?).and_return(false)
         allow(described_class).to receive(:generated_assets_full_path)
           .and_return("/path/to/generated/assets")
       end

1-644: Remove remaining references to removed packer APIs (packer_type, using_packer?)

rg shows leftover usages — update or remove them to stop CI failures:

  • spec/react_on_rails/utils_spec.rb — ReactOnRails::PackerUtils.packer_type, packers_to_test loop, stubs of using_packer? and using_packer_source_path_is_not_defined_and_custom_node_modules?. Update tests to target ::Shakapacker or remove the removed abstractions (occurrences around lines ~46, ~58, ~105, ~147, ~165, ~169–170, ~233, ~500–511).
  • lib/react_on_rails/utils.rb — using_packer_source_path_is_not_defined_and_custom_node_modules? (def at ~line 161). Remove/rename or adapt to the new API.
  • lib/react_on_rails/test_helper.rb — call to Utils.using_packer_source_path_is_not_defined_and_custom_node_modules? (around line ~89). Update or remove the warning logic.
  • lib/react_on_rails/configuration.rb — error_if_using_packer_and_generated_assets_dir_not_match_public_output_path (around line ~236). Remove/rename any packer-specific checks.
  • spec/react_on_rails/configuration_spec.rb — let(:using_packer) test helper; update accordingly.
  • rakelib/run_rspec.rake and rakelib/example_type.rb — packer_type usage for example tasks; migrate to the new naming/behaviour.

After making changes, run a repo-wide search for "packer_type" and "using_packer" to confirm no matches remain and re-run CI.

lib/react_on_rails/configuration.rb (1)

239-254: Guard for nil/misconfigured public_output_path to fix CI failures.
Current code can blow up if Shakapacker.config isn’t initialized under test.

Apply this diff:

     def error_if_using_packer_and_generated_assets_dir_not_match_public_output_path
       return if generated_assets_dir.blank?
 
-      packer_public_output_path = ReactOnRails::PackerUtils.packer_public_output_path
+      packer_public_output_path = begin
+        ReactOnRails::PackerUtils.packer_public_output_path
+      rescue StandardError
+        nil
+      end
+      return Rails.logger.warn("ReactOnRails: Skipping generated_assets_dir vs public_output_path check; Shakapacker config not initialized.") if packer_public_output_path.nil? || packer_public_output_path.to_s.empty?
 
       if File.expand_path(generated_assets_dir) == packer_public_output_path.to_s
         Rails.logger.warn("You specified generated_assets_dir in `config/initializers/react_on_rails.rb` " \
                           "with shakapacker. " \
                           "Remove this line from your configuration file.")
       else
         msg = <<~MSG
           Error configuring /config/initializers/react_on_rails.rb: You are using shakapacker
           and your specified value for generated_assets_dir = #{generated_assets_dir}
           that does not match the value for public_output_path specified in
-          shakapacker.yml = #{packer_public_output_path}. You should remove the configuration
+          shakapacker.yml = #{packer_public_output_path}. You should remove the configuration
           value for "generated_assets_dir" from your config/initializers/react_on_rails.rb file.
         MSG
         raise ReactOnRails::Error, msg
       end
     end
🧹 Nitpick comments (7)
lib/react_on_rails/test_helper/webpack_assets_compiler.rb (1)

19-21: Typo in user-facing message ("them" → "then").

Minor copy fix.

-            If you wish to use the config/shakapacker.yml compile option for tests
-            them remove your call to the ReactOnRails test helper.
+            If you wish to use the config/shakapacker.yml compile option for tests
+            then remove your call to the ReactOnRails test helper.
spec/react_on_rails/configuration_spec.rb (1)

314-316: OK to stub version/features; consider stubbing supports_ predicates directly.*

You can stub PackerUtils.supports_auto_registration? (and supports_async_loading? elsewhere) instead of internal helpers to better mirror current public API. Not required, but makes intent clearer.

spec/react_on_rails/utils_spec.rb (1)

485-549: Add a spec helper to ensure Shakapacker config values exist during these tests.
Some failures come from nil public_output_path/public_path. Consider centralizing stubs.

Apply this helper to the spec (or a shared helper):

+    def stub_shakapacker_paths(public_path:, public_output_path:)
+      allow(ReactOnRails::PackerUtils.packer).to receive_message_chain("config.public_path")
+        .and_return(Pathname.new(public_path))
+      allow(ReactOnRails::PackerUtils.packer).to receive_message_chain("config.public_output_path")
+        .and_return(Pathname.new(public_output_path))
+    end

Then call stub_shakapacker_paths in the relevant contexts to reduce duplication and avoid nils.

lib/react_on_rails/packer_utils.rb (2)

67-79: public_output_uri_path/asset_uri_from_packer: OK, but add nil-safety for config.
In some test environments Shakapacker.config.public_path/public_output_path can be nil, causing exceptions.

Apply this defensive tweak:

-    def self.public_output_uri_path
-      "#{packer.config.public_output_path.relative_path_from(packer.config.public_path)}/"
-    end
+    def self.public_output_uri_path
+      public_output = packer.config.public_output_path
+      public_root = packer.config.public_path
+      return "webpack/#{Rails.env}/" if public_output.nil? || public_root.nil?
+      "#{public_output.relative_path_from(public_root)}/"
+    end

This keeps production behavior intact while preventing CI crashes when config isn’t fully initialized.


110-120: Replace strip_heredoc with squiggly heredoc to drop ActiveSupport dependency.
Prevents crashes if ActiveSupport string core_ext isn’t loaded before this file.

Apply this diff:

-    def self.check_manifest_not_cached
-      return unless packer.config.cache_manifest?
-
-      msg = <<-MSG.strip_heredoc
-          ERROR: you have enabled cache_manifest in the #{Rails.env} env when using the
-          ReactOnRails::TestHelper.configure_rspec_to_compile_assets helper
-          To fix this: edit your config/shakapacker.yml file and set cache_manifest to false for test.
-      MSG
+    def self.check_manifest_not_cached
+      return unless packer.config.cache_manifest?
+
+      msg = <<~MSG
+        ERROR: you have enabled cache_manifest in the #{Rails.env} env when using the
+        ReactOnRails::TestHelper.configure_rspec_to_compile_assets helper
+        To fix this: edit your config/shakapacker.yml file and set cache_manifest to false for test.
+      MSG
lib/react_on_rails/configuration.rb (2)

221-223: Update to shakapacker:clean is correct, but confirm task signature.
Older Shakapacker may accept different args. Consider making the versions arg optional to avoid arity issues.

Apply this safe call:

-        Rake::Task["shakapacker:clean"].invoke(versions)
+        Rake::Task["shakapacker:clean"].invoke(*(defined?(versions) ? [versions] : []))

279-287: Handle nil public_output_path in deprecation warning.
Prevents crashes when public_output_path isn’t available in spec envs.

Apply this diff:

-      packer_public_output_path = ReactOnRails::PackerUtils.packer_public_output_path
+      packer_public_output_path = ReactOnRails::PackerUtils.packer_public_output_path rescue ReactOnRails::DEFAULT_GENERATED_ASSETS_DIR
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 233b789 and 30e0e6d.

⛔ Files ignored due to path filters (1)
  • Gemfile.lock is excluded by !**/*.lock
📒 Files selected for processing (16)
  • lib/generators/react_on_rails/base_generator.rb (1 hunks)
  • lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt (1 hunks)
  • lib/react_on_rails/configuration.rb (7 hunks)
  • lib/react_on_rails/packer_utils.rb (4 hunks)
  • lib/react_on_rails/system_checker.rb (1 hunks)
  • lib/react_on_rails/test_helper.rb (1 hunks)
  • lib/react_on_rails/test_helper/webpack_assets_compiler.rb (1 hunks)
  • lib/react_on_rails/test_helper/webpack_assets_status_checker.rb (1 hunks)
  • lib/react_on_rails/utils.rb (4 hunks)
  • spec/dummy/spec/helpers/react_on_rails_helper_spec.rb (1 hunks)
  • spec/dummy/spec/rake/assets_precompile_rake_spec.rb (1 hunks)
  • spec/react_on_rails/configuration_spec.rb (2 hunks)
  • spec/react_on_rails/locales_to_js_spec.rb (0 hunks)
  • spec/react_on_rails/packer_utils_spec.rb (1 hunks)
  • spec/react_on_rails/test_helper/webpack_assets_status_checker_spec.rb (0 hunks)
  • spec/react_on_rails/utils_spec.rb (1 hunks)
💤 Files with no reviewable changes (2)
  • spec/react_on_rails/test_helper/webpack_assets_status_checker_spec.rb
  • spec/react_on_rails/locales_to_js_spec.rb
✅ Files skipped from review due to trivial changes (1)
  • lib/generators/react_on_rails/base_generator.rb
🚧 Files skipped from review as they are similar to previous changes (1)
  • lib/react_on_rails/system_checker.rb
🧰 Additional context used
📓 Path-based instructions (1)
{**/*.rb,**/*.rake,**/*.gemspec,Gemfile,Rakefile}

📄 CodeRabbit inference engine (CLAUDE.md)

Before every commit/push, run bundle exec rubocop and fix all violations; Ruby code must pass RuboCop with zero offenses

Files:

  • lib/react_on_rails/test_helper/webpack_assets_status_checker.rb
  • spec/dummy/spec/rake/assets_precompile_rake_spec.rb
  • spec/react_on_rails/configuration_spec.rb
  • spec/dummy/spec/helpers/react_on_rails_helper_spec.rb
  • lib/react_on_rails/configuration.rb
  • lib/react_on_rails/test_helper/webpack_assets_compiler.rb
  • lib/react_on_rails/packer_utils.rb
  • lib/react_on_rails/test_helper.rb
  • spec/react_on_rails/utils_spec.rb
  • spec/react_on_rails/packer_utils_spec.rb
  • lib/react_on_rails/utils.rb
🧠 Learnings (8)
📚 Learning: 2025-09-16T08:01:11.146Z
Learnt from: justin808
PR: shakacode/react_on_rails#1770
File: lib/generators/react_on_rails/templates/base/base/app/javascript/src/HelloWorld/ror_components/HelloWorld.client.jsx:2-2
Timestamp: 2025-09-16T08:01:11.146Z
Learning: React on Rails uses webpack CSS Modules configuration with namedExports: true, which requires the import syntax `import * as style from './file.module.css'` rather than the default export pattern. This configuration enables better tree shaking and bundle size optimization for CSS modules.

Applied to files:

  • lib/react_on_rails/test_helper/webpack_assets_status_checker.rb
  • lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt
  • spec/dummy/spec/rake/assets_precompile_rake_spec.rb
  • spec/dummy/spec/helpers/react_on_rails_helper_spec.rb
  • spec/react_on_rails/utils_spec.rb
📚 Learning: 2025-02-12T16:38:06.537Z
Learnt from: Romex91
PR: shakacode/react_on_rails#1697
File: package-scripts.yml:28-28
Timestamp: 2025-02-12T16:38:06.537Z
Learning: The file `node_package/lib/ReactOnRails.full.js` is autogenerated during the build process and should not be present in the repository.

Applied to files:

  • lib/react_on_rails/test_helper/webpack_assets_status_checker.rb
  • lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt
  • spec/dummy/spec/rake/assets_precompile_rake_spec.rb
  • lib/react_on_rails/test_helper.rb
  • lib/react_on_rails/utils.rb
📚 Learning: 2025-04-26T21:55:55.874Z
Learnt from: alexeyr-ci2
PR: shakacode/react_on_rails#1732
File: spec/dummy/client/app-react16/startup/ReduxSharedStoreApp.client.jsx:40-44
Timestamp: 2025-04-26T21:55:55.874Z
Learning: In the react_on_rails project, files under `app-react16` directories are copied/moved to corresponding `/app` directories during the conversion process (removing the `-react16` suffix), which affects their relative import paths at runtime.

Applied to files:

  • lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt
  • lib/react_on_rails/configuration.rb
  • lib/react_on_rails/test_helper/webpack_assets_compiler.rb
  • lib/react_on_rails/test_helper.rb
  • lib/react_on_rails/utils.rb
📚 Learning: 2025-02-18T13:08:01.477Z
Learnt from: AbanoubGhadban
PR: shakacode/react_on_rails#1644
File: lib/react_on_rails/helper.rb:190-197
Timestamp: 2025-02-18T13:08:01.477Z
Learning: RSC support validation in React on Rails Pro is handled through a chain of validations:
1. Pro version check in `run_stream_inside_fiber`
2. RSC support check during pack generation via `ReactOnRailsPro.configuration.enable_rsc_support`
3. RSC support validation during component registration
This makes additional validation in the helper methods unnecessary.

Applied to files:

  • spec/react_on_rails/configuration_spec.rb
  • spec/dummy/spec/helpers/react_on_rails_helper_spec.rb
  • lib/react_on_rails/configuration.rb
📚 Learning: 2025-02-13T16:50:47.848Z
Learnt from: AbanoubGhadban
PR: shakacode/react_on_rails#1644
File: node_package/src/clientStartup.ts:18-21
Timestamp: 2025-02-13T16:50:47.848Z
Learning: In the react_on_rails module, the `reactOnRailsPageUnloaded` function in clientStartup.ts is intentionally kept private as it's only used internally as a callback for `onPageUnloaded`.

Applied to files:

  • spec/dummy/spec/helpers/react_on_rails_helper_spec.rb
📚 Learning: 2024-12-12T13:07:09.929Z
Learnt from: alexeyr-ci
PR: shakacode/react_on_rails#1644
File: node_package/src/ReactOnRailsRSC.ts:87-87
Timestamp: 2024-12-12T13:07:09.929Z
Learning: When handling errors in 'node_package/src/ReactOnRailsRSC.ts', include the error stack in error messages in development and test environments to aid debugging.

Applied to files:

  • lib/react_on_rails/test_helper/webpack_assets_compiler.rb
📚 Learning: 2025-02-13T14:29:49.267Z
Learnt from: AbanoubGhadban
PR: shakacode/react_on_rails#1644
File: spec/react_on_rails/utils_spec.rb:218-218
Timestamp: 2025-02-13T14:29:49.267Z
Learning: In RSpec tests, prefer using local variables over constants within test blocks to avoid constant redefinition warnings and maintain better test isolation.

Applied to files:

  • spec/react_on_rails/packer_utils_spec.rb
📚 Learning: 2025-04-09T12:56:10.756Z
Learnt from: AbanoubGhadban
PR: shakacode/react_on_rails#1696
File: node_package/src/RSCPayloadContainer.ts:0-0
Timestamp: 2025-04-09T12:56:10.756Z
Learning: In the react_on_rails codebase, RSC payloads are already stringified using `JSON.stringify()` before being processed by the `escapeScript` function, which handles escaping of special characters. The function only needs to handle specific HTML markers like comments and closing script tags.

Applied to files:

  • lib/react_on_rails/utils.rb
🧬 Code graph analysis (7)
lib/react_on_rails/test_helper/webpack_assets_status_checker.rb (1)
lib/react_on_rails/packer_utils.rb (1)
  • manifest_exists? (102-104)
spec/react_on_rails/configuration_spec.rb (2)
spec/dummy/config/webpack/commonWebpackConfig.js (1)
  • require (2-2)
spec/dummy/config/webpack/webpack.config.js (3)
  • require (1-1)
  • require (3-3)
  • require (4-4)
lib/react_on_rails/configuration.rb (1)
lib/react_on_rails/packer_utils.rb (3)
  • supports_async_loading? (37-39)
  • supports_auto_registration? (41-44)
  • packer_public_output_path (98-100)
lib/react_on_rails/test_helper.rb (1)
lib/react_on_rails/utils.rb (1)
  • using_packer_source_path_is_not_defined_and_custom_node_modules? (161-164)
spec/react_on_rails/utils_spec.rb (4)
spec/dummy/config/webpack/development.js (1)
  • require (3-3)
spec/dummy/config/webpack/commonWebpackConfig.js (1)
  • require (2-2)
spec/dummy/config/webpack/serverWebpackConfig.js (1)
  • require (1-1)
spec/dummy/config/webpack/webpack.config.js (3)
  • require (1-1)
  • require (3-3)
  • require (4-4)
spec/react_on_rails/packer_utils_spec.rb (1)
lib/react_on_rails/packer_utils.rb (2)
  • supports_async_loading? (37-39)
  • supports_auto_registration? (41-44)
lib/react_on_rails/utils.rb (2)
lib/react_on_rails/packer_utils.rb (5)
  • bundle_js_uri_from_packer (49-65)
  • asset_uri_from_packer (74-80)
  • packer_source_path (86-88)
  • packer_source_path_explicit? (106-108)
  • packer_public_output_path (98-100)
lib/react_on_rails/configuration.rb (1)
  • configuration (16-57)
🪛 GitHub Actions: Generator tests
lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt

[error] 1-1: Error configuring ReactOnRails: You are using shakapacker and your generated_assets_dir (public/webpack/development) does not match the public_output_path specified in shakapacker.yml (public/packs). Remove the generated_assets_dir setting from your initializer.

🪛 GitHub Actions: Rspec test for gem
spec/react_on_rails/configuration_spec.rb

[error] 285-285: RSpec failure: ReactOnRails::Configuration#setup_config_values triggered NoMethodError (join on nil) when validating prerender/public output path integration with Shakapacker.


[error] 318-318: RSpec failure: configuration_spec.rb: 'has default values for RSC options' failing due to nil public_output_path in Shakapacker integration.

lib/react_on_rails/configuration.rb

[error] 1-1: ReactOnRails configuration error: error_if_using_packer_and_generated_assets_dir_not_match_public_output_path failed due to nil public_output_path (packer/public output path validation with Shakapacker).

lib/react_on_rails/packer_utils.rb

[error] 99-99: ReactOnRails::PackerUtils.packer_public_output_path raised NoMethodError: undefined method 'join' for nil (likely due to missing public_output_path).

spec/react_on_rails/utils_spec.rb

[error] 46-46: ReactOnRails::PackerUtils.packer_type undefined (method missing) in tests mocking: using_packer? not implemented.


[error] 500-500: Mocking error: ReactOnRails::PackerUtils.packer_type undefined; attempting to mock using_packer? failing.

🪛 GitHub Actions: Lint JS and Ruby
spec/react_on_rails/packer_utils_spec.rb

[error] 95-95: RSpec/VerifiedDoubles: Prefer using verifying doubles over normal doubles.


[error] 96-96: RSpec/VerifiedDoubles: Prefer using verifying doubles over normal doubles.

🔇 Additional comments (27)
lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt (2)

28-28: LGTM: switch to bin/shakapacker for test builds.

Matches the project-wide Shakapacker-first approach and new version gating.


27-29: Incorrect — generator template no longer sets config.generated_assets_dir.
No matches in lib/generators; generated_assets_dir is validated/handled in lib/react_on_rails/configuration.rb.

Likely an incorrect or invalid review comment.

lib/react_on_rails/test_helper/webpack_assets_status_checker.rb (1)

34-36: LGTM: simplify manifest guard.

Dropping the extra “using_packer?” check is fine; manifest presence alone is the correct signal.

lib/react_on_rails/test_helper.rb (1)

89-96: LGTM: correct reference to config/shakapacker.yml and simplified guard.

Message now correctly points users to Shakapacker’s config; condition is consistent with the Shakapacker‑first stance.

spec/dummy/spec/helpers/react_on_rails_helper_spec.rb (1)

13-13: LGTM: include Shakapacker::Helper.

Aligns the helper spec with Shakapacker APIs used in expectations.

spec/react_on_rails/configuration_spec.rb (1)

4-4: LGTM: explicitly require 'shakapacker'.

Prevents missing-constant issues during spec runs.

spec/react_on_rails/packer_utils_spec.rb (2)

80-92: LGTM: async-loading feature gate tests.

Covers both sides of the 8.2.0 threshold.


102-121: LGTM: auto-registration feature gate tests.

Good coverage for version and capability (nested_entries?) checks.

spec/react_on_rails/utils_spec.rb (4)

4-4: Good: explicitly require Shakapacker in the spec.
Aligns with v15+ dependency and simplifies test setup.


27-31: Good: assert packer equals ::Shakapacker.
This matches the new PackerUtils.packer behavior.


140-167: LGTM: updated predicate name and packer.config data access.
Behavior matches the new Utils implementation.


202-214: Expectations look correct with new URI/file-path rules.
These cover both dev-server and file path branches.

Also applies to: 217-230, 250-277, 280-293

lib/react_on_rails/utils.rb (4)

81-86: Special-case manifest.json: correct and safer.
Directly targets the non-hashed manifest path; matches Shakapacker expectations.


87-95: Rescue specific Shakapacker missing entry error.
Good switch to a concrete exception; ensures correct fallback path.


112-117: Simplify react_client_manifest_file_path via asset_uri_from_packer.
Aligns with dev-server vs file-path behavior; good.


157-168: Unconditional Shakapacker-based paths: consistent with new model.
source_path and generated_assets_full_path now correctly proxy to PackerUtils.

lib/react_on_rails/packer_utils.rb (5)

18-22: Cache shakapacker_version via Gem.loaded_specs: good.
Avoids extra guards and aligns with dependency assumption.


37-44: Feature predicates are clear and version-gated.
These map the PR objectives precisely (>=8.2.0 for async, >=7.0.0 + nested_entries? for auto-registration).


82-85: precompile? switch to Shakapacker flag: good.
Matches new configuration semantics.


134-162: Errors and guidance reference Shakapacker correctly.
Copy updates and links look right.


98-101: Potential root cause for CI “join for nil”: missing public_path/output_path in tests.
If we don’t add the nil-safety above, ensure specs stub both config.public_path and config.public_output_path before calling these APIs.

Use the helper suggested in the spec review to stub these consistently.

lib/react_on_rails/configuration.rb (6)

177-190: Async loading strategy gating uses feature predicate: good.
Error/warn/defaults align with supports_async_loading?.


201-204: Autobundling requirement check uses supports_auto_registration?: good.
Matches PR objective and removes hard version coupling elsewhere.


320-327: Compile command conflict message updated to Shakapacker: good.
Clear guidance for users on shakapacker_precompile.


269-274: Default generated_assets_dir path logic: good.
Appropriate default when not explicitly set.


136-149: Order of setup calls puts validations before path checks: good.
Keeps errors actionable.


1-333: Repo-wide leftover references check — no removed-API usages found

  • No matches for the removed APIs using_packer? or using_shakapacker_const?.
  • packer_type appears only in tests and rake helpers (e.g. spec/react_on_rails/utils_spec.rb, spec/react_on_rails/packer_utils_spec.rb, rakelib/example_type.rb) — expected.
  • webpacker occurrences are limited to docs/outdated files and a Webpacker-detection guard (lib/react_on_rails/doctor.rb) — not active runtime code.
  • Conclusion: no actionable leftover removed-API usage found that would explain CI failures; attach the failing CI log if errors persist.

Comment on lines 17 to +18
config.build_production_command = "RAILS_ENV=production NODE_ENV=production /
bin/#{ReactOnRails::PackerUtils.packer_type}"
bin/shakapacker"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix broken shell command literal (newline + stray slash).

The build command spans lines and includes a literal "/". If executed, this will fail. Use a single-line string.

-      config.build_production_command = "RAILS_ENV=production NODE_ENV=production /
-      bin/shakapacker"
+      config.build_production_command = "RAILS_ENV=production NODE_ENV=production bin/shakapacker"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
config.build_production_command = "RAILS_ENV=production NODE_ENV=production /
bin/#{ReactOnRails::PackerUtils.packer_type}"
bin/shakapacker"
config.build_production_command = "RAILS_ENV=production NODE_ENV=production bin/shakapacker"
🤖 Prompt for AI Agents
In spec/dummy/spec/rake/assets_precompile_rake_spec.rb around lines 17 to 18,
the build_production_command string is broken across lines and contains a stray
"/" causing an invalid shell command; change it to a single-line string
containing the full command "RAILS_ENV=production NODE_ENV=production
bin/shakapacker" (remove the newline and slash) so the command executes
correctly.

Comment on lines 95 to 101
let(:mock_config) { double("MockConfig") }
let(:mock_packer) { double("MockPacker", config: mock_config) }

before do
allow(described_class).to receive(:packer).and_return(mock_packer)
end

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix RuboCop RSpec/VerifiedDoubles offenses (use verifying doubles).

Replace generic doubles with verifying doubles and avoid a verifying-double for the packer by using a simple Struct.

-      let(:mock_config) { double("MockConfig") }
-      let(:mock_packer) { double("MockPacker", config: mock_config) }
+      let(:mock_config) { instance_double(Shakapacker::Configuration) }
+      let(:mock_packer) { Struct.new(:config).new(mock_config) }

Also ensure Shakapacker constants are loaded at the top of this spec file:

# at file top
require "shakapacker"
🧰 Tools
🪛 GitHub Actions: Lint JS and Ruby

[error] 95-95: RSpec/VerifiedDoubles: Prefer using verifying doubles over normal doubles.


[error] 96-96: RSpec/VerifiedDoubles: Prefer using verifying doubles over normal doubles.

🤖 Prompt for AI Agents
In spec/react_on_rails/packer_utils_spec.rb around lines 95 to 101, replace the
generic doubles with verifying doubles and use a simple Struct for the packer:
change mock_config to an instance_double (or class-appropriate verifying double)
for the actual config class used in production, create mock_packer as a plain
Struct (or OpenStruct) that responds to :config returning the verifying double,
and update the before block to stub described_class.packer to return that
Struct; also add require "shakapacker" at the top of the spec file to ensure
Shakapacker constants are loaded.

justin808 and others added 2 commits September 21, 2025 13:31
Two tests were missing the required packer.config.public_output_path
mocking, causing nil errors during configuration setup.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
…packer

The configuration was automatically setting generated_assets_dir to a default
value that didn't match Shakapacker's public_output_path, causing validation
errors in CI and example apps.

Since Shakapacker manages its own public_output_path configuration, we should
not set a default generated_assets_dir when using Shakapacker. This prevents
path mismatches and allows proper Shakapacker configuration.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai coderabbitai bot requested a review from alexeyr-ci September 22, 2025 00:18
@claude
Copy link

claude bot commented Sep 22, 2025

Code Review for PR #1801

Overall Assessment

This PR successfully addresses the artificial Shakapacker version requirement issue by introducing a clean separation between basic compatibility (8.0.0) and feature-specific requirements. The approach is well-thought-out and maintains backward compatibility.

Strengths

  • Clear separation of concerns with new feature detection methods
  • Comprehensive test coverage for all scenarios
  • Maintains backward compatibility while fixing the breaking change
  • Good documentation in PR description

Issues to Address

  1. Incomplete feature detection: The supports_auto_registration? method only checks if nested_entries? method exists, not if it's enabled. Should also verify packer.config.nested_entries? returns true.

  2. Misleading warning message: system_checker.rb line 628 says "Version 7.0+ needed" but auto-registration needs both version 7.0+ AND nested_entries support.

  3. Unused code: Lines 621-622 in system_checker.rb create Gem::Version objects but don't use them - appears to be leftover from refactoring.

Minor Issues

  • Double space typo in configuration.rb line 179
  • Consider extracting version constants to avoid hardcoding
  • Add test for when nested_entries? exists but returns false

CI Status

Test failures in Ruby 3.2 and 3.4 with "latest" configuration need investigation before merging.

Recommendation

Approve with fixes. Once the issues above are addressed (particularly the incomplete feature detection and CI failures), this PR is ready to merge. The core approach is solid and solves a real problem for users with older Shakapacker versions.

Suggested Follow-up

  • Add a CHANGELOG entry documenting this important compatibility fix
  • Consider adding a migration guide for users upgrading with various Shakapacker versions

Great work on this important compatibility fix!

- Cache version requirement checks to avoid repeated Gem::Version comparisons
- Add comprehensive tests for version constants validation
- Ensure logical consistency between MINIMUM_SHAKAPACKER_VERSION constants
- Add test for caching behavior verification
- Update CHANGELOG to document new constants and performance improvements

Performance: Version checks are now cached, reducing redundant Gem::Version object creation
Reliability: Tests ensure version constants remain properly aligned
Documentation: Clear explanation of why shakapacker_gem_available? checks were removed

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@claude
Copy link

claude bot commented Sep 23, 2025

Code Review for PR #1801: Fix Shakapacker Version Requirements

Overall Assessment: ✅ APPROVED

This PR successfully addresses the Docker build failures while significantly improving code quality through the removal of legacy abstractions and introduction of feature-specific version detection.

🎯 Key Strengths

  1. Effective Problem Resolution: Fixes the 'Don't know how to build task :clean' error by removing the artificial Shakapacker 8.2.0 requirement for basic functionality.

  2. Feature-Specific Version Detection: Excellent introduction of three targeted support methods:

    • supports_basic_pack_generation? (6.5.1+)
    • supports_auto_registration? (7.0.0+)
    • supports_async_loading? (8.2.0+)
  3. Code Simplification: Removal of legacy Webpacker compatibility layers (using_packer?, packer_type, etc.) significantly reduces complexity and improves maintainability.

  4. Comprehensive Test Coverage: Added 92+ lines of well-structured tests covering all new methods with proper boundary testing and mocking.

  5. Graceful Degradation: Shows helpful warnings instead of fatal errors for missing advanced features, improving user experience.

📋 Code Quality Observations

Positive Aspects

  • Clean API design with clear method names that express intent
  • Proper use of semantic versioning with Gem::Version comparisons
  • Excellent documentation including feature compatibility matrix
  • Type-safe testing with instance_double instead of generic doubles
  • Consistent error messaging throughout the codebase

Minor Suggestions

  1. Consider centralizing version constants: MINIMUM_SHAKAPACKER_VERSION_FOR_AUTO_REGISTRATION could be moved from PacksGenerator to a more central location like PackerUtils for better organization.

  2. Documentation consistency: The PR description mentions '8.0.0' as the basic requirement but the code correctly uses '6.5.1'. Consider updating the PR description for accuracy.

  3. Error handling in packer method: The new implementation directly requires 'shakapacker' - while this aligns with the simplified approach, consider if a more graceful error message would help users with incomplete installations.

✅ Adherence to CLAUDE.md Guidelines

  • RuboCop compliance: Changes follow Ruby style guidelines
  • File formatting: All files end with proper newlines
  • No manual formatting: Code follows automated formatter patterns
  • Test coverage: Comprehensive RSpec tests added

🔒 Security & Performance

  • No security concerns identified in the changes
  • Performance neutral: Version checking is cached appropriately
  • No credential exposure or sensitive data handling issues

💡 Impact Analysis

This PR delivers significant value:

  • Immediate fix for Docker build failures affecting users on Shakapacker < 8.2.0
  • Improved developer experience with clearer error messages and upgrade guidance
  • Reduced technical debt through removal of legacy abstractions
  • Better maintainability with feature-specific version detection

Conclusion

This is a well-crafted PR that not only fixes the immediate issue but also improves the overall codebase architecture. The implementation is robust, well-tested, and maintains backward compatibility while providing clear upgrade paths. The code simplification alone makes this a valuable contribution.

Great work on this fix! 🎉


Reviewed with focus on: code quality, potential bugs, performance, security, test coverage, and adherence to project conventions (CLAUDE.md)

@claude
Copy link

claude bot commented Sep 23, 2025

Code Review for PR #1801: Fix Shakapacker version requirement

Overall Assessment

This PR addresses an important compatibility issue by properly separating basic Shakapacker functionality from advanced features. The changes significantly improve backward compatibility and simplify the codebase. However, there are several areas that need attention.

Strengths ✅

  1. Proper Feature Detection: Excellent separation of concerns with feature-specific methods (supports_async_loading, supports_basic_pack_generation, supports_auto_registration)

  2. Improved Error Messages: Clear, actionable error messages that guide users on what to do.

  3. Performance Optimization: Good addition of caching for version checks to avoid redundant comparisons.

  4. Code Simplification: Successfully removed legacy abstraction layers that were adding unnecessary complexity.

  5. Documentation: Comprehensive feature compatibility matrix in configuration.md clearly shows which features are available in each Shakapacker version.

Issues to Address 🔍

1. Critical: Missing Shakapacker Initialization Protection

In lib/react_on_rails/packer_utils.rb, the packer method raises an error if Shakapacker is not available, but many methods call it without protection (e.g., dev_server_running).

Recommendation: Add guards or ensure Shakapacker is always available when these methods are called.

2. Version Check Caching Logic

The caching implementation in shakapacker_version_requirement_met could be clearer and more testable.

3. Inconsistent Error Handling

The bundle_js_file_path method in utils.rb catches MissingEntryError but doesn't handle the case where Shakapacker itself might not be loaded.

4. Test Coverage Gaps

  • Missing tests for the new supports_* methods
  • No test coverage for the caching mechanism
  • Missing edge cases for version comparison failures

5. Configuration Warning Logic

The warning in configuration.rb:211 will appear on every Rails boot, which could be noisy. Consider showing it only once or making it configurable.

Recommendations 🚀

  1. Add Initialization Check: Create a method to verify Shakapacker is properly initialized before use

  2. Improve Version Caching: Make the caching more explicit with a clear_version_cache method for testing

  3. Add Comprehensive Tests for edge cases, version comparison, and caching

  4. Consider Feature Flags: Instead of version checks everywhere, use a feature flag approach set once during initialization

Security Considerations 🔒

No security issues identified in this change.

Performance Considerations ⚡

  • Good addition of caching for version checks
  • Consider caching the packer instance more aggressively to avoid repeated requires

Summary ✅

This PR makes important improvements to Shakapacker compatibility. The main concerns are around error handling when Shakapacker is not available and test coverage for the new methods. Once these issues are addressed, this will be a solid improvement to the codebase.

Verdict: Approved with suggestions - please address the critical initialization protection issue and consider adding more comprehensive test coverage.

- Replace defined?(@Packer) pattern with thread-safe @Packer ||= approach
- Remove unnecessary LoadError handling since Shakapacker is required in gemspec
- Fix RuboCop line length violations
- Extract long constant names to variables for readability

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@claude
Copy link

claude bot commented Sep 23, 2025

🔍 Code Review for PR #1801: Fix Shakapacker Version Requirements

✅ Overall Assessment

This PR successfully addresses the critical issue of overly restrictive Shakapacker version requirements that was causing build failures. The refactoring significantly improves code clarity, maintainability, and backward compatibility. This is a well-thought-out fix that properly separates feature requirements.

🎯 Strengths

  1. Clear Feature Separation: The introduction of feature-specific detection methods (supports_async_loading?, supports_basic_pack_generation?, supports_auto_registration?) provides excellent clarity about which features require which versions.

  2. Improved Backward Compatibility: The PR properly supports Shakapacker 6.5.1+ for basic functionality while gracefully degrading for advanced features.

  3. Better Error Messages: Error messages have been improved to be more specific and actionable, helping users understand exactly what they need to upgrade and why.

  4. Performance Optimization: The addition of caching for version checks (@version_checks hash) is a nice touch that prevents redundant version comparisons.

  5. Code Simplification: Removal of legacy abstractions (using_packer?, packer_type) reduces unnecessary indirection and makes the code more maintainable.

  6. Documentation: The feature compatibility matrix in the configuration documentation is excellent and provides clear guidance to users.

🔔 Potential Issues & Suggestions

1. Missing Shakapacker Dependency Check

The packer method now directly requires and returns Shakapacker without checking if it's available:

def self.packer
  @packer ||= begin
    require "shakapacker"
    ::Shakapacker
  end
end

Risk: Could raise LoadError if Shakapacker is not installed.
Suggestion: Consider adding error handling or a check for gem availability.

2. Version Caching Edge Case

The version caching implementation could have issues if the Shakapacker version changes during runtime (e.g., in development with bundle updates):

def self.shakapacker_version_requirement_met?(required_version)
  @version_checks ||= {}
  @version_checks[required_version] ||= Gem::Version.new(shakapacker_version) >= Gem::Version.new(required_version)
end

Suggestion: Consider clearing the cache when the version changes or in development mode.

3. Incomplete CHANGELOG Entry

The CHANGELOG mentions PR 1798 instead of the current PR 1801. This appears to be a mistake that should be corrected.

4. Test Coverage Gaps

While the PR adds good test coverage for the new methods, consider adding:

  • Edge case tests for version parsing failures
  • Tests for the caching mechanism
  • Integration tests for the warning messages

💡 Recommendations

  1. Add Safeguards: Consider adding a rescue block in the packer method to provide a helpful error message if Shakapacker is not installed.

  2. Version Constants: Consider defining the version thresholds as named constants at the module level for better maintainability:

    ASYNC_LOADING_MIN_VERSION = "8.2.0"
    AUTO_REGISTRATION_MIN_VERSION = "7.0.0"
    BASIC_PACK_MIN_VERSION = "6.5.1"
  3. Warning Frequency: The warning about missing advanced features might be logged too frequently. Consider adding a flag to show it only once per session.

🔒 Security Considerations

No security issues identified. The PR properly avoids exposing sensitive information and maintains secure coding practices.

⚡ Performance Impact

The performance improvements from caching version checks are beneficial. The removal of redundant abstraction layers should also provide minor performance gains.

✅ Test Status

The PR includes appropriate test coverage for the new functionality. All changes to specs properly mock Shakapacker to avoid dependencies during testing.

🎬 Conclusion

This is a solid PR that effectively fixes the critical Docker build issue while improving the overall code quality. The refactoring from rigid version checking to feature-based detection is a significant architectural improvement. With the minor adjustments suggested above (particularly the Shakapacker availability check and CHANGELOG correction), this PR is ready for merge.

Recommendation: Approve with minor changes

The benefits of this fix far outweigh the minor issues identified, and it successfully unblocks users who were stuck on older Shakapacker versions.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (7)
lib/react_on_rails/configuration.rb (4)

183-191: Tighten message copy and spacing; keep behavior.
Minor wording/spacing nits in the async support warning/error.

Apply:

-        ReactOnRails: Your current version of shakapacker \
-        does not support async script loading,  which may cause performance issues. Please either:
+        ReactOnRails: Your current Shakapacker version does not support async script loading, which may impact performance. Please either:

201-213: Good: capability‑gated checks for autobundling vs. advanced features.
Clear separation of basic generation vs. auto‑registration. Consider aligning the warning copy with docs link for discoverability.

Proposed tweak:

-        Rails.logger.warn("React on Rails: Basic pack generation enabled. " \
-                          "Upgrade to Shakapacker #{min_version}+ for advanced auto-registration features.")
+        Rails.logger.warn("React on Rails: Basic pack generation enabled. Upgrade to Shakapacker " \
+                          "#{min_version}+ for auto-registration. See: " \
+                          "https://www.shakacode.com/react-on-rails/docs/guides/file-system-based-automated-bundle-generation/")

231-233: Prefer Rails.logger to puts for library output.
Keeps output consistent and testable.

-        puts "Invoking task shakapacker:clean from React on Rails"
+        Rails.logger.info("Invoking task shakapacker:clean from React on Rails")

253-263: Nice improvement to the mismatch error; suggest including expanded paths.
Small UX boost for troubleshooting.

-          Your generated_assets_dir setting (#{generated_assets_dir}) doesn't match
-          Shakapacker's public_output_path (#{packer_public_output_path}).
+          Your generated_assets_dir setting:
+            #{File.expand_path(generated_assets_dir)}
+          doesn't match Shakapacker's public_output_path:
+            #{File.expand_path(packer_public_output_path)}
lib/react_on_rails/packer_utils.rb (3)

6-9: Rescue LoadError and raise a gem‑specific error.
Current require will raise a raw LoadError; surface a consistent ReactOnRails error.

-      @packer ||= begin
-        require "shakapacker"
-        ::Shakapacker
-      end
+      @packer ||= begin
+        require "shakapacker"
+        ::Shakapacker
+      rescue LoadError
+        raise_shakapacker_not_installed
+      end

20-24: Guard shakapacker_version when the gem isn’t loaded.
Avoid NoMethodError on nil.version; reuse the same friendly error path.

-      @shakapacker_version = Gem.loaded_specs["shakapacker"].version.to_s
+      spec = Gem.loaded_specs["shakapacker"]
+      return raise_shakapacker_not_installed unless spec
+      @shakapacker_version = spec.version.to_s

142-148: Polish error copy (capitalization/punctuation).
Minor grammar nits.

-    **ERROR** ReactOnRails: `nested_entries` is configured to be disabled in shakapacker. Please update \
-    config/shakapacker.yml to enable nested entries. for more information read
+    **ERROR** ReactOnRails: `nested_entries` is disabled in Shakapacker. Please update \
+    config/shakapacker.yml to enable nested entries. For more information, see
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a575302 and 67210ef.

📒 Files selected for processing (5)
  • CHANGELOG.md (1 hunks)
  • docs/guides/configuration.md (2 hunks)
  • lib/react_on_rails/configuration.rb (6 hunks)
  • lib/react_on_rails/packer_utils.rb (5 hunks)
  • spec/react_on_rails/packer_utils_spec.rb (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • CHANGELOG.md
  • docs/guides/configuration.md
🧰 Additional context used
📓 Path-based instructions (2)
{Gemfile,Rakefile,**/*.{rb,rake,gemspec,ru}}

📄 CodeRabbit inference engine (CLAUDE.md)

{Gemfile,Rakefile,**/*.{rb,rake,gemspec,ru}}: Before every commit/push, run bundle exec rubocop and fix all violations in Ruby code
Let RuboCop handle all Ruby code formatting; never manually format Ruby files

Files:

  • spec/react_on_rails/packer_utils_spec.rb
  • lib/react_on_rails/configuration.rb
  • lib/react_on_rails/packer_utils.rb
{Gemfile,Rakefile,**/*.{rb,rake,gemspec,ru,js,jsx,ts,tsx,json,yml,yaml,md,css,scss}}

📄 CodeRabbit inference engine (CLAUDE.md)

Ensure all committed files end with a trailing newline character

Files:

  • spec/react_on_rails/packer_utils_spec.rb
  • lib/react_on_rails/configuration.rb
  • lib/react_on_rails/packer_utils.rb
🧠 Learnings (4)
📚 Learning: 2025-02-13T14:29:49.267Z
Learnt from: AbanoubGhadban
PR: shakacode/react_on_rails#1644
File: spec/react_on_rails/utils_spec.rb:218-218
Timestamp: 2025-02-13T14:29:49.267Z
Learning: In RSpec tests, prefer using local variables over constants within test blocks to avoid constant redefinition warnings and maintain better test isolation.

Applied to files:

  • spec/react_on_rails/packer_utils_spec.rb
📚 Learning: 2025-02-18T13:08:01.477Z
Learnt from: AbanoubGhadban
PR: shakacode/react_on_rails#1644
File: lib/react_on_rails/helper.rb:190-197
Timestamp: 2025-02-18T13:08:01.477Z
Learning: RSC support validation in React on Rails Pro is handled through a chain of validations:
1. Pro version check in `run_stream_inside_fiber`
2. RSC support check during pack generation via `ReactOnRailsPro.configuration.enable_rsc_support`
3. RSC support validation during component registration
This makes additional validation in the helper methods unnecessary.

Applied to files:

  • spec/react_on_rails/packer_utils_spec.rb
  • lib/react_on_rails/packer_utils.rb
📚 Learning: 2025-02-12T16:38:06.537Z
Learnt from: Romex91
PR: shakacode/react_on_rails#1697
File: package-scripts.yml:28-28
Timestamp: 2025-02-12T16:38:06.537Z
Learning: The file `node_package/lib/ReactOnRails.full.js` is autogenerated during the build process and should not be present in the repository.

Applied to files:

  • lib/react_on_rails/configuration.rb
📚 Learning: 2025-04-26T21:55:55.874Z
Learnt from: alexeyr-ci2
PR: shakacode/react_on_rails#1732
File: spec/dummy/client/app-react16/startup/ReduxSharedStoreApp.client.jsx:40-44
Timestamp: 2025-04-26T21:55:55.874Z
Learning: In the react_on_rails project, files under `app-react16` directories are copied/moved to corresponding `/app` directories during the conversion process (removing the `-react16` suffix), which affects their relative import paths at runtime.

Applied to files:

  • lib/react_on_rails/configuration.rb
🧬 Code graph analysis (3)
spec/react_on_rails/packer_utils_spec.rb (1)
lib/react_on_rails/packer_utils.rb (4)
  • supports_async_loading? (40-42)
  • supports_basic_pack_generation? (44-46)
  • supports_auto_registration? (48-51)
  • shakapacker_version_requirement_met? (35-38)
lib/react_on_rails/configuration.rb (1)
lib/react_on_rails/packer_utils.rb (7)
  • supports_async_loading? (40-42)
  • raise_shakapacker_version_incompatible_for_basic_pack_generation (162-169)
  • supports_basic_pack_generation? (44-46)
  • supports_auto_registration? (48-51)
  • raise_nested_entries_disabled (141-149)
  • nested_entries? (101-103)
  • packer_public_output_path (105-107)
lib/react_on_rails/packer_utils.rb (3)
spec/dummy/config/webpack/commonWebpackConfig.js (1)
  • require (2-2)
spec/dummy/config/webpack/webpack.config.js (3)
  • require (1-1)
  • require (3-3)
  • require (4-4)
lib/react_on_rails/engine.rb (1)
  • config (6-17)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: dummy-app-integration-tests (3.4, 22)
  • GitHub Check: dummy-app-integration-tests (3.2, 20)
  • GitHub Check: examples (3.4, latest)
  • GitHub Check: examples (3.2, minimum)
  • GitHub Check: rspec-package-tests (3.4, minimum)
  • GitHub Check: rspec-package-tests (3.2, latest)
  • GitHub Check: rspec-package-tests (3.4, latest)
  • GitHub Check: rspec-package-tests (3.2, minimum)
  • GitHub Check: claude-review
🔇 Additional comments (13)
spec/react_on_rails/packer_utils_spec.rb (5)

80-92: LGTM: async loading capability tests read cleanly.
Covers true/false branches via version predicate stubbing.


94-108: LGTM: basic pack generation capability tests.
Good coupling to the constant-based threshold.


160-172: LGTM: version-check caching behavior.
Asserts memoization without over-specifying internals.


110-117: Fix verifying doubles: wrong constant, and avoid instance_double for a module.

  • Shakapacker config class is likely Shakapacker::Configuration, not Shakapacker::Config.
  • Prefer a simple Struct for the packer rather than instance_double on the Shakapacker module.
  • Require shakapacker so verifying doubles resolve, then remove the rubocop disable comments.

Apply:

@@
-      let(:mock_config) { instance_double("Shakapacker::Config") } # rubocop:disable RSpec/VerifiedDoubleReference
-      let(:mock_packer) { instance_double("Shakapacker", config: mock_config) } # rubocop:disable RSpec/VerifiedDoubleReference
+      let(:mock_config) { instance_double(Shakapacker::Configuration) }
+      let(:mock_packer) { Struct.new(:config).new(mock_config) }
@@
-      before do
-        allow(described_class).to receive(:packer).and_return(mock_packer)
-      end
+      before { allow(described_class).to receive(:packer).and_return(mock_packer) }

And near the top of this file (after spec_helper):

-require_relative "spec_helper"
+require_relative "spec_helper"
+require "shakapacker"

Also applies to: 118-141


144-159: Constants validated — no change required.
Spec expectations ("6.5.1" and "7.0.0") match the definitions in lib/react_on_rails/packs_generator.rb.

lib/react_on_rails/configuration.rb (3)

281-287: LGTM: avoid defaulting generated_assets_dir; defer to Shakapacker.
Warning is appropriate; prevents config drift.


292-297: LGTM: deprecation message references shakapacker.yml and shows current path.
Good clarity for users migrating configs.


330-337: LGTM: conflict message now points to shakapacker.yml and bin/shakapacker.
Accurate guidance.

lib/react_on_rails/packer_utils.rb (5)

35-38: LGTM: memoized version requirement checks.
Simple and effective cache keyed by required version.


40-50: LGTM: capability predicates replace brittle version branching.
Clear thresholds and nested_entries guard.


117-124: LGTM: check_manifest_not_cached now references shakapacker.yml.
Accurate file reference post‑migration.


151-160: LGTM: explicit, actionable version‑incompatibility errors.
Messages provide current version context and thresholds.

Also applies to: 162-169


89-91: Bug: direct Shakapacker constant use can raise NameError; route via packer.
Use the accessor that ensures the gem is loaded.

Apply:

-      ::Shakapacker.config.shakapacker_precompile?
+      packer.config.shakapacker_precompile?

- Update error message to include "does not match the value for public_output_path"
- This ensures the configuration test passes in CI

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@justin808 justin808 requested a review from Copilot September 23, 2025 01:37
@claude
Copy link

claude bot commented Sep 23, 2025

Code Review - PR #1801

Thanks for this important fix addressing the Shakapacker version compatibility issue! I have thoroughly reviewed the changes and have the following feedback:

Positive Aspects

  1. Excellent Problem Resolution: This PR correctly addresses the artificial breaking change that was forcing users to upgrade to Shakapacker 8.2.0 for basic functionality when 8.0.0 is sufficient.

  2. Feature-Specific Detection: The introduction of supports_async_loading? and supports_auto_registration? methods provides clean feature detection, making the code more maintainable and intent clearer.

  3. Significant Code Simplification: Removing legacy Webpacker compatibility code is a great cleanup since the gemspec already requires shakapacker >= 6.0. This eliminates redundant runtime checks and reduces complexity.

  4. Comprehensive Test Coverage: The PR includes thorough test coverage for the new feature detection methods.

🔧 Suggestions for Improvement

1. Test Failures Need Fixing

There appear to be some test failures in configuration_spec.rb where packer mocks are incomplete:

  • Lines 291-304 and 306-321 need proper packer.config.public_output_path mocking
  • Consider extracting shared test setup for consistency

2. Documentation Updates

  • The CHANGELOG.md should clearly document the minimum supported Shakapacker versions for different features:
    • Basic compatibility: 8.0.0+
    • Auto-registration: 7.0.0+
    • Async script loading: 8.2.0+
  • Consider adding migration notes for users upgrading from earlier versions

3. Error Messages Could Be More Helpful

The system_checker.rb warning at line 627 could be more precise:

# Current
add_warning("⚠️  Shakapacker #{version} - Version 7.0+ needed for React on Rails auto-registration")

# Suggested  
add_warning("⚠️  Shakapacker #{version} - Version 7.0+ with nested_entries support needed for React on Rails auto-registration")

4. Method Naming Consistency

Consider renaming supports_auto_registration? to supports_autobundling? since it is used specifically for the autobundling feature in configuration.rb:199.

🐛 Potential Issues

  1. Version Check Logic: The supports_auto_registration? method checks for both version 7.0.0+ AND nested_entries support. However, the error message only mentions the version requirement. This could confuse users who have 7.0.0+ but have not enabled nested_entries.

  2. Missing Validation: In packer_utils.rb, the shakapacker_version method does not handle the case where the shakapacker gem spec might be nil (though unlikely given the gemspec requirement).

📋 Testing Recommendations

  1. Verify the PR works correctly with:

    • Shakapacker 8.0.0 (basic features)
    • Shakapacker 8.1.x (without async loading)
    • Shakapacker 8.2.0+ (with async loading)
  2. Test the upgrade path for existing users on different Shakapacker versions

  3. Ensure Docker builds work correctly with the minimum supported version

Overall Assessment

This is a well-thought-out PR that solves a real pain point for users. The approach of separating basic compatibility from feature-specific requirements is sound. Once the test failures are addressed and documentation is updated, this will be a valuable improvement to React on Rails.

The simplification of the codebase by removing legacy Webpacker support is particularly welcome and makes the code much cleaner and easier to maintain.

Great work on this fix! 👏

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 20 out of 21 changed files in this pull request and generated 2 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +36 to +37
@version_checks ||= {}
@version_checks[required_version] ||= Gem::Version.new(shakapacker_version) >= Gem::Version.new(required_version)
Copy link

Copilot AI Sep 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The @version_checks class variable is not thread-safe. In a multi-threaded environment, concurrent access could lead to race conditions. Consider using a thread-safe alternative like Concurrent::Hash or adding proper synchronization.

Copilot uses AI. Check for mistakes.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link

@claude claude bot Sep 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude finished @justin808's task —— View job


Thread Safety Analysis for @version_checks

I've analyzed the thread safety concern raised about the @version_checks variable on line 37 of lib/react_on_rails/packer_utils.rb.

Todo List:

  • Read the packer_utils.rb file to understand the context
  • Analyze the thread safety implications
  • Provide assessment and recommendation

Analysis

The @version_checks instance variable is used as a cache for version comparisons:

def self.shakapacker_version_requirement_met?(required_version)
  @version_checks ||= {}
  @version_checks[required_version] ||= Gem::Version.new(shakapacker_version) >= Gem::Version.new(required_version)
end

Assessment

This is NOT a real concern in practice for React on Rails. Here's why:

  1. Rails Context: This code runs during Rails initialization and configuration setup, which happens in a single-threaded context before any request handling begins. The version checks are performed during:

    • Rails boot/initialization
    • Configuration validation
    • Asset precompilation
  2. Immutable Data: The cached values are boolean results of version comparisons. Once a version is checked, the result never changes during the application lifecycle since gem versions don't change at runtime.

  3. Read-heavy Pattern: After initialization, this becomes essentially read-only data. Even if multiple threads read simultaneously after initialization, they would all compute the same boolean result.

  4. Worst Case: In the extremely unlikely event of a race condition during initialization (which shouldn't happen in Rails), the worst outcome would be redundant computation of the same boolean value - not data corruption or incorrect results.

Recommendation

No action needed. The current implementation is safe for its intended use in Rails applications. Adding thread synchronization (like Mutex or Concurrent::Hash) would:

  • Add unnecessary complexity
  • Introduce performance overhead
  • Provide no practical benefit given the initialization-time usage pattern

The code is appropriate as-is for the React on Rails gem's architecture and usage patterns.


require_relative "spec_helper"
require ReactOnRails::PackerUtils.packer_type
require "shakapacker"
Copy link

Copilot AI Sep 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Hardcoding the require statement removes the flexibility that the previous dynamic approach provided. If Shakapacker becomes unavailable or needs to be mocked, this could cause test failures. Consider maintaining some level of abstraction for testing purposes.

Suggested change
require "shakapacker"
begin
require "shakapacker"
rescue LoadError
RSpec.describe "Shakapacker dependency" do
it "is required for these tests" do
skip "Shakapacker gem is not available. Skipping tests that require Shakapacker."
end
end
end

Copilot uses AI. Check for mistakes.
@claude
Copy link

claude bot commented Sep 23, 2025

Code Review for PR #1801: Fix Shakapacker version requirement

Thank you for this important fix! I've conducted a thorough review of the changes. Overall, the approach to separate feature detection from basic compatibility is excellent and will help users with gradual upgrades.

✅ Strengths

  1. Clear separation of concerns: The distinction between basic pack generation (6.5.1+), auto-registration (7.0.0+), and async loading (8.2.0+) is well-designed
  2. Backward compatibility: The changes maintain support for older Shakapacker versions while providing clear upgrade paths
  3. Code simplification: Removing legacy abstraction layers improves maintainability
  4. Performance optimization: Version check caching reduces redundant computations
  5. Comprehensive test coverage: Updated tests properly validate the new feature detection methods

🔍 Areas for Improvement

1. Potential nil reference in packer method

In lib/react_on_rails/packer_utils.rb, the packer method could raise LoadError if Shakapacker isn't installed. Consider adding error handling to provide a clearer error message.

2. Configuration validation timing

The ensure_generated_assets_dir_present method now doesn't set a default when using Shakapacker, but the warning message could be misleading if Shakapacker isn't properly configured. Consider checking if packer_public_output_path exists before assuming it will handle the path.

3. Version constant naming

Consider renaming MINIMUM_SHAKAPACKER_VERSION_FOR_AUTO_REGISTRATION to MINIMUM_SHAKAPACKER_VERSION_WITH_NESTED_ENTRIES for clarity, as that's what it actually represents.

4. Test double usage

Good job fixing the RuboCop issues with verified doubles! The use of instance_double throughout improves test reliability.

🎯 Suggestions

  1. Documentation enhancement: Consider adding a migration guide for users upgrading from older Shakapacker versions
  2. Deprecation warnings: For methods that will be removed in future versions, add deprecation warnings to help users prepare
  3. Feature matrix validation: Add a startup check that validates the feature matrix against the installed Shakapacker version and warns about unavailable features

✅ Security & Performance

  • No security issues identified
  • Performance improvement through version check caching is a nice touch
  • Removal of redundant abstraction layers should improve runtime performance

📝 Minor Issues

  1. CHANGELOG entry: The CHANGELOG references PR 1798 but this is PR 1801
  2. Trailing newlines: Ensure all modified files end with a newline per CLAUDE.md requirements
  3. RuboCop compliance: Run bundle exec rubocop before merging to ensure all violations are fixed

✅ Test Coverage

Excellent test coverage for the new methods:

  • supports_async_loading?
  • supports_basic_pack_generation?
  • supports_auto_registration?
  • Version caching validation

🎉 Conclusion

This PR successfully addresses the Docker build failure and improves the codebase. The changes are well-thought-out and maintain backward compatibility while enabling gradual upgrades. With the minor improvements suggested above, this will be a solid enhancement to React on Rails.

Recommendation: ✅ Approve with minor changes

Great work on simplifying the abstraction layers and making the version requirements more granular! 🚀

- Rename supports_auto_registration? to supports_autobundling? for consistency with auto_load_bundle config
- Improve system checker warning message to be more descriptive about nested_entries requirement
- Update all references in tests and configuration files
- Remove redundant ModuleLength disable directive (auto-fixed by RuboCop)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@claude
Copy link

claude bot commented Sep 23, 2025

Code Review for PR #1801: Fix Shakapacker version requirement

Thank you for this important fix that addresses the Docker build failures. I've reviewed the changes and have the following feedback:

✅ Strengths

  1. Clear separation of concerns: The introduction of feature-specific methods (supports_async_loading?, supports_basic_pack_generation?, supports_autobundling?) provides excellent clarity and maintainability.

  2. Backward compatibility: The solution thoughtfully maintains backward compatibility while enabling gradual upgrades, which is crucial for existing users.

  3. Code simplification: Removing legacy abstractions (using_packer?, packer_type) reduces technical debt and improves code readability.

  4. Performance optimization: Caching version checks with @version_checks memoization is a good optimization.

🔍 Areas for Improvement

1. Potential Runtime Error Risk

In lib/react_on_rails/packer_utils.rb:

  • The packer method now uses @packer ||= memoization but doesn't check if Shakapacker is available first
  • Methods like dev_server_running? directly call packer.dev_server without guards
  • Recommendation: Add a check for Shakapacker availability or wrap in a rescue block
def self.packer
  @packer ||= begin
    require "shakapacker"
    ::Shakapacker
  rescue LoadError
    raise ReactOnRails::Error, "Shakapacker gem is required but not installed"
  end
end

2. Missing Nil Check

In lib/react_on_rails/configuration.rb, line 281:

  • The condition return if generated_assets_dir.present? means the method continues when generated_assets_dir is nil
  • The warning message will be printed even when using Shakapacker correctly
  • Recommendation: Add a Shakapacker check to avoid unnecessary warnings

3. Test Coverage Concerns

  • The diff shows updates to test mocks but doesn't include new tests for the three new feature detection methods
  • Recommendation: Add unit tests for supports_async_loading?, supports_basic_pack_generation?, and supports_autobundling?

4. Documentation Clarity

  • The version compatibility matrix in the docs is excellent, but consider adding migration examples for users upgrading from different versions
  • Recommendation: Add a migration guide section showing common upgrade paths

🔒 Security Considerations

No security vulnerabilities identified. The removal of unnecessary abstractions actually reduces the attack surface.

⚡ Performance Considerations

  • Version check caching is properly implemented
  • No performance regressions identified

🐛 Potential Edge Cases

  1. Shakapacker Not Installed: The refactored code assumes Shakapacker is always present. Consider users who might be using alternative bundlers.

  2. Version String Parsing: While Gem::Version handles most cases well, consider adding explicit error handling for malformed version strings.

📝 Minor Suggestions

  1. Consider extracting version constants to a single location for easier maintenance
  2. The deprecation warnings could benefit from including the version when the deprecated feature will be removed

✅ Overall Assessment

This is a well-thought-out fix that addresses the immediate issue while improving the codebase. The changes properly handle the version requirements and provide clear upgrade paths. With the suggested improvements around error handling and test coverage, this PR will be production-ready.

Great work on maintaining backward compatibility while cleaning up technical debt! 👏

- Eliminate the packer method abstraction completely
- Replace all packer method calls with direct Shakapacker references
- Update all tests to mock Shakapacker directly instead of the packer method
- Add require "shakapacker" at module level for test compatibility
- Remove all unnecessary abstraction layers as suggested in code review
- Simplifies codebase by removing unnecessary indirection
- All tests passing with direct Shakapacker usage

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@claude
Copy link

claude bot commented Sep 23, 2025

Code Review for PR #1801: Fix Shakapacker version requirement

Thank you for this PR addressing the Shakapacker version compatibility issues! I have thoroughly reviewed the changes, and here is my feedback:

✅ Strengths

1. Excellent Backward Compatibility Approach

  • The PR properly reduces the minimum required version from 8.2.0 to 8.0.0 for basic functionality
  • Feature-specific detection methods (supports_async_loading?, supports_basic_pack_generation?, supports_autobundling?) are well-designed
  • Clear separation between basic functionality (6.5.1+) and advanced features (7.0.0+ for auto-registration, 8.2.0+ for async loading)

2. Good Code Cleanup

  • Removal of legacy abstraction layers (using_packer?, packer_type) simplifies the codebase
  • Direct usage of Shakapacker module reduces unnecessary indirection
  • Test mocking is cleaner without the abstraction layer

3. Comprehensive Documentation

  • Version compatibility matrix in configuration.md is excellent
  • Clear upgrade guidance for users on different Shakapacker versions
  • CHANGELOG properly documents the fix

4. Proper Test Coverage

  • Tests verify each feature detection method
  • Version requirement validation ensures consistency
  • Mock updates properly reflect the simplified architecture

🔍 Areas for Improvement

1. Performance: Version Check Caching

The caching implementation in shakapacker_version_requirement_met? is good but consider clearing this cache in development/test environments where gem versions might change.

2. Error Messages Could Be More Actionable

The error messages are informative but could provide more specific next steps. For example, the warning about basic pack generation could include a link to the upgrade guide or specific features users are missing.

3. Minor: Naming Consistency

There is inconsistency in method naming:

  • supports_basic_pack_generation? vs supports_autobundling?
    Consider using consistent naming like supports_auto_bundling? or supports_auto_registration?

🐛 Potential Issues

1. Missing Shakapacker Dependency Check

The code now directly requires "shakapacker" at the top of packer_utils.rb. This will fail if Shakapacker is not installed. Consider adding a guard or rescue to handle the case where Shakapacker is not available.

2. Configuration Default Behavior

The change to not set generated_assets_dir when using Shakapacker is good, but the warning message could be clearer about what is happening. This might confuse users who do not understand the relationship between these configs.

🔒 Security Considerations

No security issues identified. The changes are primarily configuration and version checking logic.

🚀 Performance Considerations

  • Version check caching is a good optimization
  • Removing abstraction layers should slightly improve performance
  • Direct Shakapacker usage eliminates method call overhead

✅ Testing

  • Tests properly validate all version detection methods
  • Mock updates correctly reflect the new architecture
  • Consider adding integration tests for different Shakapacker versions

📝 Summary

Overall Assessment: APPROVED ✅

This is a well-executed fix that properly addresses the version requirement issue while improving the codebase. The backward compatibility approach is excellent, allowing users on older versions to continue using basic features while clearly communicating the benefits of upgrading.

The main suggestions are:

  1. Add a guard for the Shakapacker require statement
  2. Consider cache invalidation strategy for development
  3. Minor improvements to error messages for better user guidance

Great work on maintaining backward compatibility while simplifying the codebase! The version compatibility matrix in the documentation is particularly helpful for users.


Review performed by Claude Code according to repository standards in CLAUDE.md

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
lib/react_on_rails/packer_utils.rb (2)

118-118: Fix typo in configuration path reference.

Line 118 has a typo with shaka::Shakapacker.yml instead of config/shakapacker.yml.

-To fix this: edit your config/shaka::Shakapacker.yml file and set cache_manifest to false for test.
+To fix this: edit your config/shakapacker.yml file and set cache_manifest to false for test.

138-140: Fix typo in error message path references.

Lines 138-139 have typos with shaka::Shakapacker instead of config/shakapacker.yml.

-**ERROR** ReactOnRails: `nested_entries` is configured to be disabled in shaka::Shakapacker. Please update \
-config/shaka::Shakapacker.yml to enable nested entries. for more information read
+**ERROR** ReactOnRails: `nested_entries` is configured to be disabled in config/shakapacker.yml. Please update \
+config/shakapacker.yml to enable nested entries. For more information read
spec/react_on_rails/packer_utils_spec.rb (1)

110-141: Fix RuboCop RSpec/VerifiedDoubles offense.

The generic doubles violate RuboCop's verified doubles rule. Based on RSpec's verifying doubles requirements, use proper instance doubles for the actual Shakapacker classes.

-let(:mock_config) { instance_double("::Shakapacker::Config") } # rubocop:disable RSpec/VerifiedDoubleReference
-let(:mock_packer) { instance_double("::Shakapacker", config: mock_config) } # rubocop:disable RSpec/VerifiedDoubleReference
+let(:mock_config) { instance_double(Shakapacker::Configuration) }
+let(:mock_packer) { instance_double(Shakapacker, config: mock_config) }

 before do
-  allow(::Shakapacker).to receive(:config).and_return(mock_config)
+  allow(::Shakapacker).to receive(:config).and_return(mock_config)
 end

Make sure to add require "shakapacker" at the top of the file to ensure the constants are available:

+require "shakapacker"
 require_relative "spec_helper"
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 67210ef and 8d03cc6.

📒 Files selected for processing (7)
  • lib/react_on_rails/configuration.rb (6 hunks)
  • lib/react_on_rails/packer_utils.rb (7 hunks)
  • lib/react_on_rails/system_checker.rb (1 hunks)
  • spec/react_on_rails/configuration_spec.rb (6 hunks)
  • spec/react_on_rails/packer_utils_spec.rb (3 hunks)
  • spec/react_on_rails/test_helper/webpack_assets_status_checker_spec.rb (3 hunks)
  • spec/react_on_rails/utils_spec.rb (9 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • spec/react_on_rails/configuration_spec.rb
  • spec/react_on_rails/test_helper/webpack_assets_status_checker_spec.rb
🧰 Additional context used
📓 Path-based instructions (2)
{Gemfile,Rakefile,**/*.{rb,rake,gemspec,ru}}

📄 CodeRabbit inference engine (CLAUDE.md)

{Gemfile,Rakefile,**/*.{rb,rake,gemspec,ru}}: Before every commit/push, run bundle exec rubocop and fix all violations in Ruby code
Let RuboCop handle all Ruby code formatting; never manually format Ruby files

Files:

  • spec/react_on_rails/packer_utils_spec.rb
  • lib/react_on_rails/configuration.rb
  • spec/react_on_rails/utils_spec.rb
  • lib/react_on_rails/packer_utils.rb
  • lib/react_on_rails/system_checker.rb
{Gemfile,Rakefile,**/*.{rb,rake,gemspec,ru,js,jsx,ts,tsx,json,yml,yaml,md,css,scss}}

📄 CodeRabbit inference engine (CLAUDE.md)

Ensure all committed files end with a trailing newline character

Files:

  • spec/react_on_rails/packer_utils_spec.rb
  • lib/react_on_rails/configuration.rb
  • spec/react_on_rails/utils_spec.rb
  • lib/react_on_rails/packer_utils.rb
  • lib/react_on_rails/system_checker.rb
🧠 Learnings (5)
📚 Learning: 2025-02-13T14:29:49.267Z
Learnt from: AbanoubGhadban
PR: shakacode/react_on_rails#1644
File: spec/react_on_rails/utils_spec.rb:218-218
Timestamp: 2025-02-13T14:29:49.267Z
Learning: In RSpec tests, prefer using local variables over constants within test blocks to avoid constant redefinition warnings and maintain better test isolation.

Applied to files:

  • spec/react_on_rails/packer_utils_spec.rb
  • spec/react_on_rails/utils_spec.rb
📚 Learning: 2025-02-18T13:08:01.477Z
Learnt from: AbanoubGhadban
PR: shakacode/react_on_rails#1644
File: lib/react_on_rails/helper.rb:190-197
Timestamp: 2025-02-18T13:08:01.477Z
Learning: RSC support validation in React on Rails Pro is handled through a chain of validations:
1. Pro version check in `run_stream_inside_fiber`
2. RSC support check during pack generation via `ReactOnRailsPro.configuration.enable_rsc_support`
3. RSC support validation during component registration
This makes additional validation in the helper methods unnecessary.

Applied to files:

  • spec/react_on_rails/packer_utils_spec.rb
  • lib/react_on_rails/packer_utils.rb
📚 Learning: 2025-02-12T16:38:06.537Z
Learnt from: Romex91
PR: shakacode/react_on_rails#1697
File: package-scripts.yml:28-28
Timestamp: 2025-02-12T16:38:06.537Z
Learning: The file `node_package/lib/ReactOnRails.full.js` is autogenerated during the build process and should not be present in the repository.

Applied to files:

  • lib/react_on_rails/configuration.rb
📚 Learning: 2025-04-26T21:55:55.874Z
Learnt from: alexeyr-ci2
PR: shakacode/react_on_rails#1732
File: spec/dummy/client/app-react16/startup/ReduxSharedStoreApp.client.jsx:40-44
Timestamp: 2025-04-26T21:55:55.874Z
Learning: In the react_on_rails project, files under `app-react16` directories are copied/moved to corresponding `/app` directories during the conversion process (removing the `-react16` suffix), which affects their relative import paths at runtime.

Applied to files:

  • lib/react_on_rails/configuration.rb
  • spec/react_on_rails/utils_spec.rb
📚 Learning: 2024-06-27T05:22:46.156Z
Learnt from: justin808
PR: shakacode/react_on_rails#1622
File: spec/dummy/spec/rake/assets_precompile_rake_spec.rb:12-12
Timestamp: 2024-06-27T05:22:46.156Z
Learning: When stubbing environment variables in RSpec tests, use `before` and `after` hooks to ensure that the original values are restored after the tests, preventing any side effects on other tests. Example provided by justin808:
```ruby
describe "My test" do
  before do
    original_value = ENV["VARIABLE_NAME"]
    allow(ENV).to receive(:[]).with("VARIABLE_NAME").and_return("stubbed_value")
  end

  after do
    allow(ENV).to receive(:[]).with("VARIABLE_NAME").and_call_original
    ENV["VARIABLE_NAME"] = original_value
  end

  it "tests something" do
    # Your test code here
  end
end
```
This practice ensures test isolation and reliability.

Applied to files:

  • spec/react_on_rails/utils_spec.rb
🧬 Code graph analysis (5)
spec/react_on_rails/packer_utils_spec.rb (1)
lib/react_on_rails/packer_utils.rb (4)
  • supports_async_loading? (35-37)
  • supports_basic_pack_generation? (39-41)
  • supports_autobundling? (43-46)
  • shakapacker_version_requirement_met? (30-33)
lib/react_on_rails/configuration.rb (1)
lib/react_on_rails/packer_utils.rb (7)
  • supports_async_loading? (35-37)
  • raise_shakapacker_version_incompatible_for_basic_pack_generation (157-164)
  • supports_basic_pack_generation? (39-41)
  • supports_autobundling? (43-46)
  • raise_nested_entries_disabled (136-144)
  • nested_entries? (96-98)
  • packer_public_output_path (100-102)
spec/react_on_rails/utils_spec.rb (2)
lib/react_on_rails/packer_utils.rb (1)
  • packer_public_output_path (100-102)
lib/react_on_rails/utils.rb (1)
  • using_packer_source_path_is_not_defined_and_custom_node_modules? (161-164)
lib/react_on_rails/packer_utils.rb (3)
spec/dummy/config/webpack/commonWebpackConfig.js (1)
  • require (2-2)
spec/dummy/config/webpack/webpack.config.js (3)
  • require (1-1)
  • require (3-3)
  • require (4-4)
lib/react_on_rails/utils.rb (1)
  • source_path (157-159)
lib/react_on_rails/system_checker.rb (1)
lib/react_on_rails/packer_utils.rb (1)
  • supports_autobundling? (43-46)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: dummy-app-integration-tests (3.2, 20)
  • GitHub Check: dummy-app-integration-tests (3.4, 22)
  • GitHub Check: claude-review
  • GitHub Check: examples (3.4, latest)
  • GitHub Check: rspec-package-tests (3.2, minimum)
  • GitHub Check: rspec-package-tests (3.2, latest)
  • GitHub Check: rspec-package-tests (3.4, minimum)
  • GitHub Check: examples (3.2, minimum)
  • GitHub Check: rspec-package-tests (3.4, latest)
🔇 Additional comments (38)
lib/react_on_rails/packer_utils.rb (15)

8-8: LGTM! Consistent Shakapacker API usage.

Direct usage of ::Shakapacker.dev_server.running? is cleaner and more explicit than the previous indirect approach.


12-12: LGTM! Simplified dev server URL construction.

The direct Shakapacker API calls are more readable and maintainable.


30-33: Thread safety note acknowledged from past review.

The @version_checks instance variable cache is functionally safe for React on Rails' initialization-time usage patterns, despite theoretical thread safety concerns.


35-37: LGTM! Clean capability method implementation.

The new supports_async_loading? method provides a clear, semantic API for checking Shakapacker async loading capabilities.


39-41: LGTM! Good capability abstraction.

Using the constants from ReactOnRails::PacksGenerator ensures consistency across the codebase.


52-52: LGTM! Direct manifest lookup usage.

The transition to ::Shakapacker.manifest.lookup! is clean and removes unnecessary abstraction layers.


61-61: LGTM! Consistent dev server checking.

All dev server checks now use the same ::Shakapacker.dev_server.running? pattern consistently.


70-70: LGTM! Direct path configuration access.

The direct access to Shakapacker's public output path configuration is cleaner and more maintainable.


84-85: Fix addressed from past review.

The direct ::Shakapacker.config.shakapacker_precompile? call is now properly used instead of the packer wrapper.


88-89: LGTM! Consistent Shakapacker configuration access.

All the configuration methods now consistently use ::Shakapacker.config directly, which is cleaner and removes the need for wrapper methods.

Also applies to: 92-93, 97-97, 101-101, 105-105, 109-109


148-155: LGTM! Clear error messaging for autobundling requirements.

The error message clearly explains the version requirements and provides helpful context about different feature tiers.


157-164: LGTM! Clean error messaging for basic pack generation.

The error message is concise and provides the necessary version information.


166-174: LGTM! Appropriate error for missing Shakapacker.

The error message correctly identifies that Shakapacker is entirely missing and provides version guidance.


18-18: Add nil check for Shakapacker gem before accessing version.

The version access can raise NoMethodError if the Shakapacker gem is not loaded since Gem.loaded_specs['shakapacker'] returns nil.

-@shakapacker_version = Gem.loaded_specs["shakapacker"].version.to_s
+spec = Gem.loaded_specs["shakapacker"]
+raise ReactOnRails::Error, "Shakapacker gem is required but not loaded. Please add 'shakapacker' to your Gemfile and run bundle install." unless spec
+@shakapacker_version = spec.version.to_s

43-46: Add nil check before calling config methods.

The method could raise NoMethodError if ::Shakapacker.config returns nil, since it calls respond_to? without verification.

 def self.supports_autobundling?
   min_version = ReactOnRails::PacksGenerator::MINIMUM_SHAKAPACKER_VERSION_FOR_AUTO_REGISTRATION
-  ::Shakapacker.config.respond_to?(:nested_entries?) && shakapacker_version_requirement_met?(min_version)
+  config = ::Shakapacker.config
+  config&.respond_to?(:nested_entries?) && shakapacker_version_requirement_met?(min_version)
 end
lib/react_on_rails/system_checker.rb (2)

621-622: Remove no-op Gem::Version call.

The standalone Gem::Version.new(version) call on line 622 creates an unused version object and will be flagged by RuboCop.

 begin
-  # Validate version string format
-  Gem::Version.new(version)
+  # Validate version string format by attempting to parse
+  Gem::Version.new(version)

If the intent is just format validation, consider this approach:

-  # Validate version string format
-  Gem::Version.new(version)
+  # Validate version string format
+  valid_version = Gem::Version.new(version)

624-629: LGTM! Clean capability-based version checking.

The use of ReactOnRails::PackerUtils.supports_autobundling? provides a clear, semantic check and appropriate messaging based on actual capabilities rather than raw version numbers.

lib/react_on_rails/configuration.rb (7)

183-183: LGTM! Improved capability checking.

Using PackerUtils.supports_async_loading? provides clearer semantics than the raw version check.


201-214: LGTM! Enhanced autobundling requirement checks.

The new approach provides better granularity:

  1. Basic pack generation support is required for auto_load_bundle
  2. Advanced features (auto-registration) warn but don't block functionality
  3. Clear error messages distinguish between different capability levels

This preserves backward compatibility while guiding users toward newer features.


231-232: LGTM! Correct task name for Shakapacker.

The task name is now correctly shakapacker:clean instead of the dynamic packer_type:clean.


253-264: LGTM! Clearer error messaging for configuration mismatch.

The updated messaging properly references Shakapacker and provides clearer guidance on resolving configuration conflicts.


280-285: LGTM! Improved configuration guidance.

The warning message clearly explains that Shakapacker manages its own output path configuration, preventing conflicts.


291-295: LGTM! Updated deprecation messaging.

The message correctly references shakapacker.yml and explains the Shakapacker-managed approach.


329-336: LGTM! Updated conflict resolution guidance.

The updated messaging correctly references Shakapacker configuration files and commands.

spec/react_on_rails/packer_utils_spec.rb (5)

45-58: LGTM! Properly updated mocks for Shakapacker.

The mocks correctly use ::Shakapacker::DevServer and related Shakapacker classes with proper instance_double usage.


68-71: LGTM! Consistent Shakapacker mocking pattern.

The mocks follow the same pattern as the dev server running context.


80-92: LGTM! Clean test for async loading support.

The test properly verifies the supports_async_loading? method behavior with appropriate mocking of the underlying version check.


94-108: LGTM! Good test coverage for basic pack generation.

The test correctly uses the MINIMUM_SHAKAPACKER_VERSION constant and verifies both true and false scenarios.


144-173: LGTM! Comprehensive version constant validation.

The version constant validation tests ensure:

  1. Constants are properly defined
  2. Version consistency (auto-registration >= basic)
  3. Caching behavior works correctly

This provides good coverage of the version checking system.

spec/react_on_rails/utils_spec.rb (9)

4-4: Remove hardcoded require statement.

The hardcoded require removes flexibility for testing scenarios where Shakapacker might not be available.

Consider a more flexible approach:

-require "shakapacker"
+begin
+  require "shakapacker"
+rescue LoadError
+  # Handle gracefully in tests if needed
+end

Alternatively, since this is a test file and the PR objectives indicate Shakapacker is now a required dependency, the current approach may be acceptable.


9-11: LGTM! Clear comment about Shakapacker requirement.

The comment clearly explains that React on Rails v15+ requires Shakapacker, making the single-packer test approach appropriate.


14-24: LGTM! Properly updated mock objects for Shakapacker.

The mocks correctly use ::Shakapacker::Instance, ::Shakapacker::Configuration, and ::Shakapacker::DevServer with appropriate stubbing.


32-34: LGTM! Clear expectation about Shakapacker usage.

The test comment and expectation clearly document that PackerUtils now uses ::Shakapacker directly.


38-50: LGTM! Updated manifest mocking for Shakapacker.

The mock properly uses ::Shakapacker::Manifest and ::Shakapacker::Manifest::MissingEntryError consistently.


66-73: LGTM! Consistent dev server mocking pattern.

All dev server mocks now consistently use the ::Shakapacker API.


128-130: LGTM! Updated configuration access pattern.

The mocks properly use ::Shakapacker.config.send to access the internal configuration data structure.

Also applies to: 137-139, 146-147


173-173: LGTM! Direct Shakapacker variable assignment.

Using packer = ::Shakapacker directly is cleaner and more explicit.

Also applies to: 236-236


484-488: LGTM! Consistent Shakapacker mocking in manifest path tests.

The manifest path tests properly use Shakapacker's configuration and dev server APIs with appropriate mocking.

Also applies to: 492-500, 510-511

@@ -1,44 +1,19 @@
# frozen_string_literal: true

require "shakapacker"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove Shakapacker require to maintain lazy loading capability.

The require statement removes flexibility that the previous dynamic approach provided. The original code likely used lazy loading to avoid issues when Shakapacker isn't available. Consider requiring Shakapacker only when needed or adding proper error handling.

-require "shakapacker"

Add conditional requiring in the methods that need it:

def self.packer
  @packer ||= begin
    require "shakapacker"
    ::Shakapacker
  rescue LoadError => e
    raise ReactOnRails::Error, "Shakapacker gem is required but not available. Please add 'shakapacker' to your Gemfile. Error: #{e.message}"
  end
end
🤖 Prompt for AI Agents
In lib/react_on_rails/packer_utils.rb around line 3, the unconditional require
"shakapacker" breaks lazy loading and fails when the gem isn't present; change
to lazy/conditional requiring inside the methods that use Shakapacker (e.g., a
self.packer accessor) so the gem is only required when needed, rescue LoadError
and raise a clear ReactOnRails::Error with guidance to add shakapacker to the
Gemfile; memoize the resolved ::Shakapacker constant to avoid repeated requires.

- Replace all remaining ReactOnRails::PackerUtils.packer.config.public_output_path mocks
  with direct ::Shakapacker.config.public_output_path mocks in configuration_spec.rb
- All tests now pass with the simplified direct Shakapacker usage
- Updated Claude.md with requirements to run corresponding tests and RuboCop before pushing

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@claude
Copy link

claude bot commented Sep 23, 2025

PR Review: Fix Shakapacker version requirement from 8.2.0 to 8.0.0 for basic compatibility

Summary

This PR addresses an important compatibility issue that was causing React on Rails 16 to unnecessarily require Shakapacker 8.2.0 for all functionality, when only async loading actually requires that version. The changes properly implement feature detection and version gating to allow basic functionality with Shakapacker 8.0.0+.

Strengths

  1. Excellent backward compatibility approach: The PR correctly differentiates between basic functionality (6.5.1+), auto-registration (7.0.0+), and async loading (8.2.0+), allowing users to use React on Rails with older Shakapacker versions for basic features.

  2. Good code simplification: Removing the legacy abstraction layer significantly reduces code complexity and improves maintainability. The direct use of ::Shakapacker is cleaner and more straightforward.

  3. Improved error messaging: The differentiation between different incompatibility errors provides clearer guidance to users about what features require which versions.

  4. Performance optimization: The version check caching is a nice touch that avoids redundant version comparisons.

  5. Comprehensive test coverage: The PR includes extensive test updates covering the new version detection methods and ensuring backward compatibility scenarios work correctly.

Observations and Suggestions

  1. Potential edge case in configuration: The ensure_generated_assets_dir_present method now doesn't set a default value when using Shakapacker. While this prevents configuration mismatches, it might cause issues for code that expects generated_assets_dir to always have a value. Consider documenting this behavioral change clearly.

  2. Direct Shakapacker requires: The PR adds require shakapacker at the top of packer_utils.rb. This makes Shakapacker a hard dependency. Consider whether this should be wrapped in a rescue block or conditional require for environments where Shakapacker might not be installed.

  3. Documentation clarity: The version compatibility matrix in the configuration documentation is excellent. Consider adding this information to the main README as well for better visibility.

Minor Issues

  1. Inconsistent class references: Some error messages use ::Shakapacker while others use Shakapacker. Standardize on one format for consistency.

  2. Test mocking consistency: Some tests use instance_double while others use double. Consider standardizing on instance_double for better type safety in tests.

Performance Considerations

  • Version check caching: The caching implementation is good, but consider if the cache should be cleared in development mode where gems might be updated without restarting the Rails server.

Security Considerations

  • No security issues identified. The PR appropriately doesn't expose any sensitive information or introduce new attack vectors.

Overall Assessment

This is a high-quality PR that solves a real problem elegantly. The approach of using feature detection rather than hard version requirements is the right architectural decision. The code simplification makes the codebase more maintainable, and the backward compatibility ensures existing users aren't forced into unnecessary upgrades.

The changes are well-tested, properly documented, and follow Rails/Ruby best practices. The PR successfully achieves its goal of fixing the Docker build failures while improving the overall codebase.

Recommendation: APPROVE

This PR is ready to merge once the minor suggestions above are considered (though none are blocking issues).

Great work on thoughtfully solving this compatibility issue while simultaneously improving code quality!

- Local RuboCop is now clean (0 offenses detected)
- Auto-fix resolved ModuleLength violations during pre-commit
- Force CI to re-run with current clean state

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@claude
Copy link

claude bot commented Sep 23, 2025

Code Review for PR #1801: Fix Shakapacker version requirement from 8.2.0 to 8.0.0

✅ Overall Assessment

This PR successfully addresses the reported issue and provides a significant improvement to the codebase. The changes fix the Docker build failure while simplifying the compatibility layer and improving version management.

🎯 Code Quality & Best Practices

Strengths:

  • Clear separation of concerns: The introduction of feature-specific methods (supports_async_loading?, supports_basic_pack_generation?, supports_autobundling?) provides better clarity and maintainability
  • Performance optimization: Addition of caching in shakapacker_version_requirement_met? method reduces redundant version checks
  • Code simplification: Removal of legacy abstraction layers (using_packer?, packer_type, using_shakapacker_const?) reduces complexity
  • Comprehensive documentation: The version compatibility matrix in the configuration guide is excellent for user understanding

Minor Suggestions:

  1. Consider extracting version constants to a dedicated module for better organization
  2. The caching implementation could use a more descriptive variable name than @version_checks

🐛 Potential Issues

Low Risk:

  1. Direct Shakapacker dependency: The 'require "shakapacker"' at the top of packer_utils.rb assumes Shakapacker is always available. Consider wrapping in a rescue block for better error handling
  2. Thread safety: The @version_checks cache might have thread safety issues in multi-threaded environments. Consider using a thread-safe implementation if needed

⚡ Performance Considerations

Improvements:

  • ✅ Version check caching reduces redundant Gem::Version comparisons
  • ✅ Removal of unnecessary abstraction layers reduces method call overhead
  • ✅ Simplified configuration logic reduces startup time

Note: The caching strategy is appropriate for the use case since gem versions don't change during runtime.

🔒 Security Concerns

No security issues identified. The changes maintain proper input validation and don't introduce any new attack vectors.

🧪 Test Coverage

Excellent Coverage:

  • ✅ Comprehensive tests for all new feature detection methods
  • ✅ Version constant validation tests ensure logical consistency
  • ✅ Proper mocking strategy for Shakapacker initialization
  • ✅ Edge cases covered for different version scenarios

Minor Observation:
The test mocking has been simplified, which actually improves test maintainability.

📝 Additional Comments

  1. Breaking Change Mitigation: The backward compatibility approach is well-thought-out, allowing users on older Shakapacker versions to continue working with basic functionality
  2. Error Messages: The improved error messages with clear upgrade paths are user-friendly
  3. Changelog: The CHANGELOG entry clearly documents the fix and references the relevant PR

✅ Recommendation

APPROVE - This PR effectively solves the reported issue while improving code quality. The changes are well-tested, documented, and maintain backward compatibility appropriately.

The removal of the artificial 8.2.0 requirement for basic functionality is the right approach, and the feature-specific version checking provides a better upgrade path for users.

🤖 Generated with Claude Code

- Changed bare `rubocop -a` to `bundle exec rubocop -a` in linters.md
- Ensures documentation follows best practices for bundled gem usage
- Prevents version conflicts between global and project rubocop versions

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
docs/contributor-info/linters.md (1)

81-84: Add language tags to code fences for syntax highlighting.

Mark these as JavaScript for better readability.

-```
+```js
 /* global $, window, angular */
 // rest of code

- +js
console.log('console.log not allowed'); // eslint-disable-line

alert('alert not allowed'); // eslint-disable-line no-alert

/* eslint-disable no-console, no-alert /
console.log('more console.log');
alert('more alert');
/
eslint-enable no-console, no-alert */

Also applies to: 88-97

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8d03cc6 and 4b932ad.

📒 Files selected for processing (2)
  • docs/contributor-info/linters.md (1 hunks)
  • spec/react_on_rails/configuration_spec.rb (7 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
{Gemfile,Rakefile,**/*.{rb,rake,gemspec,ru}}

📄 CodeRabbit inference engine (CLAUDE.md)

{Gemfile,Rakefile,**/*.{rb,rake,gemspec,ru}}: Before every commit/push, run bundle exec rubocop and fix all violations in Ruby code
Let RuboCop handle all Ruby code formatting; never manually format Ruby files

Files:

  • spec/react_on_rails/configuration_spec.rb
{Gemfile,Rakefile,**/*.{rb,rake,gemspec,ru,js,jsx,ts,tsx,json,yml,yaml,md,css,scss}}

📄 CodeRabbit inference engine (CLAUDE.md)

Ensure all committed files end with a trailing newline character

Files:

  • spec/react_on_rails/configuration_spec.rb
  • docs/contributor-info/linters.md
**/*.{js,jsx,ts,tsx,json,yml,yaml,md,css,scss}

📄 CodeRabbit inference engine (CLAUDE.md)

Let Prettier handle all non-Ruby file formatting; never manually format these files

Files:

  • docs/contributor-info/linters.md
🧠 Learnings (7)
📚 Learning: 2025-04-26T21:55:55.874Z
Learnt from: alexeyr-ci2
PR: shakacode/react_on_rails#1732
File: spec/dummy/client/app-react16/startup/ReduxSharedStoreApp.client.jsx:40-44
Timestamp: 2025-04-26T21:55:55.874Z
Learning: In the react_on_rails project, files under `app-react16` directories are copied/moved to corresponding `/app` directories during the conversion process (removing the `-react16` suffix), which affects their relative import paths at runtime.

Applied to files:

  • spec/react_on_rails/configuration_spec.rb
📚 Learning: 2025-02-18T13:08:01.477Z
Learnt from: AbanoubGhadban
PR: shakacode/react_on_rails#1644
File: lib/react_on_rails/helper.rb:190-197
Timestamp: 2025-02-18T13:08:01.477Z
Learning: RSC support validation in React on Rails Pro is handled through a chain of validations:
1. Pro version check in `run_stream_inside_fiber`
2. RSC support check during pack generation via `ReactOnRailsPro.configuration.enable_rsc_support`
3. RSC support validation during component registration
This makes additional validation in the helper methods unnecessary.

Applied to files:

  • spec/react_on_rails/configuration_spec.rb
📚 Learning: 2025-02-18T13:08:01.477Z
Learnt from: AbanoubGhadban
PR: shakacode/react_on_rails#1644
File: lib/react_on_rails/helper.rb:190-197
Timestamp: 2025-02-18T13:08:01.477Z
Learning: RSC support validation is handled in deeper level calls of the React on Rails Pro codebase, so it doesn't need to be validated again in the `rsc_payload_react_component` helper method.

Applied to files:

  • spec/react_on_rails/configuration_spec.rb
📚 Learning: 2025-02-12T16:38:06.537Z
Learnt from: Romex91
PR: shakacode/react_on_rails#1697
File: package-scripts.yml:28-28
Timestamp: 2025-02-12T16:38:06.537Z
Learning: The file `node_package/lib/ReactOnRails.full.js` is autogenerated during the build process and should not be present in the repository.

Applied to files:

  • spec/react_on_rails/configuration_spec.rb
📚 Learning: 2025-09-22T07:21:12.910Z
Learnt from: CR
PR: shakacode/react_on_rails#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-22T07:21:12.910Z
Learning: Applies to {Gemfile,Rakefile,**/*.{rb,rake,gemspec,ru}} : Before every commit/push, run `bundle exec rubocop` and fix all violations in Ruby code

Applied to files:

  • docs/contributor-info/linters.md
📚 Learning: 2025-09-22T07:21:12.910Z
Learnt from: CR
PR: shakacode/react_on_rails#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-22T07:21:12.910Z
Learning: Applies to {Gemfile,Rakefile,**/*.{rb,rake,gemspec,ru}} : Let RuboCop handle all Ruby code formatting; never manually format Ruby files

Applied to files:

  • docs/contributor-info/linters.md
📚 Learning: 2025-09-22T07:21:12.910Z
Learnt from: CR
PR: shakacode/react_on_rails#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-22T07:21:12.910Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use ESLint for JavaScript/TypeScript and fix all linter offenses before committing

Applied to files:

  • docs/contributor-info/linters.md
🧬 Code graph analysis (1)
spec/react_on_rails/configuration_spec.rb (3)
lib/react_on_rails/packer_utils.rb (1)
  • packer_public_output_path (100-102)
lib/react_on_rails/configuration.rb (2)
  • configure (6-9)
  • configuration (16-57)
lib/react_on_rails/react_component/render_options.rb (1)
  • auto_load_bundle (78-80)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: dummy-app-integration-tests (3.2, 20)
  • GitHub Check: dummy-app-integration-tests (3.4, 22)
  • GitHub Check: examples (3.4, latest)
  • GitHub Check: rspec-package-tests (3.4, minimum)
  • GitHub Check: rspec-package-tests (3.4, latest)
  • GitHub Check: rspec-package-tests (3.2, minimum)
  • GitHub Check: examples (3.2, minimum)
  • GitHub Check: rspec-package-tests (3.2, latest)
  • GitHub Check: claude-review
🔇 Additional comments (10)
spec/react_on_rails/configuration_spec.rb (7)

4-4: LGTM: Updated require statement to use Shakapacker directly.

The change from requiring the PackerUtils to directly requiring Shakapacker aligns with the PR's objective to remove legacy abstractions and use Shakapacker explicitly.


29-30: LGTM: Correct stubbing of Shakapacker configuration.

The stub correctly mocks ::Shakapacker.config.public_output_path to return a Pathname object, which matches the expected behavior based on the code snippets showing that packer_public_output_path returns ::Shakapacker.config.public_output_path.to_s.


188-193: LGTM: Updated autobundling capability stubbing.

The change correctly replaces the old using_packer? method with the new feature-specific detection methods supports_autobundling? and nested_entries?. This aligns with the PR's introduction of feature-specific detection methods instead of generic packer type checking.


292-294: LGTM: Consistent Shakapacker stubbing pattern.

The stubbing pattern is consistent with other tests and correctly mocks the Shakapacker configuration path.


307-309: LGTM: Consistent test setup pattern.

The test setup follows the same pattern as the previous test, ensuring consistent behavior across test cases.


323-334: LGTM: New test correctly validates Shakapacker-only configuration.

This new test case properly validates that the configuration works without specifying generated_assets_dir when using Shakapacker, which is an important scenario covered by the PR changes. The test correctly stubs Shakapacker's public output path and verifies that the configuration doesn't raise errors while keeping generated_assets_dir blank.


337-340: LGTM: Updated autobundling feature detection calls.

The tests correctly use the new feature-specific detection methods:

  • supports_autobundling? replaces the generic packer type checks
  • nested_entries? provides specific capability detection
  • The test expectations are updated to verify these new method calls

This aligns with the PR's objective to replace dynamic packer/webpacker branching with explicit capability predicates.

Also applies to: 350-354, 361-362

docs/contributor-info/linters.md (3)

12-14: Good change: use Bundler to run RuboCop.

Switching to bundle exec rubocop -a matches our guidelines and avoids version mismatches.


39-47: Verify commands exist — confirmed.
package.json "start" = nps; package-scripts.yml defines format.default (prettier --write .), format.listDifferent (prettier --check .) and an autofix entry that runs rake autofix; rakelib/lint.rake defines task :autofix.


1-103: Add missing trailing newline to EOF — docs/contributor-info/linters.md

Automated checks failed in the sandbox (missing 'od' / script error); manually confirm the file ends with a newline character and commit the fix if it's missing.

justin808 and others added 2 commits September 22, 2025 16:40
- Add Code Cleanup section documenting removal of PackerUtils.packer method
- Explain rationale: abstraction no longer needed since we only support Shakapacker
- Note that all tests were updated accordingly
- Provides context for this architectural simplification

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Include 'by [claude-code](https://claude.ai/code)' to follow project format
- Maintain consistency with existing CHANGELOG entries that include author attribution

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@claude
Copy link

claude bot commented Sep 23, 2025

Code Review for PR #1801: Fix Shakapacker version requirement

Thank you for this comprehensive fix! I have reviewed the changes and here is my feedback:

✅ Strengths

  1. Clear problem definition and solution: The PR excellently addresses the artificial version requirement issue while maintaining backward compatibility.

  2. Improved abstraction: Removing the legacy PackerUtils abstraction layer significantly simplifies the codebase by eliminating unnecessary indirection.

  3. Feature-specific detection: The new methods (supports_async_loading?, supports_basic_pack_generation?, supports_autobundling?) provide clear semantic meaning.

  4. Performance optimization: Adding caching to version checks with @version_checks memoization is a good optimization.

🔍 Potential Issues & Suggestions

  1. Missing require statement guard: In lib/react_on_rails/packer_utils.rb, there is a require "shakapacker" at the top. This could fail if Shakapacker is not installed. Consider adding a guard or moving the require to where it is needed.

  2. Inconsistent error handling: Some places still reference ::Shakapacker in error messages while the code now uses bare Shakapacker. Consider standardizing to just Shakapacker.

  3. Test coverage concern: The changelog mentions "All existing tests pass" but I do not see new tests for the version-specific feature detection methods. Consider adding tests for:

    • supports_async_loading?
    • supports_basic_pack_generation?
    • supports_autobundling?
  4. Configuration validation: In configuration.rb:198, the logic for checking autobundling requirements could be clearer with early returns.

🛡️ Security Considerations

No security concerns identified. The changes properly validate versions and configurations without introducing new attack vectors.

🚀 Performance Considerations

The version check caching is a good addition. Consider also caching the shakapacker_version_as_array result since it is derived from shakapacker_version.

📝 Documentation

Excellent documentation updates in configuration.md with the feature compatibility matrix! Very helpful for users.

⚠️ Minor Issues

  1. Typo in error message (line 137 in packer_utils.rb): "shaka::Shakapacker.yml" should be "shakapacker.yml"

  2. Trailing whitespace: Ensure all modified files follow the project linting rules (per CLAUDE.md requirements - must run bundle exec rubocop before commit).

Recommendation

APPROVED with minor suggestions

This is a well-thought-out fix that properly addresses the version requirement issue while simplifying the codebase. The minor issues mentioned above should be addressed, particularly the potential missing Shakapacker require guard and the typo in the error message.

Great work on maintaining backward compatibility while enabling users on older Shakapacker versions to use basic functionality!

@justin808 justin808 merged commit 2f11606 into master Sep 23, 2025
12 of 13 checks passed
@justin808 justin808 deleted the fix/shakapacker-version-requirement branch September 23, 2025 02:42
@claude
Copy link

claude bot commented Sep 23, 2025

Code Review for PR #1801: Fix Shakapacker Version Requirements

Thank you for this PR! The abstraction layer cleanup and improved backward compatibility handling are valuable improvements. Here's my detailed review:

Strengths

  • Excellent abstraction removal: Eliminating the unnecessary packer method layer makes the code more maintainable
  • Smart version caching: The new @version_checks caching in shakapacker_version_requirement_met? improves performance
  • Clear feature detection: New methods like supports_async_loading? and supports_basic_pack_generation? improve code clarity
  • Good test coverage: Comprehensive tests for version management and constants validation

🔴 Critical Issues to Address

1. Error Message Inconsistencies

Found inconsistent references in packer_utils.rb:

  • Line 118: "shaka::Shakapacker.yml" should be "shakapacker.yml"
  • Line 138-139: "::Shakapacker gem" should be "Shakapacker gem"

2. Missing Error Handling

The require "shakapacker" at the top of packer_utils.rb doesn't handle LoadError if Shakapacker isn't available.

Suggested fix:

begin
  require "shakapacker"
rescue LoadError
  # Handle gracefully or defer until actually needed
end

3. Version Cache Memory Growth

The @version_checks hash in shakapacker_version_requirement_met? grows indefinitely. In long-running processes, this could accumulate memory.

Suggested improvement:

def self.shakapacker_version_requirement_met?(required_version)
  @version_checks ||= {}
  @version_checks.clear if @version_checks.size > 100  # Prevent unbounded growth
  @version_checks[required_version] ||= Gem::Version.new(shakapacker_version) >= Gem::Version.new(required_version)
end

⚠️ Potential Edge Cases

Configuration Logic (configuration.rb lines 201-214)

The code doesn't verify Shakapacker is installed before calling PackerUtils.raise_shakapacker_not_installed. This could cause issues if the gem isn't available.

Cache Staleness

If shakapacker_version changes during runtime (e.g., gem reload in development), the cached version checks will return stale results. Consider documenting this limitation or adding cache invalidation.

📝 Minor Improvements

  1. Standardize error message formatting: Some use <<~MSG heredocs while others use strings
  2. Add integration tests: The new configuration flow would benefit from end-to-end tests
  3. Test error scenarios: Add tests for LoadError and malformed version strings

Performance & Security

  • Performance: Good improvements by removing abstraction overhead and adding caching
  • Security: No issues identified - proper use of Gem::Version for safe comparisons

📊 Test Coverage Gaps

Consider adding tests for:

  • LoadError when Shakapacker is missing
  • Cache invalidation scenarios
  • Warning message generation in configuration
  • Version parsing edge cases

🎯 Summary

This is a solid cleanup that improves code maintainability and backward compatibility. The changes successfully reduce complexity while maintaining functionality. With the error message fixes and error handling improvements, this will be ready to merge.

Recommendation: ✅ Approve with minor changes - Please address the error message inconsistencies and add LoadError handling.

Great work on simplifying the codebase while improving compatibility! 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants