Skip to content

Conversation

@justin808
Copy link
Member

@justin808 justin808 commented Nov 26, 2025

Summary

  • Add using_swc? helper method to detect SWC configuration in shakapacker.yml
  • Automatically install SWC dependencies (@swc/core, swc-loader) when SWC is configured
  • Update spec/dummy to include SWC packages

Key Changes

1. Enhanced using_swc? Helper

  • Parses shakapacker.yml for javascript_transpiler setting
  • Returns true when SWC is explicitly configured
  • Returns true for Shakapacker 9.3.0+ when not specified (SWC is the default)
  • Returns true for fresh installations (SWC is recommended)

2. Generator Updates

  • Add SWC_DEPENDENCIES constant with @swc/core and swc-loader
  • Install SWC deps automatically when using_swc? returns true
  • Add to devDependencies since they're build-time tools

3. spec/dummy Updates

  • Add @swc/core and swc-loader to devDependencies
  • Matches the javascript_transpiler: swc setting already in shakapacker.yml

Testing

  • Added comprehensive RSpec tests for using_swc? helper
  • All existing tests pass
  • RuboCop checks pass

Test Plan

  • Test generator with Shakapacker 9.3.0+
  • Verify SWC detection logic
  • Test fallback to Babel when explicitly configured

Closes #1956

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added automatic SWC transpiler support detection based on Shakapacker configuration
    • SWC dependencies are now automatically installed during project setup when applicable (Shakapacker 9.3.0+)
    • Graceful fallback handling for configuration parsing and dependency installation
  • Tests

    • Added comprehensive test coverage for SWC configuration detection and dependency installation

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 26, 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 25 minutes and 6 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 c7f23d7 and d02af07.

📒 Files selected for processing (7)
  • .github/workflows/detect-invalid-ci-commands.yml (0 hunks)
  • react_on_rails/lib/generators/react_on_rails/generator_helper.rb (1 hunks)
  • react_on_rails/lib/generators/react_on_rails/js_dependency_manager.rb (3 hunks)
  • react_on_rails/spec/dummy/package.json (2 hunks)
  • react_on_rails/spec/react_on_rails/generators/generator_helper_spec.rb (1 hunks)
  • react_on_rails/spec/react_on_rails/generators/install_generator_spec.rb (1 hunks)
  • react_on_rails/spec/react_on_rails/generators/js_dependency_manager_spec.rb (2 hunks)

Walkthrough

Introduces SWC configuration detection in the generator helper with automatic Shakapacker version checking and shakapacker.yml parsing. Adds conditional SWC dependency installation in the JS dependency manager. Includes comprehensive tests for the new SWC detection logic.

Changes

Cohort / File(s) Change Summary
SWC Detection & Configuration
react_on_rails/lib/generators/react_on_rails/generator_helper.rb
Adds using_swc? public method that detects SWC via shakapacker.yml config or Shakapacker 9.3.0+ version check; includes detect_swc_configuration, parse_shakapacker_yml, and shakapacker_version_9_3_or_higher? helpers with resilient YAML parsing and version detection.
SWC Dependency Installation
react_on_rails/lib/generators/react_on_rails/js_dependency_manager.rb
Adds SWC_DEPENDENCIES constant and add_swc_dependencies private method; conditionally installs SWC dependencies via add_js_dependencies when using_swc? is true, with error handling and manual install fallback.
Test Suite
react_on_rails/spec/react_on_rails/generators/generator_helper_spec.rb, react_on_rails/spec/react_on_rails/generators/install_generator_spec.rb, react_on_rails/spec/react_on_rails/generators/js_dependency_manager_spec.rb
Comprehensive tests for using_swc? detection across config scenarios (swc, babel, missing, parse errors); integration test verifying SWC dependencies installed by default; test helper methods for configurable SWC flag.
Development Dependencies
react_on_rails/spec/dummy/package.json
Adds @swc/core@^1.7.0 and swc-loader@^0.2.6 as development dependencies.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • generator_helper.rb: Multiple fallback paths in YAML parsing and version detection require careful attention to error handling and precedence logic.
  • js_dependency_manager.rb: Verify SWC dependency installation mirrors existing patterns and error handling is consistent.
  • Test coverage: Comprehensive test suite validates detection logic across edge cases; verify mocking and setup/teardown are correct.

Possibly related issues

Possibly related PRs

Suggested labels

review-needed, full-ci

Suggested reviewers

  • alexeyr-ci
  • AbanoubGhadban
  • Judahmeek

Poem

🐰 ✨ A transpiler so swift, now bundled with care,
SWC detection in springtime air!
Version checks, configs parsed just right,
Dependencies installed, shining bright! 🚀

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Linked Issues check ❓ Inconclusive The PR addresses core SWC detection and dependency installation but does not fully cover all stated objectives from issue #1956, particularly generated shakapacker.yml configuration and documentation. Verify whether generated shakapacker.yml configuration updates, documentation, and migration notes are planned as follow-up work or out of scope for this PR.
✅ 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 'Improve SWC compiler detection and default dependencies' directly and clearly summarizes the main changes: enhanced SWC detection logic and automatic SWC dependency installation.
Out of Scope Changes check ✅ Passed All changes in the PR are directly related to SWC detection and dependency management, with no unrelated modifications outside the stated objectives.

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 Nov 26, 2025

Code Review: PR #2135 - Improve SWC compiler detection and default dependencies

Summary

This PR adds intelligent SWC (Speedy Web Compiler) detection and automatic dependency installation for the React on Rails generator. Overall, the implementation is well-designed and production-ready with excellent test coverage and error handling.


✅ Strengths

1. Excellent Error Handling & Graceful Degradation

The code follows a defensive programming approach that aligns well with the project's error handling philosophy:

def parse_shakapacker_yml(path)
  require "yaml"
  YAML.load_file(path, aliases: true)
rescue ArgumentError
  # Older Psych versions don't support the aliases parameter
  YAML.load_file(path)
rescue StandardError
  # If we can't parse the file, return empty config
  {}
end
  • ✅ Handles both old and new Psych versions
  • ✅ Returns empty config instead of raising exceptions
  • ✅ Prevents generator crashes from malformed YAML files

2. Smart Default Behavior

The detection logic makes sensible assumptions:

  • Explicitly configured transpilers take precedence (babel vs swc)
  • Defaults to SWC for Shakapacker 9.3.0+ (matches upstream default)
  • Assumes latest version for fresh installs (optimistic but safe)
  • Falls back gracefully when version detection fails

3. Comprehensive Test Coverage

The specs cover all edge cases:

 Explicit SWC configuration
 Explicit Babel configuration  
 No transpiler specified (version-based default)
 Missing shakapacker.yml
 Malformed YAML parsing errors

4. Proper Memoization

def using_swc?
  return @using_swc if defined?(@using_swc)
  @using_swc = detect_swc_configuration
end

Uses defined?(@using_swc) instead of just checking truthiness, which correctly handles false values.

5. Clear Documentation

Excellent inline documentation explaining:

  • What the method does
  • Detection logic flow
  • Why certain defaults are chosen
  • Performance benefits ("20x faster than Babel")

🔍 Potential Issues & Suggestions

1. Missing Version Check Implementation ⚠️

The code calls shakapacker_version_9_3_or_higher? but I notice it's a new method. Let me verify the implementation:

def shakapacker_version_9_3_or_higher?
  return true unless defined?(ReactOnRails::PackerUtils)
  
  ReactOnRails::PackerUtils.shakapacker_version_requirement_met?("9.3.0")
rescue StandardError
  # If we can't determine version, assume latest (which uses SWC)
  true
end

Good: This follows the same pattern as the existing shakapacker_version_9_or_higher? method.

Concern: The method returns true when ReactOnRails::PackerUtils is not defined. During generator runtime, this might not be defined yet.

Recommendation: Verify this works correctly during fresh installations where Shakapacker hasn't been installed yet. The optimistic default is probably correct, but worth confirming.

2. Dependency Installation Ordering 💡

In js_dependency_manager.rb:

def add_js_dependencies
  add_react_on_rails_package
  add_react_dependencies
  add_css_dependencies
  add_rspack_dependencies if respond_to?(:options) && options&.rspack?
  add_swc_dependencies if using_swc?  # ← Called here
  add_dev_dependencies
end

Question: Should SWC dependencies be added earlier in the sequence, perhaps before CSS dependencies? Build tools typically need to be installed before other dependencies that might use them.

Recommendation: Consider moving add_swc_dependencies right after add_react_on_rails_package or at least before add_css_dependencies.

3. YAML.load_file Security 🔒

YAML.load_file(path, aliases: true)

Current: Uses YAML.load_file which can execute arbitrary Ruby code in older YAML versions.

Recommendation: Consider using YAML.safe_load_file for better security:

def parse_shakapacker_yml(path)
  require "yaml"
  YAML.safe_load_file(path, aliases: true, permitted_classes: [Symbol])
rescue ArgumentError
  YAML.safe_load_file(path, permitted_classes: [Symbol])
rescue StandardError
  {}
end

However: Since this is reading the user's own shakapacker.yml config file (not external input), the security risk is minimal. But it's worth considering for defense-in-depth.

4. Missing Test: Version Boundary 📝

The tests cover the logic well, but there's no test for the version boundary:

Suggestion: Add a test that mocks ReactOnRails::PackerUtils.shakapacker_version_requirement_met? to return both true and false for version 9.3.0.

Example:

context "when Shakapacker version is 9.2.0 (before SWC default)" do
  before do
    allow(ReactOnRails::PackerUtils).to receive(:shakapacker_version_requirement_met?)
      .with("9.3.0").and_return(false)
  end

  it "returns false when no transpiler is specified" do
    File.write(shakapacker_yml_path, "default: {}\n")
    expect(using_swc?).to be false
  end
end

5. Potential Race Condition with Memoization 🧵

The memoization uses instance variables:

def using_swc?
  return @using_swc if defined?(@using_swc)
  @using_swc = detect_swc_configuration
end

Concern: If shakapacker.yml changes during generator execution, the memoized value won't update.

Reality Check: This is probably fine since generators run quickly and config files shouldn't change mid-execution.

Optional Enhancement: Add a comment explaining this caching behavior.


🎯 Code Quality Assessment

Category Rating Notes
Error Handling ⭐⭐⭐⭐⭐ Excellent graceful degradation
Test Coverage ⭐⭐⭐⭐½ Comprehensive, missing version boundary test
Documentation ⭐⭐⭐⭐⭐ Clear comments and inline docs
Code Style ⭐⭐⭐⭐⭐ Follows project conventions
Security ⭐⭐⭐⭐☆ Minor YAML.load concern (low risk)
Performance ⭐⭐⭐⭐⭐ Proper memoization

🚀 Testing Recommendations

Before merging, please verify:

  1. Fresh Installation Test:

    # In a new Rails app without Shakapacker
    rails new test_app
    cd test_app
    bundle add react_on_rails --git=<your-branch>
    rails generate react_on_rails:install
    # Verify SWC dependencies are installed
    grep -E '@swc/core|swc-loader' package.json
  2. Babel Override Test:

    # Edit config/shakapacker.yml BEFORE running generator
    # Set javascript_transpiler: babel
    rails generate react_on_rails:install
    # Verify SWC dependencies are NOT installed
    grep -E '@swc/core|swc-loader' package.json  # Should be empty
  3. Existing Installation Test:

    # In an app with existing Shakapacker 9.3.0+
    rails generate react_on_rails:install
    # Verify SWC deps are added

📋 Checklist for Author

  • Manual testing completed per recommendations above
  • CI passes (RuboCop, RSpec)
  • Tested with both fresh and existing installations
  • Verified SWC deps are correctly installed/skipped based on config
  • Consider adding version boundary test (optional)
  • Consider YAML.safe_load_file (optional security hardening)

✅ Final Recommendation

APPROVE with minor suggestions.

This is a well-implemented feature that:

  • Solves a real problem (manual SWC dependency installation)
  • Has excellent error handling
  • Includes comprehensive tests
  • Follows project conventions
  • Makes sensible default assumptions

The suggestions above are minor improvements, not blocking issues. The code is production-ready as-is.

Great work! 🎉


Reviewed by: Claude Code
Date: 2025-11-26

@justin808
Copy link
Member Author

/run-skipped-ci

@github-actions
Copy link
Contributor

github-actions bot commented Dec 9, 2025

🚀 Full CI Mode Enabled

Triggered all workflows for full CI coverage

Note: Added the full-ci label to this PR. All future commits will run the full CI suite (including minimum dependency tests) until the label is removed.

To disable full CI mode, use the /stop-run-skipped-ci command.

View progress in the Actions tab.

@claude claude bot mentioned this pull request Dec 9, 2025
3 tasks
justin808 and others added 5 commits December 8, 2025 19:59
Add using_swc? helper method to detect SWC configuration:
- Parses shakapacker.yml for javascript_transpiler setting
- Returns true when SWC is explicitly configured
- Returns true for Shakapacker 9.3.0+ when not specified (SWC default)
- Returns true for fresh installations (SWC is recommended)

Add SWC dependency installation to generator:
- Add SWC_DEPENDENCIES constant (@swc/core, swc-loader)
- Install SWC deps automatically when using_swc? returns true
- Add to devDependencies since they're build-time tools

Update spec/dummy to include SWC packages:
- Add @swc/core and swc-loader to devDependencies
- Matches the javascript_transpiler: swc setting in shakapacker.yml

Add comprehensive tests for using_swc? helper:
- Test explicit swc config returns true
- Test explicit babel config returns false
- Test missing config defaults to SWC for 9.3.0+
- Test missing file defaults to SWC
- Test invalid YAML defaults to SWC

Closes #1956

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

Co-Authored-By: Claude <noreply@anthropic.com>
The JsDependencyManager tests create a mock test class that includes
the module. After adding the using_swc? call to add_js_dependencies,
the test class needs to provide this method (which comes from
GeneratorHelper in actual generator classes).

Changes:
- Add using_swc? method stub to test class (defaults to true)
- Add using_swc setter for test control
- Add test for SWC_DEPENDENCIES constant

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

Co-Authored-By: Claude <noreply@anthropic.com>
Changes based on code review feedback:

1. Security: Use YAML.safe_load_file instead of YAML.load_file
   - Defense-in-depth even though it's the user's own config
   - Added fallback chain for older Psych versions

2. Documentation: Add caching behavior note to using_swc?
   - Explains memoization is per-generator-instance
   - Notes config changes during execution won't be reflected

3. Tests: Add version boundary tests for Shakapacker 9.3.0
   - Test SWC default when version is 9.3.0+
   - Test Babel default when version is below 9.3.0
   - Test graceful fallback when version check fails

4. Tests: Add generator test verifying SWC dependency installation
   - Confirms @swc/core and swc-loader in devDependencies
   - Mirrors existing rspack dependency test pattern

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

Co-Authored-By: Claude <noreply@anthropic.com>
Remove `result-encoding: string` from the github-script step.
With this setting, returning an object produces "[object Object]"
instead of proper JSON, causing fromJSON() to fail with
"Unexpected character 'o'".

Without result-encoding, github-script returns proper JSON by default.

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

Co-Authored-By: Claude <noreply@anthropic.com>
Tests for using_swc? and SWC dependency installation were failing
in the "minimum" CI environment (Shakapacker 8.2.0) because they
expected SWC to be the default, but SWC is only default for
Shakapacker 9.3.0+.

Changes:
- Stub ReactOnRails::PackerUtils in generator_helper_spec.rb tests
  that check default SWC behavior (fresh install, missing config,
  parse errors) to simulate Shakapacker 9.3.0+
- Update install_generator_spec.rb to check actual Shakapacker
  version and expect appropriate transpiler dependencies

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

Co-Authored-By: Claude <noreply@anthropic.com>
@justin808 justin808 force-pushed the jg/swc-detection-fix branch from 457ee41 to d02af07 Compare December 9, 2025 05:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve SWC compiler detection and configuration for Shakapacker 9.3.0+

2 participants