Skip to content

Conversation

@justin808
Copy link
Member

@justin808 justin808 commented Nov 2, 2025

Summary

Updates all references to shakapacker from version 8.2.0 to 9.3.0 across the codebase.

Changes

  • Updated Gemfile.development_dependencies to require shakapacker 9.3.0
  • Updated spec/dummy/package.json devDependencies to shakapacker 9.3.0
  • Updated lib/react_on_rails/packer_utils.rb async loading version check to 9.3.0
  • Updated rakelib/shakapacker_examples.rake to use >= 9.3.0 for generated examples
  • Updated script/convert to reference shakapacker 9.3.0
  • Updated spec/react_on_rails/packer_utils_spec.rb test expectations to match new version
  • Updated Gemfile.lock and yarn.lock files after bundle/yarn install

Testing

  • All RuboCop checks pass with no offenses
  • Bundle install and yarn install completed successfully
  • Git hooks (trailing-newlines, prettier, rubocop, autofix) all passed

🤖 Generated with Claude Code


This change is Reviewable

Summary by CodeRabbit

Release Notes

  • New Features

    • Added SWC compiler as an alternative to Babel for faster React builds.
    • Automatic package manager detection for npm, yarn, pnpm, and bun.
    • Enhanced ESLint configuration with new rules for server component files.
  • Bug Fixes

    • Fixed CSS Modules compatibility for bundler 9.0.
    • Improved React Server Components handling.
  • Dependencies

    • Upgraded bundler to version 9.3.0.
    • Added SWC build tool integration.
    • Updated test dependencies.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 2, 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 24 minutes and 15 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 a04a12f and a229abc.

⛔ Files ignored due to path filters (5)
  • Gemfile.lock is excluded by !**/*.lock
  • react_on_rails_pro/spec/dummy/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • react_on_rails_pro/spec/execjs-compatible-dummy/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • spec/dummy/Gemfile.lock is excluded by !**/*.lock
  • spec/dummy/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (25)
  • .github/workflows/lint-js-and-ruby.yml (1 hunks)
  • .github/workflows/pro-integration-tests.yml (3 hunks)
  • Gemfile.development_dependencies (1 hunks)
  • TURBO_NAVIGATION_TEST_ISSUE.md (1 hunks)
  • eslint-rules/README.md (1 hunks)
  • eslint.config.ts (1 hunks)
  • lib/generators/react_on_rails/base_generator.rb (3 hunks)
  • lib/generators/react_on_rails/generator_helper.rb (2 hunks)
  • lib/generators/react_on_rails/install_generator.rb (6 hunks)
  • lib/react_on_rails/dev/pack_generator.rb (1 hunks)
  • package-scripts.yml (1 hunks)
  • packages/react-on-rails-pro/src/RSCProvider.tsx (3 hunks)
  • packages/react-on-rails-pro/src/RSCRoute.tsx (4 hunks)
  • rakelib/shakapacker_examples.rake (1 hunks)
  • react_on_rails_pro/spec/dummy/client/app/components/HelloWorld.module.scss (1 hunks)
  • react_on_rails_pro/spec/dummy/client/app/ror-auto-load-components/AsyncOnServerSyncOnClient.server.tsx (0 hunks)
  • react_on_rails_pro/spec/dummy/client/app/ror-auto-load-components/LazyApolloGraphQLApp.server.tsx (0 hunks)
  • react_on_rails_pro/spec/dummy/client/app/ror-auto-load-components/ServerComponentRouter.server.tsx (0 hunks)
  • react_on_rails_pro/spec/dummy/package.json (2 hunks)
  • react_on_rails_pro/spec/execjs-compatible-dummy/Gemfile (2 hunks)
  • react_on_rails_pro/spec/execjs-compatible-dummy/package.json (1 hunks)
  • script/convert (1 hunks)
  • spec/dummy/client/app/components/HelloWorld.module.scss (1 hunks)
  • spec/dummy/config/webpack/commonWebpackConfig.js (1 hunks)
  • spec/dummy/package.json (2 hunks)

Walkthrough

This PR upgrades Shakapacker to 9.3.0, introduces SWC compiler detection with conditional dependency management, adds package manager detection logic, updates CSS Modules configuration for Shakapacker 9.0 compatibility, integrates React Server Components in the Pro package with updated type signatures, and refactors generator dependency installation workflows.

Changes

Cohort / File(s) Change Summary
Shakapacker version upgrades to 9.3.0
Gemfile.development_dependencies, script/convert, rakelib/shakapacker_examples.rake, react_on_rails_pro/Gemfile.development_dependencies, react_on_rails_pro/spec/dummy/package.json, react_on_rails_pro/spec/execjs-compatible-dummy/package.json, react_on_rails_pro/spec/execjs-compatible-dummy/Gemfile
Updated Shakapacker from 8.x to 9.3.0 or 9.3.0-compatible constraints across gem and npm declarations.
Package dependency and SWC support additions
spec/dummy/package.json, react_on_rails_pro/spec/dummy/package.json, react_on_rails_pro/spec/execjs-compatible-dummy/package.json
Added devDependencies for @swc/core ^1.7.0 and swc-loader ^0.2.6 to support SWC compiler.
Generator enhancements for compiler and package manager detection
lib/generators/react_on_rails/base_generator.rb, lib/generators/react_on_rails/install_generator.rb, lib/generators/react_on_rails/generator_helper.rb
Added using_swc? method for SWC detection via YAML config parsing, detect_package_manager_and_exact_flag for lock file detection (npm, yarn, pnpm, bun), and refactored dependency installation to use detected package manager with exact version flags.
Webpack CSS Modules compatibility for Shakapacker 9.0
spec/dummy/config/webpack/commonWebpackConfig.js, react_on_rails_pro/spec/dummy/config/webpack/commonWebpackConfig.js
Added second pass to configure CSS Modules with default exports (modules.namedExport = false) and camelCase export convention for Shakapacker 9.0 compatibility.
Capybara version constraint
Gemfile.development_dependencies
Updated from gem "capybara" to gem "capybara", ">= 3.40".
React Server Components type updates
packages/react-on-rails-pro/src/RSCProvider.tsx, packages/react-on-rails-pro/src/RSCRoute.tsx
Refactored to use named ReactNode import and removed React namespace usage throughout type signatures; updated return and promise types from Promise<React.ReactNode> to Promise.
Server component directives
react_on_rails_pro/spec/dummy/client/app/ror-auto-load-components/AsyncOnServerSyncOnClient.server.tsx, react_on_rails_pro/spec/dummy/client/app/ror-auto-load-components/LazyApolloGraphQLApp.server.tsx, react_on_rails_pro/spec/dummy/client/app/ror-auto-load-components/ServerComponentRouter.server.tsx
Removed 'use client' directives from server component files.
SCSS imports for styling consistency
spec/dummy/client/app/components/HelloWorld.module.scss, react_on_rails_pro/spec/dummy/client/app/components/HelloWorld.module.scss
Added imports for app-variables.scss to bring SCSS variables into scope.
CI workflow updates
.github/workflows/lint-js-and-ruby.yml, .github/workflows/pro-integration-tests.yml
Updated "Detect dead code" step to use yarn run knip with --no-config-hints flag; added yalc publish steps for Pro package testing; replaced frozen-lockfile with --ignore-scripts for yarn install.
ESLint configuration and custom rules
eslint.config.ts, eslint-rules/README.md
Added top-level react-on-rails ESLint plugin configuration for no-use-client-in-server-files rule; added documentation for custom ESLint rule set.
Build tooling and utilities
package-scripts.yml, lib/react_on_rails/dev/pack_generator.rb
Updated prepack build step from npm to yarn; refactored pack generation system call to use single string command instead of separate arguments.
Documentation
TURBO_NAVIGATION_TEST_ISSUE.md
Added new markdown file detailing Turbo navigation JavaScript regression and Playwright E2E test plan.
Ruby version constraint
react_on_rails_pro/spec/execjs-compatible-dummy/Gemfile
Updated from ruby "3.3.7" to ruby ">= 3.0.0", "< 3.5.0".

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • SWC detection logic in lib/generators/react_on_rails/base_generator.rb — requires careful review of YAML parsing with error handling and graceful fallback to Babel
  • Package manager detection precedence in lib/generators/react_on_rails/generator_helper.rb — lock file detection order and multi-lock-file warning logic need validation
  • Webpack CSS Modules configuration changes across multiple commonWebpackConfig.js files — guard conditions for rule iteration and namedExport flag changes require verification
  • React Server Components type signature updates across Pro package TypeScript files — widespread ReactNode refactoring across multiple type definitions and imports
  • CI workflow yalc publishing logic in .github/workflows/pro-integration-tests.yml — new package publishing steps and yarn install flag changes need testing validation
  • Generator install flow refactoring in lib/generators/react_on_rails/install_generator.rb — package manager detection integration with system calls and error messaging

Possibly related issues

Possibly related PRs

Suggested reviewers

  • Judahmeek
  • AbanoubGhadban
  • alexeyr-ci

Poem

🐰 A bunny hops through Shakapacker's gate,
SWC speeds up, no more we wait,
CSS Modules dance their graceful stance,
React Server Components find their chance,
Nine-point-three, a version so fine—
This build's a masterpiece, carrot-divine! 🥕✨

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarizes the two main objectives: updating shakapacker to 9.3.0 and fixing RSC client component directives, which are reflected throughout the changeset.

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 2, 2025

Code Review: Update shakapacker to 9.3.0

Summary

This PR updates shakapacker from version 8.2.0 to 9.3.0 across the codebase. Overall, this is a well-executed dependency update with comprehensive test coverage updates. The changes are consistent and follow the project's conventions.

✅ Strengths

  1. Comprehensive Coverage: All relevant files have been updated consistently (Gemfiles, lockfiles, package.json, test specs, conversion scripts, rake tasks)

  2. Test Coverage: The PR properly updates test expectations in spec/react_on_rails/packer_utils_spec.rb to match the new version requirement.

  3. Follows Project Guidelines: Author mentions running RuboCop and git hooks, proper formatting maintained

  4. Dependency Updates: Both Gemfile.lock and yarn.lock properly updated with new version and transitive dependencies.

⚠️ Issues Found - Action Required

CRITICAL: Multiple references to version 8.2.0 were NOT updated in this PR but should be:

1. Documentation Files (Should be updated)

  • docs/api-reference/configuration.md:240, 247, 271, 272
  • docs/pro/major-performance-breakthroughs-upgrade-guide.md:94
  • docs/upgrading/release-notes/16.0.0.md:49, 51, 59, 90

2. Source Code Files (Should be updated)

  • lib/react_on_rails/configuration.rb:180
  • lib/react_on_rails/doctor.rb:716

3. Test Files (Should be reviewed/updated)

  • spec/react_on_rails/configuration_spec.rb:281, 284, 328, 331
  • spec/lib/react_on_rails/system_checker_spec.rb:165, 173

🤔 Questions

  1. Breaking Changes: What changed between 8.2.0 and 9.3.0? Have these been tested?

  2. Async Loading Requirement: Why does supports_async_loading? now require 9.3.0 instead of 8.2.0? This is significant and should be documented.

  3. Backwards Compatibility: Can users on 8.2.0 still use earlier react_on_rails versions?

📋 Recommendations

High Priority:

  1. Update all documentation to reference 9.3.0
  2. Update error/info messages in source code
  3. Update test specs for consistency
  4. Add CHANGELOG entry with migration guidance

Medium Priority:
5. Verify CI passes completely
6. Test with example apps
7. Document why 9.3.0 is now required

Code Quality Score: 7/10

Great work on the thorough dependency update! Just needs the additional reference updates for completeness.

@claude
Copy link

claude bot commented Nov 2, 2025

Code Review: Update shakapacker to 9.3.0

Overall Assessment

APPROVED - This is a well-executed dependency update with proper version management and good backward compatibility considerations.


Strengths

1. Excellent Version Strategy 🎯

The second commit demonstrates excellent understanding of semantic versioning:

  • Correctly keeps supports_async_loading? check at 8.2.0 (when feature was introduced)
  • Allows users on any version >= 8.2.0 to use async loading
  • Prevents forcing users to upgrade unnecessarily

Code reference: lib/react_on_rails/packer_utils.rb:36

2. Comprehensive Update Coverage ✅

All necessary files were updated:

  • Development dependencies (Gemfile)
  • Test fixtures (spec/dummy/)
  • Rake tasks for example generation
  • Conversion scripts
  • Lock files properly regenerated

3. Good Testing Hygiene 🧪

  • Tests correctly validate the version check stays at 8.2.0
  • Version constants remain properly defined
  • Test coverage remains intact

Observations & Recommendations

1. Missing CHANGELOG Entry 📝

Issue: No update to CHANGELOG.md for this version bump

Recommendation: Add an entry documenting this upgrade, especially noting:

  • Shakapacker upgraded from 8.2.0 to 9.3.0
  • Backward compatibility maintained for async loading (8.2.0+)
  • Any new features from Shakapacker 9.x that users can leverage

2. Dependency Updates in yarn.lock 🔍

Observation: The update introduces new dependencies:

  • flat@5.0.2 (new)
  • webpack-merge@5.10.0 (upgraded from 5.x)
  • yargs@17.7.2 (now required)

Question: Have these been tested for compatibility? The new dependencies appear to be internal Shakapacker requirements, which should be fine, but worth verifying CI passes.

3. Generated Examples Version Constraint ⚠️

Code: rakelib/shakapacker_examples.rake:37

Concern: This forces generated examples to require >= 9.3.0, which may be stricter than necessary.

Question: Should this be >= 8.2.0 or >= 7.0.0 to align with actual minimum version requirements (MINIMUM_SHAKAPACKER_VERSION_FOR_AUTO_BUNDLING = 7.0.0)?

Impact: Users generating new examples will be forced to use 9.3.0+, even if their actual requirements are lower.

4. Documentation Updates 📖

Files that likely reference version requirements and may need updates:

  • docs/upgrading/release-notes/ - Should document this change
  • docs/api-reference/configuration.md - May reference minimum versions
  • README/Getting Started guides - If they mention specific Shakapacker versions

5. Breaking Changes from Shakapacker? 🔍

Recommendation: Verify the Shakapacker 8.2.0 → 9.3.0 upgrade doesn't introduce breaking changes that affect react_on_rails users. The major version bump (8→9) suggests potential breaking changes.


Security Considerations

✅ No security concerns identified:

  • Upgrading to latest stable dependency version
  • No new suspicious dependencies
  • All changes are version bumps of existing, trusted packages

Performance Considerations

✅ No performance concerns:

  • Dependency updates should be neutral or positive for performance
  • No algorithmic changes in the codebase
  • Lock file properly regenerated to ensure consistent installs

Testing Recommendations

  1. Run Full Test Suite: Ensure all tests pass with the new version
  2. Test Generated Examples: Verify rake shakapacker_examples:gen_all works correctly
  3. Integration Testing: Test with a real app using different Shakapacker versions (8.2.0, 9.0.0, 9.3.0)
  4. SSR Testing: Verify server-side rendering still works correctly (shakapacker version checks are involved)

Action Items

High Priority:

  • Add CHANGELOG.md entry
  • Verify CI passes (RuboCop, tests, integration tests)

Medium Priority:

  • Review generated examples version constraint (consider allowing >= 7.0.0 or >= 8.2.0)
  • Update documentation mentioning Shakapacker version requirements
  • Verify no breaking changes from Shakapacker 8.x → 9.x affect users

Low Priority:

  • Consider adding release notes explaining what users get from Shakapacker 9.3.0

Code Quality: ⭐⭐⭐⭐⭐ (5/5)

  • Follows project conventions perfectly
  • RuboCop clean
  • Files properly end with newlines
  • Formatting is consistent

Great work on maintaining backward compatibility while upgrading! 🎉


🤖 Review generated with Claude Code

@claude
Copy link

claude bot commented Nov 2, 2025

Code Review: Update shakapacker to 9.3.0

Summary

This PR updates the shakapacker dependency from version 8.2.0 to 9.3.0 across the codebase. The changes are systematic and well-documented.


✅ Strengths

  1. Comprehensive Coverage: All relevant files have been updated consistently:

    • Gemfile dependencies
    • package.json files
    • Rake task generators
    • Conversion scripts
    • Lock files (Gemfile.lock, yarn.lock)
  2. Good Documentation: The PR description clearly lists all changes and confirms testing has been performed (RuboCop, bundle install, yarn install, git hooks).

  3. Consistent Version References: The update correctly maintains the version check at lib/react_on_rails/packer_utils.rb:36 which checks for async loading support (still checking against "8.2.0" as the minimum requirement, which is correct).

  4. Test Coverage: The existing test suite at spec/react_on_rails/packer_utils_spec.rb already validates version checking logic and should catch any breaking changes.


⚠️ Potential Issues & Recommendations

1. Documentation References Need Updating

Several documentation files still reference version 8.2.0 as examples/requirements. While these may be intentional (showing minimum versions), they should be reviewed:

  • docs/api-reference/configuration.md:240: Comments about async loading support
  • docs/api-reference/configuration.md:247: Version compatibility table
  • docs/upgrading/release-notes/16.0.0.md:49-90: Multiple references to 8.2.0 as the async loading threshold
  • docs/pro/major-performance-breakthroughs-upgrade-guide.md:94: Performance documentation

Recommendation: Consider whether these docs should:

  • Keep referencing 8.2.0 as the minimum version for async support (correct from a backward compatibility perspective)
  • Add a note recommending upgrade to 9.3.0+ for latest features
  • Update examples to show current best practices with 9.3.0

2. Missing Changelog Entry

The PR doesn't appear to include a CHANGELOG.md entry. According to the repository's patterns, version updates typically warrant a changelog entry.

Recommendation: Add an entry to CHANGELOG.md documenting this upgrade, especially if there are any behavioral changes or new features available in Shakapacker 9.3.0.

3. Dependency Breaking Changes Not Validated

The jump from 8.2.0 to 9.3.0 skips several minor versions (8.3, 9.0, 9.1, 9.2). The yarn.lock diff shows new dependencies:

  • flat@^5.0.2 (new transitive dependency)
  • webpack-merge@^5.8.0 (version range update from ^5.7.3)
  • yargs@^17.7.2 (new transitive dependency)

Recommendation:

  • Review the Shakapacker changelog for versions 8.3.0 through 9.3.0 to identify any breaking changes
  • Verify that existing webpack configurations remain compatible
  • Test the dev server and production builds thoroughly
  • Ensure SSR (server-side rendering) still works correctly

4. Test Coverage Gap

While packer_utils_spec.rb tests the version checking logic, there don't appear to be integration tests that validate:

  • Async script loading still works with 9.3.0
  • Webpack dev server integration remains functional
  • Manifest generation/lookup works correctly

Recommendation: Consider adding integration tests or at minimum, manually verify these critical features in the dummy app.

5. Generated Examples Consideration

The update changes rakelib/shakapacker_examples.rake:37 to require >= 9.3.0 for generated examples. This means:

  • Users running the examples generator will now require 9.3.0+
  • This could break workflows for users on older versions

Recommendation: Verify this is intentional and consider backward compatibility implications.


🔒 Security Considerations

No security concerns identified. Upgrading to a newer version generally includes security fixes, which is positive.


⚡ Performance Considerations

  • Shakapacker 9.3.0 may include performance improvements over 8.2.0
  • The new webpack-merge version could have optimizations
  • No performance regressions expected, but worth monitoring in production

🧪 Testing Recommendations

  1. Manual Testing Checklist:

    • Run full test suite: rake
    • Test webpack dev server: Start dev server and verify HMR works
    • Test production build: rake shakapacker:compile
    • Test SSR: Verify server-side rendering functions correctly
    • Test generated examples: rake shakapacker_examples:gen_all
    • Test async script loading with component packs
    • Verify manifest.json generation and lookup
  2. CI Validation: Wait for all CI checks to pass before merging


📝 Code Quality

  • ✅ Follows repository conventions
  • ✅ All files end with newlines (per CLAUDE.md requirements)
  • ✅ No RuboCop violations reported
  • ✅ Consistent formatting throughout

Final Verdict

Approval Status: ⚠️ Conditional Approval

The code changes themselves are solid and well-executed. However, I recommend addressing these items before merging:

  1. MUST: Verify no breaking changes exist between 8.2.0 and 9.3.0 in Shakapacker
  2. SHOULD: Add CHANGELOG.md entry
  3. SHOULD: Review and update documentation references
  4. SHOULD: Run comprehensive manual testing per checklist above

The systematic nature of the changes gives confidence that nothing was missed, but the version jump is significant enough to warrant thorough validation.


🤖 Review generated by Claude Code

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 (1)
rakelib/shakapacker_examples.rake (1)

37-37: Consider using pessimistic version constraint ~> 9.3 for better compatibility.

The >= 9.3.0 constraint allows any future version including potentially incompatible major versions (10.x, 11.x). Using ~> 9.3 would allow patch and minor updates within the 9.x line while preventing breaking changes from future major versions.

Apply this diff to use a pessimistic version constraint:

-      sh_in_dir(example_type.dir, "echo \"gem 'shakapacker', '>= 9.3.0'\" >> #{example_type.gemfile}")
+      sh_in_dir(example_type.dir, "echo \"gem 'shakapacker', '~> 9.3'\" >> #{example_type.gemfile}")
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a59bbb7 and 752456c.

⛔ Files ignored due to path filters (3)
  • Gemfile.lock is excluded by !**/*.lock
  • spec/dummy/Gemfile.lock is excluded by !**/*.lock
  • spec/dummy/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (5)
  • Gemfile.development_dependencies (1 hunks)
  • lib/generators/react_on_rails/templates/base/base/config/shakapacker.yml (1 hunks)
  • rakelib/shakapacker_examples.rake (1 hunks)
  • script/convert (1 hunks)
  • spec/dummy/package.json (2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{js,jsx,ts,tsx,css,scss,json,yml,yaml,md}

📄 CodeRabbit inference engine (CLAUDE.md)

Prettier is the sole authority for formatting all non-Ruby files; never manually format them

Files:

  • lib/generators/react_on_rails/templates/base/base/config/shakapacker.yml
  • spec/dummy/package.json
{Gemfile,Rakefile,config.ru,**/*.{rb,rake,gemspec,ru}}

📄 CodeRabbit inference engine (CLAUDE.md)

{Gemfile,Rakefile,config.ru,**/*.{rb,rake,gemspec,ru}}: All Ruby code must pass RuboCop with zero offenses before commit/push
RuboCop is the sole authority for Ruby file formatting; never manually format Ruby files

Files:

  • rakelib/shakapacker_examples.rake
🧠 Learnings (6)
📓 Common learnings
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 1687
File: spec/dummy/package.json:0-0
Timestamp: 2025-01-23T18:20:45.824Z
Learning: When adding or updating dependencies in spec/dummy/package.json, maintain version consistency with other package.json files in the codebase to avoid potential version conflicts.
📚 Learning: 2025-09-16T08:01:11.146Z
Learnt from: justin808
Repo: shakacode/react_on_rails PR: 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/generators/react_on_rails/templates/base/base/config/shakapacker.yml
📚 Learning: 2025-04-26T21:55:55.874Z
Learnt from: alexeyr-ci2
Repo: shakacode/react_on_rails PR: 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/shakapacker.yml
  • script/convert
📚 Learning: 2025-02-12T16:38:06.537Z
Learnt from: Romex91
Repo: shakacode/react_on_rails PR: 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/generators/react_on_rails/templates/base/base/config/shakapacker.yml
  • script/convert
📚 Learning: 2025-07-08T05:57:29.630Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1745
File: node_package/src/RSCRequestTracker.ts:8-14
Timestamp: 2025-07-08T05:57:29.630Z
Learning: The global `generateRSCPayload` function in React on Rails Pro (RORP) is provided by the framework during rendering requests, not implemented in application code. The `declare global` statements are used to document the expected interface that RORP will inject at runtime.

Applied to files:

  • lib/generators/react_on_rails/templates/base/base/config/shakapacker.yml
📚 Learning: 2025-01-23T18:20:45.824Z
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 1687
File: spec/dummy/package.json:0-0
Timestamp: 2025-01-23T18:20:45.824Z
Learning: When adding or updating dependencies in spec/dummy/package.json, maintain version consistency with other package.json files in the codebase to avoid potential version conflicts.

Applied to files:

  • spec/dummy/package.json
  • script/convert
🔇 Additional comments (4)
Gemfile.development_dependencies (1)

3-3: LGTM!

The shakapacker version update is consistent with other changes in this PR. Exact version pinning ensures reproducible builds across development environments.

spec/dummy/package.json (2)

57-57: No issues found — swc-loader 0.2.6 is compatible with webpack 5.72.0 and shakapacker.

swc-loader@0.2.6 is compatible with Webpack 5 (including 5.72.0), and Shakapacker v6.1.1+ includes opt-in SWC support. Since shakapacker 9.3.0 is newer than 6.1.1+, the added dependency is appropriate for this configuration.


32-32: No compatibility issues detected.

Shakapacker 9.3.0 recommends @swc/core ^1.3.0, and the specified version ^1.7.0 falls within this compatible range. The configuration is correct.

script/convert (1)

20-22: Shakapacker 9.3.0 is still in beta—verify if intentional and test API compatibility.

The codebase extensively uses shakapacker APIs that could break with major version changes:

  • Ruby: Shakapacker::Instance, Shakapacker::Configuration, Shakapacker::DevServer, Shakapacker::Manifest, exception handling
  • JavaScript: generateWebpackConfig, webpackConfig, inliningCss, config, devServer, merge, Babel preset imports

Shakapacker 9.3.0 is still in beta—no stable release notes or formal breaking changes documentation has been published yet. Before upgrading:

  1. Confirm 9.3.0 beta is acceptable for your use case (consider using the latest stable version instead)
  2. Review the 9.3.0 beta releases and PRs on the Shakapacker repository to identify any API-breaking changes affecting the patterns found in the codebase
  3. Run full integration tests after updating, including webpack config generation and bundle loading

@claude
Copy link

claude bot commented Nov 2, 2025

Pull Request Review: Update shakapacker to 9.3.0

Overview

This PR updates Shakapacker from version 8.2.0 to 9.3.0 across the codebase. Overall, the changes are well-structured and comprehensive. The PR description indicates that all linting checks pass and git hooks succeeded.


Strengths

1. Comprehensive Version Updates

All version references have been properly updated across:

  • Gemfile.development_dependencies
  • Both Gemfile.lock files (root and spec/dummy)
  • package.json (spec/dummy)
  • rakelib/shakapacker_examples.rake
  • script/convert

2. Configuration Changes Are Correct

The shakapacker.yml template correctly updates from the deprecated webpack_loader setting to the new javascript_transpiler setting:

# OLD (v8.2.0):
webpack_loader: 'babel'

# NEW (v9.3.0):
javascript_transpiler: "swc"  # Default, 20x faster

This change aligns with Shakapacker 9.x's improved configuration naming and defaults to SWC for better performance.

3. Proper Dependency Additions

The PR correctly adds the required SWC dependencies to spec/dummy/package.json:

  • @swc/core: ^1.7.0
  • swc-loader: ^0.2.6

These are necessary for the new default transpiler configuration.

4. Lock Files Updated Correctly

Both yarn.lock files show proper resolution of:

  • shakapacker 9.3.0 with new dependencies (webpack-merge, yargs)
  • All SWC platform-specific binaries
  • Consistent dependency tree

⚠️ Issues & Concerns

1. 🔴 CRITICAL: Hardcoded Version Check Not Updated

Location: lib/react_on_rails/packer_utils.rb:36

def self.supports_async_loading?
  shakapacker_version_requirement_met?("8.2.0")
end

Issue: This method still checks for version 8.2.0, which was the version that introduced async loading support. While this isn't technically wrong (9.3.0 > 8.2.0 so the check passes), it creates maintenance confusion.

Recommendation: Consider whether this should be updated or documented. The check is functionally correct but may confuse future maintainers who see 8.2.0 referenced in code while the minimum required version is now 9.3.0.

Consideration: If 8.2.0 was indeed the version that introduced async loading, keeping this check at 8.2.0 is semantically correct. However, if there are breaking changes between 8.2.0 and 9.3.0, this might need updating.

2. 📝 Documentation References Need Review

The grep search found "8.2.0" still referenced in these files (not changed in this PR):

  • docs/pro/major-performance-breakthroughs-upgrade-guide.md
  • docs/upgrading/release-notes/16.0.0.md
  • docs/api-reference/configuration.md

Recommendation: Review these documentation files to determine if they need updating for the new minimum version, or if they're correctly documenting historical information.

3. ❓ Breaking Changes Between 8.2.0 and 9.3.0

Question: The PR description doesn't mention if there are any breaking changes between Shakapacker 8.2.0 and 9.3.0.

Recommendation:

  • Add a note about compatibility/breaking changes (if any)
  • Test that the upgrade works smoothly in generated examples
  • Verify that the configuration migration from webpack_loader to javascript_transpiler is backward compatible

4. Test Coverage Consideration

Location: spec/react_on_rails/packer_utils_spec.rb:80-92

The test for supports_async_loading? is present and tests the 8.2.0 version check. This is good, but consider adding an integration test that verifies:

  • The new SWC transpiler configuration works correctly
  • Async loading still functions properly with 9.3.0

🔍 Code Quality & Best Practices

Positive Observations:

  1. ✅ All Ruby files maintain frozen_string_literal: true
  2. ✅ Consistent version references across the codebase
  3. ✅ Lock files properly committed with dependency updates
  4. ✅ Generator templates updated to use new version
  5. ✅ Test suite expectations maintained (tests still reference 8.2.0 where semantically appropriate)

Formatting Compliance:

According to CLAUDE.md, this PR should:

  • ✅ Have run bundle exec rubocop (confirmed in PR description)
  • ✅ Ensure files end with newlines (git hooks passed)
  • ✅ Use Prettier/RuboCop for formatting (autofix hooks passed)

🎯 Recommendations

High Priority:

  1. Clarify the version check in packer_utils.rb:36 - Either update it to 9.3.0 or add a comment explaining why 8.2.0 is the correct semantic version to check
  2. Document breaking changes - Add information about Shakapacker 8.2.0 → 9.3.0 compatibility
  3. Review documentation files - Check if docs need updating for the new minimum version

Medium Priority:

  1. Integration testing - Verify that generated examples work with new SWC configuration
  2. Configuration migration - Confirm that existing projects using webpack_loader will see clear migration instructions

Low Priority:

  1. Changelog entry - Consider adding this upgrade to CHANGELOG.md under Unreleased
  2. Performance validation - Since SWC is now the default (20x faster claim), validate this in tests

🔐 Security Considerations

✅ No security concerns identified. The new SWC dependencies are from official packages with good reputation.


📊 Performance Considerations

Positive Impact: Switching from Babel to SWC as the default transpiler should provide significant build performance improvements (as noted in the configuration comments: "20x faster").


Final Assessment

Approval Status: ✅ Approve with Minor Suggestions

This is a solid dependency upgrade PR with comprehensive changes. The main concerns are:

  1. Clarification needed on the 8.2.0 version check in supports_async_loading?
  2. Documentation review recommended
  3. Breaking changes should be documented

The code changes are correct and follow project conventions. The configuration updates properly reflect Shakapacker 9.3.0's new settings.


Great job on this upgrade! The thoroughness of updating all references and properly adding new dependencies shows attention to detail. 🎉

Generated with Claude Code - Technical accuracy prioritized ✨

@claude
Copy link

claude bot commented Nov 2, 2025

PR Review: Update shakapacker to 9.3.0

Overall Assessment

This is a well-executed dependency upgrade that properly handles the breaking changes introduced in Shakapacker 9.x. The PR demonstrates good attention to compatibility and includes all necessary configuration updates. ✅


Code Quality & Best Practices

✅ Strengths

  1. Comprehensive Version Update

    • All version references updated consistently across Gemfiles, package.json, and supporting scripts
    • Both Ruby and JavaScript dependency files properly updated with matching lock files
  2. Breaking Change Mitigation

    • Excellent handling of the CSS Modules breaking change (namedExport: true default in 9.0)
    • The backward compatibility fix in commonWebpackConfig.js:29-41 is well-commented and explains the rationale
    • Smart decision to keep async loading check at 8.2.0 rather than bumping to 9.3.0 (allows broader version compatibility)
  3. Configuration Updates

    • Template updated to use the new javascript_transpiler setting instead of deprecated webpack_loader
    • Good documentation in shakapacker.yml comments explaining the transpiler options and their performance characteristics
  4. Documentation

    • Clear commit messages explaining the why behind each change
    • Inline comments document breaking changes and compatibility fixes

Potential Issues & Concerns

⚠️ Medium Priority

  1. CSS Modules Configuration Mutation (commonWebpackConfig.js:32-41)

    Issues:

    • Directly mutating the webpack config object could be fragile
    • The check loader.loader.includes('css-loader') is string-based and could match unintended loaders
    • No validation that loader.options.modules is actually an object before setting properties

    Suggestions:

    • Consider using a more explicit check: loader.loader === 'css-loader' or path-based comparison
    • Add defensive checks: ensure modules is an object before modifying
    • Alternative: Configure this in shakapacker.yml if possible, or use webpack-merge to override config more explicitly
  2. Missing Test Coverage

    • No new tests added to verify CSS Modules behavior with the new configuration
    • Should add tests to ensure default imports still work
    • Should test that the transpiler change (babel → swc) doesn't break existing functionality

Performance Considerations

✅ Positive

  1. SWC Adoption
    • Switching to SWC (20x faster than Babel) is excellent for build performance
    • Properly added @swc/core and swc-loader dependencies

Security Concerns

✅ No Critical Issues Found

  1. Dependency Versions

    • Shakapacker 9.3.0 is the latest version (good for security patches)
    • SWC dependencies pulled from npm registry with integrity hashes in yarn.lock ✓
  2. Configuration Changes

    • No security-sensitive configuration changes detected
    • CSS Modules configuration is cosmetic (export style), not security-related

Summary

Approve with Minor Suggestions 👍

This PR successfully upgrades Shakapacker to 9.3.0 with proper handling of breaking changes. The main improvement areas are:

  1. Add safety checks to the CSS Modules configuration mutation
  2. Add test coverage for CSS Modules and SWC transpilation
  3. Verify all tests pass before merging

The code quality is high, and the migration strategy is sound. The breaking change mitigation demonstrates good understanding of the upgrade impact on downstream users.

Great work handling a complex dependency upgrade! The attention to backward compatibility and clear documentation will make this upgrade smooth for users of the gem.

@claude
Copy link

claude bot commented Nov 2, 2025

Code Review: Shakapacker 9.3.0 Upgrade

Summary

This PR successfully upgrades Shakapacker from 8.2.0 to 9.3.0 with proper handling of breaking changes. The changes are well-structured across 4 commits that logically progress through the upgrade process.


✅ Strengths

1. Excellent Commit Structure

The PR follows a logical progression through initial version bump, backward compatibility correction, SWC support, and CSS Modules fix. This incremental approach makes the changes easy to review and understand.

2. Backward Compatibility Preservation

The second commit correctly reverts the async loading version check to 8.2.0 in lib/react_on_rails/packer_utils.rb. This is the right decision - users with shakapacker >= 8.2.0 should be able to use async loading.

3. Proper Handling of Breaking Changes

SWC Transpiler Support: Added required dependencies (@swc/core, swc-loader) and updated template to use new javascript_transpiler setting with good documentation about performance benefits.

CSS Modules Compatibility: The webpack config fix properly addresses Shakapacker 9.0 breaking change by setting namedExport: false to preserve compatibility with existing default imports.


🔍 Issues & Recommendations

1. Missing CSS Modules Fix in Generator Template

The CSS Modules compatibility fix is applied to spec/dummy/config/webpack/commonWebpackConfig.js but needs verification in generator templates. New projects should have this fix.

2. Documentation Gaps

Missing: CHANGELOG entry, migration guide for users upgrading from 8.x to 9.x, documentation of breaking changes.

Recommendation: Add CHANGELOG entry documenting the upgrade, breaking changes (SWC as default transpiler, CSS Modules configuration), and migration steps.

3. Test Coverage

Missing: Tests for SWC transpiler configuration, CSS Modules with default imports, integration tests for 9.3.0 upgrade.

4. Version Conflicts

Generated examples require >= 9.3.0 but main gem uses = 9.3.0 (exact version). Consider using ~> 9.3 for flexibility or document why exact version is required.

5. Security

SWC dependencies use caret ranges which is good for security patches. Current approach is reasonable.


🎯 Performance

SWC is 20x faster than Babel - significant improvement. Consider adding before/after build time metrics to quantify benefits.


📋 Action Items Before Merge

  1. SHOULD ADD: CHANGELOG entry with migration guide
  2. SHOULD ADD: Verify CSS Modules fix in generator templates
  3. SHOULD ADD: Tests for new transpiler configuration
  4. NICE TO HAVE: Document version pinning strategy
  5. NICE TO HAVE: Build performance benchmarks

🎓 Code Quality Assessment

  • Code Quality: ⭐⭐⭐⭐⭐ Clean, well-structured
  • Testing: ⭐⭐⭐ Could benefit from additional tests
  • Documentation: ⭐⭐ Needs CHANGELOG and migration guide
  • Backward Compatibility: ⭐⭐⭐⭐⭐ Excellent
  • Security: ⭐⭐⭐⭐ Good dependency choices
  • Performance: ⭐⭐⭐⭐⭐ Major improvement with SWC

✅ Final Recommendation

Approve with Minor Improvements Requested

The upgrade is well-executed, especially the handling of breaking changes. Main improvements needed are documentation (CHANGELOG) and ensuring generator templates include the CSS Modules fix.

Great work on backward compatibility preservation and logical commit progression! 🎉

@claude
Copy link

claude bot commented Nov 2, 2025

Code Review - PR #1896: Update shakapacker to 9.3.0

I've completed a comprehensive review of this PR. Overall, this is a well-executed dependency upgrade with appropriate configuration updates. Here's my detailed feedback:


Positive Findings

1. Comprehensive Version Updates

  • All references to shakapacker updated consistently from 8.2.0 to 9.3.0 across:
    • Gemfile.development_dependencies
    • Rake tasks (shakapacker_examples.rake)
    • Conversion scripts (script/convert)
    • Lock files (Gemfile.lock, spec/dummy/Gemfile.lock, yarn.lock)

2. SWC Integration (Performance Improvement)

  • ✅ Added @swc/core and swc-loader as dev dependencies in generators
  • ✅ Updated shakapacker.yml to use javascript_transpiler: "swc" (20x faster than Babel)
  • This is a significant performance improvement for build times

3. Breaking Change Mitigation

  • ✅ Excellent work handling the CSS Modules breaking change in spec/dummy/config/webpack/commonWebpackConfig.js:29-43
  • The code explicitly sets namedExport: false to maintain backward compatibility
  • Clear comments explain the rationale

4. Configuration Updates

  • Updated shakapacker.yml template with better documentation
  • Changed webpack_loaderjavascript_transpiler (naming improvement)
  • Added helpful comment about rspack behavior

⚠️ Issues & Concerns

1. PR Description Inaccuracy ⚠️

The PR summary claims:

"Updated lib/react_on_rails/packer_utils.rb async loading version check to 9.3.0"
"Updated spec/react_on_rails/packer_utils_spec.rb test expectations to match new version"

However, these files are NOT in the diff. The actual file list shows:

  • ❌ lib/react_on_rails/packer_utils.rb - NOT modified
  • ❌ spec/react_on_rails/packer_utils_spec.rb - NOT modified

Impact: The version check in lib/react_on_rails/packer_utils.rb:36 still references "8.2.0":

def self.supports_async_loading?
  shakapacker_version_requirement_met?("8.2.0")
end

Question: Should this be updated to "9.3.0" or is "8.2.0" the correct minimum version requirement?

2. Missing Test Coverage ⚠️

  • No new tests added to verify the CSS Modules configuration changes
  • Consider adding integration tests to ensure namedExport: false behavior works correctly

3. Dependency Version Constraints

In package.json, consider using caret ranges for better flexibility:

"@swc/core": "^1.7.0"  // ✅ Good - allows patch/minor updates
"swc-loader": "^0.2.6"  // ✅ Good
"shakapacker": "9.3.0"   // ⚠️ Consider "^9.3.0" for patch updates

🔍 Code Quality Assessment

Best Practices

  • Follows repository's formatting rules (RuboCop, Prettier)
  • Clear, descriptive comments in complex sections
  • Consistent code style

Performance Considerations

  • SWC migration will significantly improve build performance
  • No blocking or synchronous operations introduced

Security Concerns

  • No security issues identified
  • Dependency updates from reputable sources
  • No sensitive data exposure

📝 Recommendations

High Priority:

  1. Update PR description to accurately reflect the actual changes
  2. Clarify if packer_utils.rb version check should be updated to 9.3.0
  3. Verify the webpack configuration changes work across all examples

Medium Priority:

  1. Add tests for CSS Modules configuration behavior
  2. Document breaking changes in CHANGELOG/migration guide
  3. Consider semver ranges for npm packages

Low Priority:

  1. Add comments in generators explaining why SWC deps are added

Testing Notes

Per the PR description:

  • ✅ RuboCop checks passed
  • ✅ Bundle install successful
  • ✅ Yarn install successful
  • ✅ Git hooks passed

Recommended additional testing:

  • Run full test suite: rake
  • Test example generation: rake shakapacker_examples:gen_all
  • Verify CSS Modules imports work correctly
  • Test HMR with SWC transpiler

📊 Overall Assessment

Rating: ⭐⭐⭐⭐ (4/5)

This is a solid dependency upgrade with thoughtful handling of breaking changes. The main issue is the PR description inaccuracy, which should be corrected. Once that's clarified and the version check question is resolved, this should be ready to merge.

Recommendation: Request clarification on the packer_utils.rb version check, update PR description, then approve.


Review conducted following CLAUDE.md guidelines and React on Rails conventions.

@claude
Copy link

claude bot commented Nov 2, 2025

Pull Request Review: Update Shakapacker to 9.3.0

Summary

This PR updates Shakapacker from version 8.2.0 to 9.3.0 across the codebase. Overall, the update is well-structured and comprehensive. The changes are properly tested according to the PR description, and the automated git hooks have passed.

✅ Code Quality & Best Practices

Strengths:

  1. Comprehensive version updates: All version references have been systematically updated across Gemfiles, package.json, rake tasks, and scripts
  2. Backward compatibility handling: The webpack configuration properly handles breaking changes in Shakapacker 9.0's CSS Modules behavior (see commonWebpackConfig.js:29-43)
  3. Generator updates: Both base_generator.rb and install_generator.rb correctly add the new SWC dependencies (@swc/core and swc-loader)
  4. Template updates: The shakapacker.yml template properly documents the new javascript_transpiler setting with helpful comments
  5. Defensive programming: The engine.rb validation skip for missing package.json is a good safety measure during initial setup

Areas for Improvement:

1. Missing Test Update ⚠️

The hardcoded version check in lib/react_on_rails/packer_utils.rb:36 still references "8.2.0":

def self.supports_async_loading?
  shakapacker_version_requirement_met?("8.2.0")
end

Recommendation: This should likely be updated to "9.3.0" if async loading support requires the newer version, OR if 8.2.0 is still the correct minimum version for this feature, add a comment explaining why it wasn't updated:

def self.supports_async_loading?
  # Async loading has been supported since 8.2.0, no need to bump requirement
  shakapacker_version_requirement_met?("8.2.0")
end

2. Configuration Key Name Change

In shakapacker.yml, the configuration key changed from webpack_loader to javascript_transpiler. This is a breaking change for users upgrading.

Recommendation:

  • Consider adding a migration note in the CHANGELOG.md under "Unreleased" → "Breaking Changes"
  • Document this in any upgrade guides
  • Consider adding a deprecation warning if the old key is detected (though this may be outside the scope of this PR)

3. Documentation Updates Needed 📝

The PR doesn't update the CHANGELOG.md or any migration documentation.

Recommendation: Add an entry to CHANGELOG.md:

### Dependencies
- **Shakapacker Upgrade**: Updated Shakapacker from 8.2.0 to 9.3.0. [PR #1896](https://github.com/shakacode/react_on_rails/pull/1896) by [justin808](https://github.com/justin808).
  - Changed default JavaScript transpiler to SWC (20x faster than Babel)
  - Configuration key renamed from `webpack_loader` to `javascript_transpiler` in `shakapacker.yml`
  - Added automatic SWC dependencies to generator (`@swc/core`, `swc-loader`)
  - Fixed CSS Modules namedExport compatibility for existing projects

4. CSS Modules Compatibility Code

The CSS Modules fix in spec/dummy/config/webpack/commonWebpackConfig.js:29-43 is excellent for backward compatibility, but it's only in the spec/dummy app.

Question: Should this pattern be documented or added to the generator templates for users upgrading existing projects? Users with existing import styles from './styles.module.css' syntax will hit this breaking change.

🐛 Potential Bugs

Low Risk:

  1. Version check caching: The @version_checks hash in packer_utils.rb:31 could theoretically grow unbounded if many different version checks are performed, though this is unlikely in practice.

🔒 Security Concerns

No security concerns identified. The dependency updates include security patches from the Shakapacker project.

⚡ Performance Considerations

Positive Impact:

  1. SWC as default transpiler: This is a significant performance improvement (20x faster than Babel according to the comments)
  2. New webpack-merge dependency: Shakapacker 9.3.0 adds webpack-merge and yargs as direct dependencies, which is cleaner than relying on transitive dependencies

🧪 Test Coverage

Current Status:

  • ✅ RuboCop passes (per PR description)
  • ✅ Bundle/yarn install successful
  • ✅ Git hooks passed

Gaps:

  1. No test updates: The spec files were not updated, though the existing mocking approach should still work
  2. Integration tests: Consider running the example app generators to ensure they work with the new version (though this may have been done manually)

Recommendation: Run rake run_rspec:example_basic to verify the generators work correctly with the new Shakapacker version and SWC setup.

📋 Checklist Before Merge

  • Update CHANGELOG.md with dependency update entry
  • Review and clarify supports_async_loading? version check (line lib/react_on_rails/packer_utils.rb:36)
  • Consider documenting the CSS Modules namedExport fix for users upgrading
  • Verify example generators work: rake shakapacker_examples:gen_all
  • Run full test suite: rake all_but_examples

🎯 Overall Assessment

Rating: 8.5/10

This is a solid PR that handles the Shakapacker upgrade systematically. The main areas for improvement are documentation and clarifying the version requirements. The code changes are well-thought-out, particularly the CSS Modules backward compatibility fix.

Recommendation: Approve with minor changes requested (documentation updates and version check clarification).


Great work on this upgrade! The attention to backward compatibility details like the CSS Modules configuration shows careful consideration of the impact on existing users. 🚀

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 (2)
lib/react_on_rails/engine.rb (1)

12-14: Good defensive guard to handle missing package.json.

The validation skip when package.json doesn't exist prevents startup errors during initial setup, which aligns well with the Shakapacker installation workflow.

Minor suggestion: Consider renaming the variable to package_json_path for clarity, since it holds a path rather than JSON content.

Apply this diff to improve variable naming:

 # Skip validation if package.json doesn't exist yet (during initial setup)
-package_json = VersionChecker::NodePackageVersion.package_json_path
-next unless File.exist?(package_json)
+package_json_path = VersionChecker::NodePackageVersion.package_json_path
+next unless File.exist?(package_json_path)
spec/dummy/config/webpack/commonWebpackConfig.js (1)

32-43: Consider more robust loader detection and handle additional webpack rule formats.

The current implementation has a few limitations:

  1. Incomplete rule.use handling: Only processes rule.use when it's an array. Webpack rules can also have:

    • rule.use as a single loader object
    • rule.use as a function
    • rule.loader instead of rule.use
  2. Fragile loader matching: Using loader.loader.includes('css-loader') could match unintended paths (e.g., /custom-css-loader/). Consider a more precise check like loader.loader.endsWith('css-loader') or using a regex pattern.

Consider this more comprehensive approach:

-baseClientWebpackConfig.module.rules.forEach((rule) => {
-  if (Array.isArray(rule.use)) {
-    rule.use.forEach((loader) => {
-      if (loader.loader && loader.loader.includes('css-loader') && loader.options?.modules) {
-        // eslint-disable-next-line no-param-reassign
-        loader.options.modules.namedExport = false;
-        // eslint-disable-next-line no-param-reassign
-        loader.options.modules.exportLocalsConvention = 'camelCase';
-      }
-    });
-  }
-});
+const configureCssLoader = (loader) => {
+  if (loader.loader?.match(/css-loader/) && loader.options?.modules) {
+    // eslint-disable-next-line no-param-reassign
+    loader.options.modules.namedExport = false;
+    // eslint-disable-next-line no-param-reassign
+    loader.options.modules.exportLocalsConvention = 'camelCase';
+  }
+};
+
+baseClientWebpackConfig.module.rules.forEach((rule) => {
+  // Handle rule.use as array
+  if (Array.isArray(rule.use)) {
+    rule.use.forEach(configureCssLoader);
+  }
+  // Handle rule.use as single loader object
+  else if (rule.use && typeof rule.use === 'object') {
+    configureCssLoader(rule.use);
+  }
+  // Handle rule.loader (alternative to rule.use)
+  else if (rule.loader) {
+    configureCssLoader({ loader: rule.loader, options: rule.options });
+  }
+});
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 752456c and c088ba1.

📒 Files selected for processing (4)
  • lib/generators/react_on_rails/base_generator.rb (1 hunks)
  • lib/generators/react_on_rails/install_generator.rb (1 hunks)
  • lib/react_on_rails/engine.rb (1 hunks)
  • spec/dummy/config/webpack/commonWebpackConfig.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
{Gemfile,Rakefile,config.ru,**/*.{rb,rake,gemspec,ru}}

📄 CodeRabbit inference engine (CLAUDE.md)

{Gemfile,Rakefile,config.ru,**/*.{rb,rake,gemspec,ru}}: All Ruby code must pass RuboCop with zero offenses before commit/push
RuboCop is the sole authority for Ruby file formatting; never manually format Ruby files

Files:

  • lib/react_on_rails/engine.rb
  • lib/generators/react_on_rails/install_generator.rb
  • lib/generators/react_on_rails/base_generator.rb
**/*.{js,jsx,ts,tsx,css,scss,json,yml,yaml,md}

📄 CodeRabbit inference engine (CLAUDE.md)

Prettier is the sole authority for formatting all non-Ruby files; never manually format them

Files:

  • spec/dummy/config/webpack/commonWebpackConfig.js
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use ESLint for JS/TS code (lint via rake lint or yarn lint)

Files:

  • spec/dummy/config/webpack/commonWebpackConfig.js
🧠 Learnings (11)
📚 Learning: 2025-02-18T13:08:01.477Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 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/engine.rb
📚 Learning: 2025-10-23T17:22:01.074Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1875
File: lib/react_on_rails/utils.rb:112-124
Timestamp: 2025-10-23T17:22:01.074Z
Learning: In React on Rails, when Pro is installed but not licensed, the intended behavior is to raise an error on boot. The `react_on_rails_pro?` method validates licenses and should raise errors early (including during path resolution in methods like `server_bundle?`) to enforce licensing requirements rather than failing later with obscure errors.

Applied to files:

  • lib/react_on_rails/engine.rb
📚 Learning: 2025-02-13T16:50:26.861Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/turbolinksUtils.ts:34-36
Timestamp: 2025-02-13T16:50:26.861Z
Learning: In React on Rails, when checking for Turbolinks version 5 using `turbolinksVersion5()`, always ensure `Turbolinks` exists first by checking `turbolinksInstalled()` to prevent TypeError when accessing properties.

Applied to files:

  • lib/react_on_rails/engine.rb
📚 Learning: 2025-02-12T16:38:06.537Z
Learnt from: Romex91
Repo: shakacode/react_on_rails PR: 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/engine.rb
  • lib/generators/react_on_rails/install_generator.rb
  • lib/generators/react_on_rails/base_generator.rb
📚 Learning: 2025-01-23T18:20:45.824Z
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 1687
File: spec/dummy/package.json:0-0
Timestamp: 2025-01-23T18:20:45.824Z
Learning: When adding or updating dependencies in spec/dummy/package.json, maintain version consistency with other package.json files in the codebase to avoid potential version conflicts.

Applied to files:

  • lib/react_on_rails/engine.rb
  • lib/generators/react_on_rails/base_generator.rb
  • spec/dummy/config/webpack/commonWebpackConfig.js
📚 Learning: 2025-09-15T21:24:48.207Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1781
File: node_package/src/ClientSideRenderer.ts:82-95
Timestamp: 2025-09-15T21:24:48.207Z
Learning: In React on Rails, the force_load feature includes both explicit `data-force-load="true"` usage and the ability to hydrate components during the page loading state (`document.readyState === 'loading'`). Both capabilities require a Pro license, so the condition `!railsContext.rorPro && (isComponentForceLoaded || document.readyState === 'loading')` correctly gates both scenarios.

Applied to files:

  • lib/react_on_rails/engine.rb
📚 Learning: 2025-02-18T13:08:01.477Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 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:

  • lib/react_on_rails/engine.rb
📚 Learning: 2024-12-12T13:07:09.929Z
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 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/engine.rb
  • lib/generators/react_on_rails/base_generator.rb
📚 Learning: 2025-04-26T21:55:55.874Z
Learnt from: alexeyr-ci2
Repo: shakacode/react_on_rails PR: 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/engine.rb
  • lib/generators/react_on_rails/install_generator.rb
  • lib/generators/react_on_rails/base_generator.rb
📚 Learning: 2025-09-16T08:01:11.146Z
Learnt from: justin808
Repo: shakacode/react_on_rails PR: 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/generators/react_on_rails/install_generator.rb
  • spec/dummy/config/webpack/commonWebpackConfig.js
📚 Learning: 2025-07-08T05:57:29.630Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1745
File: node_package/src/RSCRequestTracker.ts:8-14
Timestamp: 2025-07-08T05:57:29.630Z
Learning: The global `generateRSCPayload` function in React on Rails Pro (RORP) is provided by the framework during rendering requests, not implemented in application code. The `declare global` statements are used to document the expected interface that RORP will inject at runtime.

Applied to files:

  • lib/generators/react_on_rails/install_generator.rb
🧬 Code graph analysis (1)
lib/react_on_rails/engine.rb (2)
lib/generators/react_on_rails/generator_helper.rb (1)
  • package_json (7-20)
lib/react_on_rails/version_checker.rb (1)
  • package_json_path (222-224)
⏰ 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). (11)
  • GitHub Check: build
  • GitHub Check: build-dummy-app-webpack-test-bundles (3.2, 20)
  • GitHub Check: build-dummy-app-webpack-test-bundles (3.4, 22)
  • GitHub Check: lint-js-and-ruby
  • GitHub Check: build-dummy-app-webpack-test-bundles
  • GitHub Check: rspec-package-tests (3.4, minimum)
  • GitHub Check: claude-review
  • GitHub Check: rspec-package-tests (3.2, latest)
  • GitHub Check: rspec-package-tests (3.2, minimum)
  • GitHub Check: rspec-package-tests (3.4, latest)
  • GitHub Check: build-dummy-app-webpack-test-bundles
🔇 Additional comments (3)
lib/generators/react_on_rails/base_generator.rb (1)

204-205: LGTM! SWC dependencies added for Shakapacker 9.x support.

The addition of @swc/core and swc-loader aligns with the Shakapacker 9.3.0 upgrade. These packages enable SWC-based transpilation as an alternative to Babel.

lib/generators/react_on_rails/install_generator.rb (1)

497-498: LGTM! SWC dependencies added for Shakapacker 9.x support.

These additions mirror the changes in base_generator.rb and correctly enable SWC transpilation support for the Shakapacker 9.3.0 upgrade.

spec/dummy/config/webpack/commonWebpackConfig.js (1)

29-31: ****

The review comment misidentifies the scope and impact of this change. The webpack configuration modification only affects the test app (spec/dummy), not the generator templates.

Analysis shows:

  • Generator templates use import * as style (named imports) and will continue using Shakapacker 9.0 defaults (namedExport: true)
  • The dummy test app uses import css/styles (default imports) and is now configured with namedExport: false to align with those imports
  • These are separate concerns with separate configurations

The change reconciles the dummy app's webpack configuration with its actual CSS Module import patterns—it's not breaking existing imports. The retrieved learning about namedExports: true remains valid for generated projects using template defaults.

Likely an incorrect or invalid review comment.

@claude
Copy link

claude bot commented Nov 2, 2025

PR Review: Update shakapacker to 9.3.0

Overall, this is a well-executed upgrade with thoughtful handling of breaking changes. The PR addresses multiple compatibility issues systematically. Here's my detailed review:

✅ Strengths

  1. Comprehensive Breaking Change Handling: The PR properly addresses Shakapacker 9.x breaking changes:

    • CSS Modules namedExport change (spec/dummy/config/webpack/commonWebpackConfig.js:31-45)
    • SWC as new default transpiler with proper dependency additions
    • Updated configuration format (webpack_loader → javascript_transpiler)
  2. Smart Generator Improvements:

    • Added @swc/core and swc-loader to both base_generator.rb and install_generator.rb
    • Ensures all generated apps have required dependencies
  3. Exact Version Enforcement: The install_generator.rb changes to always use --save-exact flag (line 444) ensure version consistency, which aligns with the strict version checking requirements

  4. Well-Documented Commits: Each commit has clear explanations of what changed and why

⚠️ Issues & Concerns

1. Generator Detection Logic May Be Fragile (lib/react_on_rails/engine.rb:17)

next if defined?(Rails::Generators) && ARGV.any? { |arg| arg.include?("generate") || arg.include?("g") }

Issues:

  • Using ARGV.include? for generator detection is fragile and could have false positives
  • This could skip validation in production if someone has "generate" in their arguments
  • The check for defined?(Rails::Generators) alone may not be sufficient

Recommendation: Consider a more robust approach:

# Check if we're in a generator context more reliably
next if defined?(Rails::Generators) && caller.any? { |line| line.include?('/generators/') }

Or use a dedicated flag/environment variable set by the generator itself.

2. Potential Race Condition in Webpack Config (spec/dummy/config/webpack/commonWebpackConfig.js:27-29)

The guard check is good, but there's a subtle issue:

if (scssConfigIndex !== -1 && baseClientWebpackConfig.module.rules[scssConfigIndex]?.use) {
  baseClientWebpackConfig.module.rules[scssConfigIndex].use.push(sassLoaderConfig);
}

Issue: If scssConfigIndex is found but the rule structure changes between the findIndex and the actual access, this could still fail. However, this is unlikely in practice.

Minor suggestion: Consider adding a debug log when the scss config isn't found to help troubleshoot issues.

3. CSS Modules Mutation Uses ESLint Disable (spec/dummy/config/webpack/commonWebpackConfig.js:38-41)

// eslint-disable-next-line no-param-reassign
loader.options.modules.namedExport = false;

Observation: While the eslint-disable is justified here, this direct mutation approach could be fragile if Shakapacker's internal structure changes.

Recommendation: Consider documenting this as a potential maintenance point, or explore if Shakapacker provides a more official way to configure this in future versions.

4. Missing Async Loading Version Documentation

The PR reverted the async loading version check back to 8.2.0 (commit 2), which is correct. However, this could confuse future maintainers.

Recommendation: Add a comment in lib/react_on_rails/packer_utils.rb explaining why this version differs from the main Shakapacker version requirement.

🔍 Security Considerations

  1. No Security Concerns Identified: The changes are primarily dependency updates and configuration adjustments
  2. Lock Files Updated Properly: Both Gemfile.lock and yarn.lock are updated consistently

🧪 Testing Observations

From the PR description, testing appears comprehensive:

  • RuboCop checks passed
  • Git hooks validated
  • Multiple CI test suites mentioned (examples, build-dummy-app-webpack-test-bundles)

Question: Were manual tests performed for:

  • Existing apps with CSS Modules using default imports?
  • Apps with custom webpack configurations?
  • Both SWC and Babel transpiler options?

📊 Performance Considerations

Positive Impact: SWC as default transpiler should provide ~20x faster builds compared to Babel, which is excellent for developer experience.

🎯 Best Practices Alignment

Follows CLAUDE.md Requirements:

  • All files end with newlines
  • RuboCop compliance verified
  • Git hooks validated
  • Formatted with automated tools

📝 Recommendations

  1. High Priority: Improve the generator detection logic in engine.rb (see issue TODO for first version #1 above)

  2. Medium Priority:

    • Add inline comment explaining async loading version difference
    • Consider logging when webpack config modifications fail silently
  3. Documentation:

    • Update CHANGELOG.md with breaking changes and migration guide
    • Document that users with custom CSS Module configurations may need adjustments
  4. Future Enhancement:

    • Consider providing a migration rake task that checks user webpack configs for potential issues
    • Add deprecation warnings if old webpack_loader setting is detected

✅ Approval Recommendation

Status: Approve with minor suggestions

This PR successfully handles a complex version upgrade with multiple breaking changes. The issues identified are minor and mostly about future maintainability rather than critical bugs. The validation skip logic is the only item I'd strongly recommend reviewing before merge.

Overall Quality: 8.5/10

  • Excellent handling of breaking changes
  • Good test coverage
  • One architectural concern with generator detection
  • Well-documented commit history

Great work on this upgrade! 🚀

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)
lib/react_on_rails/engine.rb (1)

16-17: Consider more robust generator detection.

The current ARGV string matching could produce false positives if any argument contains "generate" or "g" (e.g., file paths, script names). A more precise approach would be to check the Rails command context directly.

Consider using a more targeted check:

-        # Skip validation when running generators (packages may not be installed yet)
-        next if defined?(Rails::Generators) && ARGV.any? { |arg| arg.include?("generate") || arg.include?("g") }
+        # Skip validation when running generators (packages may not be installed yet)
+        next if defined?(Rails::Command::GenerateCommand) || (defined?(Rails::Generators) && Rails.const_defined?(:Generator))

Alternatively, check the command name more precisely:

-        next if defined?(Rails::Generators) && ARGV.any? { |arg| arg.include?("generate") || arg.include?("g") }
+        next if defined?(Rails::Generators) && ARGV.first&.match?(/\A(g|generate)\z/)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c088ba1 and 31a88fd.

📒 Files selected for processing (4)
  • lib/generators/react_on_rails/install_generator.rb (2 hunks)
  • lib/react_on_rails/engine.rb (1 hunks)
  • package_json_issue_comment.md (1 hunks)
  • spec/dummy/config/webpack/commonWebpackConfig.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • lib/generators/react_on_rails/install_generator.rb
🧰 Additional context used
📓 Path-based instructions (3)
{Gemfile,Rakefile,config.ru,**/*.{rb,rake,gemspec,ru}}

📄 CodeRabbit inference engine (CLAUDE.md)

{Gemfile,Rakefile,config.ru,**/*.{rb,rake,gemspec,ru}}: All Ruby code must pass RuboCop with zero offenses before commit/push
RuboCop is the sole authority for Ruby file formatting; never manually format Ruby files

Files:

  • lib/react_on_rails/engine.rb
**/*.{js,jsx,ts,tsx,css,scss,json,yml,yaml,md}

📄 CodeRabbit inference engine (CLAUDE.md)

Prettier is the sole authority for formatting all non-Ruby files; never manually format them

Files:

  • spec/dummy/config/webpack/commonWebpackConfig.js
  • package_json_issue_comment.md
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use ESLint for JS/TS code (lint via rake lint or yarn lint)

Files:

  • spec/dummy/config/webpack/commonWebpackConfig.js
🧠 Learnings (10)
📚 Learning: 2025-10-23T17:22:01.074Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1875
File: lib/react_on_rails/utils.rb:112-124
Timestamp: 2025-10-23T17:22:01.074Z
Learning: In React on Rails, when Pro is installed but not licensed, the intended behavior is to raise an error on boot. The `react_on_rails_pro?` method validates licenses and should raise errors early (including during path resolution in methods like `server_bundle?`) to enforce licensing requirements rather than failing later with obscure errors.

Applied to files:

  • lib/react_on_rails/engine.rb
📚 Learning: 2025-02-18T13:08:01.477Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 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/engine.rb
📚 Learning: 2025-02-12T16:38:06.537Z
Learnt from: Romex91
Repo: shakacode/react_on_rails PR: 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/engine.rb
📚 Learning: 2025-02-13T16:50:26.861Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/turbolinksUtils.ts:34-36
Timestamp: 2025-02-13T16:50:26.861Z
Learning: In React on Rails, when checking for Turbolinks version 5 using `turbolinksVersion5()`, always ensure `Turbolinks` exists first by checking `turbolinksInstalled()` to prevent TypeError when accessing properties.

Applied to files:

  • lib/react_on_rails/engine.rb
📚 Learning: 2025-09-15T21:24:48.207Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1781
File: node_package/src/ClientSideRenderer.ts:82-95
Timestamp: 2025-09-15T21:24:48.207Z
Learning: In React on Rails, the force_load feature includes both explicit `data-force-load="true"` usage and the ability to hydrate components during the page loading state (`document.readyState === 'loading'`). Both capabilities require a Pro license, so the condition `!railsContext.rorPro && (isComponentForceLoaded || document.readyState === 'loading')` correctly gates both scenarios.

Applied to files:

  • lib/react_on_rails/engine.rb
📚 Learning: 2025-04-26T21:55:55.874Z
Learnt from: alexeyr-ci2
Repo: shakacode/react_on_rails PR: 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/engine.rb
📚 Learning: 2025-02-18T13:08:01.477Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 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:

  • lib/react_on_rails/engine.rb
📚 Learning: 2024-12-12T13:07:09.929Z
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 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/engine.rb
📚 Learning: 2025-01-23T18:20:45.824Z
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 1687
File: spec/dummy/package.json:0-0
Timestamp: 2025-01-23T18:20:45.824Z
Learning: When adding or updating dependencies in spec/dummy/package.json, maintain version consistency with other package.json files in the codebase to avoid potential version conflicts.

Applied to files:

  • lib/react_on_rails/engine.rb
  • package_json_issue_comment.md
📚 Learning: 2025-09-16T08:01:11.146Z
Learnt from: justin808
Repo: shakacode/react_on_rails PR: 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:

  • spec/dummy/config/webpack/commonWebpackConfig.js
🧬 Code graph analysis (1)
lib/react_on_rails/engine.rb (2)
lib/generators/react_on_rails/generator_helper.rb (1)
  • package_json (7-20)
lib/react_on_rails/version_checker.rb (1)
  • package_json_path (222-224)
🔇 Additional comments (4)
lib/react_on_rails/engine.rb (1)

12-14: LGTM! Safe guard for initial setup.

The package.json existence check is appropriate for initial setup scenarios where the file hasn't been created yet.

spec/dummy/config/webpack/commonWebpackConfig.js (2)

27-29: LGTM! Appropriate guard for SCSS loader.

The defensive check prevents errors if the SCSS rule doesn't exist or lacks a use array, which is good practice for plugin configurations.


31-45: LGTM! Appropriate backward compatibility fix for Shakapacker 9.0.

This correctly overrides Shakapacker 9.0's new default (namedExport: true) to preserve existing import patterns (import styles from './file.module.css'). The mutation is intentional and properly guarded.

package_json_issue_comment.md (1)

1-58: Clarify the purpose and placement of this documentation.

This file appears to document a feature request or issue comment for the package_json gem. The filename and content suggest it might be:

  • A draft issue comment for an external repository
  • Temporary documentation that shouldn't be committed
  • Internal documentation that should be in a docs/ directory

Could you clarify:

  1. Is this file intended to be committed to the repository?
  2. If yes, should it be in a more appropriate location (e.g., docs/, or as a GitHub issue)?
  3. If it's a draft for an external issue, consider moving it outside the repository.

@claude
Copy link

claude bot commented Nov 2, 2025

PR Review: Update Shakapacker to 9.3.0

I've reviewed the changes in this PR. Overall, this is a well-structured upgrade with good attention to compatibility concerns. Here's my detailed feedback:


Strengths

  1. Comprehensive version updates - All references to shakapacker across Gemfiles, package.json, specs, and rake tasks have been consistently updated to 9.3.0.

  2. Good backward compatibility handling - The CSS Modules configuration changes in commonWebpackConfig.js show thoughtful handling of breaking changes (namedExport defaults).

  3. Well-documented workaround - The package_json_issue_comment.md provides excellent context for why the package_json gem was bypassed. This is valuable documentation.

  4. SWC tooling added - Properly adds @swc/core and swc-loader as dev dependencies, which is important for Shakapacker 9.x's default transpiler.

  5. Smart validation skip logic - The engine.rb changes prevent validation failures during setup/generator runs.


🔍 Potential Issues & Concerns

1. Rails Engine Validation Logic (lib/react_on_rails/engine.rb:17)

next if defined?(Rails::Generators) && ARGV.any? { |arg| arg.include?("generate") || arg.include?("g") }

Issues:

  • Using ARGV is fragile and may not work correctly in all contexts (Rake tasks, console, tests, etc.)
  • String matching with include? could have false positives (e.g., a file path containing "generate")
  • This check happens in an initializer that runs during Rails boot, but Rails::Generators might not always be defined when generators are running

Recommendation:
Consider a more robust approach:

# Check if we're in a generator context more reliably
generator_running = defined?(Rails::Generators) && 
                   (caller.any? { |line| line.include?('generators/') } ||
                    Rails.const_defined?(:Command) && Rails::Command.current == 'generate')
next if generator_running

Or use an environment variable approach that generators can set explicitly.

2. CSS Modules Configuration (spec/dummy/config/webpack/commonWebpackConfig.js:27-28)

if (scssConfigIndex !== -1 && baseClientWebpackConfig.module.rules[scssConfigIndex]?.use) {
  baseClientWebpackConfig.module.rules[scssConfigIndex].use.push(sassLoaderConfig);
}

Good: The guard check was added to prevent errors if the SCSS rule isn't found.

Concern: The CSS Modules configuration (lines 34-45) doesn't have similar safety checks. It directly mutates loader configs without checking if they exist.

Recommendation:
Add similar defensive checks:

baseClientWebpackConfig.module.rules.forEach((rule) => {
  if (Array.isArray(rule.use)) {
    rule.use.forEach((loader) => {
      if (loader?.loader && loader.loader.includes('css-loader') && loader.options?.modules) {
        // ... existing code
      }
    });
  }
});

3. Package Installation Strategy (lib/generators/react_on_rails/install_generator.rb:430-447)

The change to always use direct npm install with --save-exact is a breaking change for users who use yarn/pnpm/bun.

Current code:

success = system("npm", "install", "--save-exact", react_on_rails_pkg)

Issues:

  • Hard-codes npm as the package manager
  • Loses the package_json gem's automatic package manager detection
  • Users with yarn.lock or pnpm-lock.yaml will get npm packages installed, causing mixed lock files

Recommendation:
Either:

  1. Detect the package manager and use appropriate commands:

    manager = detect_package_manager # 'npm', 'yarn', 'pnpm', etc.
    exact_flag = manager == 'yarn' || manager == 'bun' ? '--exact' : '--save-exact'
    success = system(manager, "install", exact_flag, react_on_rails_pkg)
  2. Or continue using package_json gem but post-process package.json to remove carets:

    add_npm_dependencies(react_on_rails_pkg)
    # Then fix the version string in package.json
    fix_package_version("react-on-rails", ReactOnRails::VERSION)

🎯 Performance & Security Considerations

  1. SWC is 20x faster - Great upgrade! The switch to SWC as default transpiler is a significant performance improvement.

  2. Locked versions - Using exact versions for react-on-rails is correct for tight gem/npm coupling. No security concerns here.

  3. yarn.lock changes - The lockfile diff looks clean, all new dependencies are legitimate shakapacker/swc packages.


🧪 Test Coverage

Question: Were the following scenarios tested?

  1. Running rails generate react_on_rails:install on a fresh Rails app (both with npm and yarn)?
  2. Running rails generate react_on_rails:base to ensure base generator works?
  3. Verifying the validation skip logic works correctly during generator runs?
  4. Testing with existing apps upgrading from shakapacker 8.x?

The PR description mentions RuboCop passing and bundle/yarn install succeeding, but explicit generator testing would be valuable.


📝 Minor Suggestions

  1. package_json_issue_comment.md - This seems like it should be in a docs folder or removed from the PR. Is this meant to be a comment on the package_json gem repo issue tracker?

  2. shakapacker.yml comments (lib/generators/react_on_rails/templates/base/base/config/shakapacker.yml:39-41) - Excellent documentation of the javascript_transpiler option!

  3. Consider adding a changelog entry - Based on CLAUDE.md guidelines, this version bump should be documented.


Best Practices Adherence

  • Formatting looks good (Prettier/RuboCop compliant)
  • Files end with newlines ✓
  • No obvious security issues
  • Good inline documentation

🎬 Recommendation

Conditional APPROVE pending:

  1. Fix or clarify the package manager hard-coding issue in install_generator.rb
  2. Consider strengthening the validation skip logic in engine.rb
  3. Add explicit generator testing to the test plan
  4. Clarify the purpose of package_json_issue_comment.md

The core upgrade work is solid, but the package manager detection regression needs attention before merging.


Great work on this upgrade! The attention to backward compatibility and the SWC migration is well-executed. 🚀

@claude
Copy link

claude bot commented Nov 3, 2025

Code Review: Shakapacker 9.3.0 Update

Overview

This PR updates Shakapacker from 8.2.0 to 9.3.0. Overall, the update is well-structured and follows the project's coding standards. However, I've identified several issues that should be addressed before merging.


Critical Issues

1. Package Manager Hard-Coding in add_react_on_rails_package (High Priority)

Location: lib/generators/react_on_rails/install_generator.rb:444

Issue: The method hard-codes npm as the package manager, which is inconsistent with the rest of the codebase and will cause problems for users using yarn/pnpm/bun.

# Current code always uses npm
success = system("npm", "install", "--save-exact", react_on_rails_pkg)

Problem:

  • Users with yarn.lock files will get conflicting lock files (both yarn.lock and package-lock.json)
  • Breaks the package manager detection pattern used elsewhere in the same file (see install_js_dependencies at lines 505-532)
  • This is a regression from the previous implementation

Recommendation: Detect and use the user's package manager:

def add_react_on_rails_package
  major_minor_patch_only = /\A\d+\.\d+\.\d+\z/
  
  react_on_rails_pkg = if ReactOnRails::VERSION.match?(major_minor_patch_only)
                         "react-on-rails@#{ReactOnRails::VERSION}"
                       else
                         puts "Adding the latest react-on-rails NPM module. " \
                              "Double check this is correct in package.json"
                         "react-on-rails"
                       end

  puts "Installing React on Rails package..."
  
  # Detect package manager and use appropriate exact version flag
  package_manager, exact_flag = detect_package_manager_and_exact_flag
  success = system(package_manager, "install", exact_flag, react_on_rails_pkg)
  @ran_direct_installs = true if success
  handle_npm_failure("react-on-rails package", [react_on_rails_pkg]) unless success
end

private

def detect_package_manager_and_exact_flag
  if File.exist?(File.join(destination_root, "yarn.lock"))
    ["yarn", "--exact"]
  elsif File.exist?(File.join(destination_root, "pnpm-lock.yaml"))
    ["pnpm", "--save-exact"]
  elsif File.exist?(File.join(destination_root, "bun.lockb"))
    ["bun", "--exact"]
  else
    ["npm", "--save-exact"]
  end
end

2. Fragile ARGV-Based Generator Detection (Medium Priority)

Location: lib/react_on_rails/engine.rb:17

Issue: The validation skip logic uses string matching on ARGV which is fragile:

next if defined?(Rails::Generators) && ARGV.any? { |arg| arg.include?("generate") || arg.include?("g") }

Problems:

  • arg.include?("g") is extremely broad and will match almost anything containing the letter "g"
  • ARGV behavior varies across different contexts (rake tasks, console, tests, background jobs)
  • Could match file paths like /path/to/generated/file.rb
  • Timing-dependent: Rails::Generators might not be defined when expected

Recommendation: Use an environment variable approach for explicit control:

# In lib/react_on_rails/engine.rb
initializer "react_on_rails.validate_version_and_package_compatibility" do
  config.after_initialize do
    package_json = VersionChecker::NodePackageVersion.package_json_path
    next unless File.exist?(package_json)
    
    # Skip validation when generators explicitly set this flag
    next if ENV["REACT_ON_RAILS_SKIP_VALIDATION"] == "true"
    
    Rails.logger.info "[React on Rails] Validating package version and compatibility..."
    VersionChecker.build.validate_version_and_package_compatibility\!
    Rails.logger.info "[React on Rails] Package validation successful"
  end
end
# In lib/generators/react_on_rails/install_generator.rb
def run_generators
  ENV["REACT_ON_RAILS_SKIP_VALIDATION"] = "true"
  
  if installation_prerequisites_met? || options.ignore_warnings?
    invoke_generators
    add_bin_scripts
    add_post_install_message unless options.redux?
  else
    # ... error handling
  end
ensure
  ENV.delete("REACT_ON_RAILS_SKIP_VALIDATION")
  print_generator_messages
end

3. Missing Defensive Checks in Webpack Config (Low Priority)

Location: spec/dummy/config/webpack/commonWebpackConfig.js:34-45

Issue: The CSS Modules configuration code lacks defensive programming compared to the SCSS configuration above it:

baseClientWebpackConfig.module.rules.forEach((rule) => {
  if (Array.isArray(rule.use)) {
    rule.use.forEach((loader) => {
      // Missing checks for loader existence before accessing properties
      if (loader.loader && loader.loader.includes('css-loader') && loader.options?.modules) {
        loader.options.modules.namedExport = false;
        loader.options.modules.exportLocalsConvention = 'camelCase';
      }
    });
  }
});

Recommendation: Add comprehensive safety checks:

baseClientWebpackConfig.module.rules.forEach((rule) => {
  if (Array.isArray(rule.use)) {
    rule.use.forEach((loader) => {
      if (
        loader &&
        typeof loader === 'object' &&
        loader.loader &&
        typeof loader.loader === 'string' &&
        loader.loader.includes('css-loader') &&
        loader.options &&
        typeof loader.options === 'object' &&
        loader.options.modules &&
        typeof loader.options.modules === 'object'
      ) {
        // eslint-disable-next-line no-param-reassign
        loader.options.modules.namedExport = false;
        // eslint-disable-next-line no-param-reassign
        loader.options.modules.exportLocalsConvention = 'camelCase';
      }
    });
  }
});

Documentation Concerns

4. Unexpected Documentation Files Added

Files: ISSUE_ANALYSIS.md and package_json_issue_comment.md

Issue: These appear to be internal analysis/draft documents that shouldn't be committed to the repository:

  • ISSUE_ANALYSIS.md (485 lines) contains detailed code review notes
  • package_json_issue_comment.md (58 lines) contains a draft comment for another project

Recommendation: Remove these files from the PR. They seem to be accidentally included.


Positive Aspects

Good configuration updates:

  • Updated shakapacker.yml to use javascript_transpiler: "swc" (20x faster than Babel)
  • Added SWC dependencies (@swc/core, swc-loader) to dev dependencies
  • Proper CSS Modules compatibility configuration for Shakapacker 9.0

Comprehensive version updates:

  • All references to 8.2.0 updated consistently across the codebase
  • Both Gemfile.lock and yarn.lock files properly updated

Code follows project standards:

  • RuboCop compliant (as mentioned in PR description)
  • Proper trailing newlines added to SCSS files
  • Uses exact version pinning where needed

Good documentation in code:

  • Clear comments explaining the CSS Modules configuration change
  • Updated shakapacker.yml comments to explain transpiler options

Testing Recommendations

Before merging, ensure:

  1. Multi-package-manager testing:

    • Test generator with yarn (most critical since it's common)
    • Test generator with pnpm
    • Test generator with npm
    • Verify no duplicate lock files are created
  2. Generator context testing:

    • Verify validation runs during normal Rails boot
    • Verify validation is skipped during rails generate react_on_rails:install
    • Test in rake tasks, console, and test environments
  3. CSS Modules testing:

    • Verify CSS Modules imports still work with default exports
    • Test with malformed webpack configs to ensure no crashes

Summary

Must Fix Before Merge:

  1. ❌ Remove ISSUE_ANALYSIS.md and package_json_issue_comment.md
  2. ❌ Fix package manager hard-coding in add_react_on_rails_package

Should Fix:
3. ⚠️ Improve generator detection logic in engine.rb
4. ⚠️ Add defensive checks to webpack config

Priority: Fix items 1 and 2 first, as they will cause issues for users. Items 3 and 4 are robustness improvements that can be addressed in follow-up PRs if time is tight.

Overall, this is a solid update to Shakapacker 9.3.0, but the package manager issue is a blocker that needs to be resolved.

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 (2)
lib/generators/react_on_rails/generator_helper.rb (1)

98-128: Good package manager detection logic with minor clarity suggestions.

The implementation correctly detects package managers and returns appropriate commands. The fallback to npm is sensible.

Consider these optional improvements for clarity:

  1. Document the precedence order - The order matters when multiple lock files exist, but it's implicit in the hash order:
# Detects the package manager based on lock files and returns the appropriate command and exact flag
# Precedence order: yarn > pnpm > bun > npm (first detected is used)
# Returns: [package_manager, exact_flag, add_command]
  1. Note the command difference - It's subtle that npm uses "install" while others use "add". Consider adding a comment:
lock_files = {
  "yarn.lock" => ["yarn", "--exact", "add"],
  "pnpm-lock.yaml" => ["pnpm", "--save-exact", "add"],
  "bun.lockb" => ["bun", "--exact", "add"],
  "package-lock.json" => ["npm", "--save-exact", "install"] # npm uses 'install' not 'add'
}
ISSUE_ANALYSIS.md (1)

1-485: Valuable design documentation capturing implementation rationale.

This document provides excellent context for the changes in this PR by:

  1. Analyzing the problems with existing approaches
  2. Evaluating multiple solution options
  3. Documenting the recommended approach (which was implemented)

The document shows that Issue #1 (engine validation) and Issue #3 (package manager detection) solutions were implemented in lib/react_on_rails/engine.rb and lib/generators/react_on_rails/generator_helper.rb respectively.

Optional improvements:

  1. Add implementation status - Consider adding a section linking to the actual implementation:
## Implementation Status

- ✅ Issue #1: Implemented in `lib/react_on_rails/engine.rb` (lines 12-17)
- ⏳ Issue #2: Pending
- ✅ Issue #3: Implemented in `lib/generators/react_on_rails/generator_helper.rb` (lines 98-128)
  1. Consider renaming - If this is meant to be permanent documentation, consider moving to docs/ directory or renaming to something like SHAKAPACKER_9_UPGRADE_ANALYSIS.md to make the context clearer.

  2. Formatting - The markdownlint warnings about emphasis-as-heading can be fixed by converting bold text to proper headings where appropriate (lines 42, 89, 108, 158, 189, 215, 282, 321, 372, 440).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 31a88fd and d779040.

📒 Files selected for processing (9)
  • .github/workflows/lint-js-and-ruby.yml (1 hunks)
  • ISSUE_ANALYSIS.md (1 hunks)
  • knip.ts (3 hunks)
  • lib/generators/react_on_rails/generator_helper.rb (1 hunks)
  • lib/generators/react_on_rails/install_generator.rb (6 hunks)
  • lib/react_on_rails/engine.rb (1 hunks)
  • react_on_rails_pro/spec/dummy/client/app/components/HelloWorld.module.scss (1 hunks)
  • spec/dummy/client/app/components/HelloWorld.module.scss (1 hunks)
  • spec/dummy/config/webpack/commonWebpackConfig.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • spec/dummy/config/webpack/commonWebpackConfig.js
  • lib/generators/react_on_rails/install_generator.rb
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{js,jsx,ts,tsx,css,scss,json,yml,yaml,md}

📄 CodeRabbit inference engine (CLAUDE.md)

Prettier is the sole authority for formatting all non-Ruby files; never manually format them

Files:

  • knip.ts
  • ISSUE_ANALYSIS.md
  • spec/dummy/client/app/components/HelloWorld.module.scss
  • react_on_rails_pro/spec/dummy/client/app/components/HelloWorld.module.scss
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use ESLint for JS/TS code (lint via rake lint or yarn lint)

Files:

  • knip.ts
{Gemfile,Rakefile,config.ru,**/*.{rb,rake,gemspec,ru}}

📄 CodeRabbit inference engine (CLAUDE.md)

{Gemfile,Rakefile,config.ru,**/*.{rb,rake,gemspec,ru}}: All Ruby code must pass RuboCop with zero offenses before commit/push
RuboCop is the sole authority for Ruby file formatting; never manually format Ruby files

Files:

  • lib/generators/react_on_rails/generator_helper.rb
  • lib/react_on_rails/engine.rb
🧠 Learnings (14)
📚 Learning: 2025-09-29T12:23:13.615Z
Learnt from: CR
Repo: shakacode/react_on_rails PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-29T12:23:13.615Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use ESLint for JS/TS code (lint via rake lint or yarn lint)

Applied to files:

  • .github/workflows/lint-js-and-ruby.yml
📚 Learning: 2025-04-26T21:55:55.874Z
Learnt from: alexeyr-ci2
Repo: shakacode/react_on_rails PR: 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:

  • .github/workflows/lint-js-and-ruby.yml
  • ISSUE_ANALYSIS.md
  • lib/react_on_rails/engine.rb
  • react_on_rails_pro/spec/dummy/client/app/components/HelloWorld.module.scss
📚 Learning: 2025-09-29T12:23:13.615Z
Learnt from: CR
Repo: shakacode/react_on_rails PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-29T12:23:13.615Z
Learning: Applies to {Gemfile,Rakefile,config.ru,**/*.{rb,rake,gemspec,ru}} : All Ruby code must pass RuboCop with zero offenses before commit/push

Applied to files:

  • .github/workflows/lint-js-and-ruby.yml
📚 Learning: 2025-02-12T16:38:06.537Z
Learnt from: Romex91
Repo: shakacode/react_on_rails PR: 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:

  • .github/workflows/lint-js-and-ruby.yml
  • ISSUE_ANALYSIS.md
  • lib/generators/react_on_rails/generator_helper.rb
  • lib/react_on_rails/engine.rb
📚 Learning: 2025-09-16T08:01:11.146Z
Learnt from: justin808
Repo: shakacode/react_on_rails PR: 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:

  • .github/workflows/lint-js-and-ruby.yml
  • knip.ts
  • ISSUE_ANALYSIS.md
  • spec/dummy/client/app/components/HelloWorld.module.scss
  • react_on_rails_pro/spec/dummy/client/app/components/HelloWorld.module.scss
📚 Learning: 2025-09-29T12:23:13.615Z
Learnt from: CR
Repo: shakacode/react_on_rails PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-29T12:23:13.615Z
Learning: Never run npm; use Yarn Classic equivalents only

Applied to files:

  • knip.ts
📚 Learning: 2025-02-13T19:09:15.991Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/RSCWebpackLoader.ts:0-0
Timestamp: 2025-02-13T19:09:15.991Z
Learning: In React Server Components webpack loader, using `new Function('return import("react-server-dom-webpack/node-loader")')()` is necessary as a workaround to bypass TypeScript compilation issues with direct dynamic imports.

Applied to files:

  • knip.ts
📚 Learning: 2025-02-18T13:08:01.477Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 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:

  • ISSUE_ANALYSIS.md
  • lib/react_on_rails/engine.rb
📚 Learning: 2025-10-23T17:22:01.074Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1875
File: lib/react_on_rails/utils.rb:112-124
Timestamp: 2025-10-23T17:22:01.074Z
Learning: In React on Rails, when Pro is installed but not licensed, the intended behavior is to raise an error on boot. The `react_on_rails_pro?` method validates licenses and should raise errors early (including during path resolution in methods like `server_bundle?`) to enforce licensing requirements rather than failing later with obscure errors.

Applied to files:

  • ISSUE_ANALYSIS.md
  • lib/react_on_rails/engine.rb
📚 Learning: 2025-02-13T16:50:26.861Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/turbolinksUtils.ts:34-36
Timestamp: 2025-02-13T16:50:26.861Z
Learning: In React on Rails, when checking for Turbolinks version 5 using `turbolinksVersion5()`, always ensure `Turbolinks` exists first by checking `turbolinksInstalled()` to prevent TypeError when accessing properties.

Applied to files:

  • lib/react_on_rails/engine.rb
📚 Learning: 2025-09-15T21:24:48.207Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1781
File: node_package/src/ClientSideRenderer.ts:82-95
Timestamp: 2025-09-15T21:24:48.207Z
Learning: In React on Rails, the force_load feature includes both explicit `data-force-load="true"` usage and the ability to hydrate components during the page loading state (`document.readyState === 'loading'`). Both capabilities require a Pro license, so the condition `!railsContext.rorPro && (isComponentForceLoaded || document.readyState === 'loading')` correctly gates both scenarios.

Applied to files:

  • lib/react_on_rails/engine.rb
📚 Learning: 2025-02-18T13:08:01.477Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 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:

  • lib/react_on_rails/engine.rb
📚 Learning: 2024-12-12T13:07:09.929Z
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 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/engine.rb
📚 Learning: 2024-10-08T20:53:47.076Z
Learnt from: theforestvn88
Repo: shakacode/react_on_rails PR: 1620
File: spec/dummy/client/app/startup/HelloTurboStream.jsx:3-3
Timestamp: 2024-10-08T20:53:47.076Z
Learning: The `RailsContext` import in `spec/dummy/client/app/startup/HelloTurboStream.jsx` is used later in the project, as clarified by the user theforestvn88.

Applied to files:

  • react_on_rails_pro/spec/dummy/client/app/components/HelloWorld.module.scss
🧬 Code graph analysis (2)
lib/generators/react_on_rails/generator_helper.rb (1)
lib/generators/react_on_rails/generator_messages.rb (1)
  • add_warning (13-15)
lib/react_on_rails/engine.rb (2)
lib/generators/react_on_rails/generator_helper.rb (1)
  • package_json (7-20)
lib/react_on_rails/version_checker.rb (1)
  • package_json_path (222-224)
🪛 LanguageTool
ISSUE_ANALYSIS.md

[uncategorized] ~463-~463: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...ase failures 3. Fix Issue #2 last - Low priority defensive programming improvement ## T...

(EN_COMPOUND_ADJECTIVE_INTERNAL)

🪛 markdownlint-cli2 (0.18.1)
ISSUE_ANALYSIS.md

42-42: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


89-89: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


108-108: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


158-158: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


189-189: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


215-215: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


282-282: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


321-321: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


372-372: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


440-440: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

🔇 Additional comments (6)
spec/dummy/client/app/components/HelloWorld.module.scss (1)

1-2: Verify that the SCSS import path and variable are available.

The import statement is being added to enable usage of $bright-color from the shared variables file. Ensure that app-variables.scss exists at the specified path and that the $bright-color variable is properly defined.

react_on_rails_pro/spec/dummy/client/app/components/HelloWorld.module.scss (1)

1-5: Verify that the SCSS import path and variable are available in the react_on_rails_pro environment.

The import statement mirrors the changes in spec/dummy/client/app/components/HelloWorld.module.scss, enabling usage of $bright-color from the shared variables file. Ensure that app-variables.scss exists at the specified path in this parallel environment and that the $bright-color variable is properly defined.

.github/workflows/lint-js-and-ruby.yml (1)

73-76: Clarify the rationale for suppressing knip config hints.

The addition of --no-config-hints to the knip invocation (Line 75) is not mentioned in the PR objectives, which focus on shakapacker version updates. This flag suppresses knip's configuration diagnostics, which could mask legitimate issues.

What is the underlying knip configuration problem triggered by the shakapacker/SWC upgrade? Consider documenting this in a comment or commit message if this is a known workaround.

lib/react_on_rails/engine.rb (1)

9-17: Excellent validation guards implementation.

The two-tier skip logic is well-designed:

  1. Skips when package.json doesn't exist (initial setup scenario)
  2. Skips when explicitly requested via environment variable (generator scenario)

This approach eliminates the fragile ARGV inspection and provides explicit control. The guards are ordered efficiently with the cheaper file existence check first.

The implementation aligns with the recommended solution in ISSUE_ANALYSIS.md and provides a robust way to handle validation timing without false positives.

knip.ts (2)

10-18: Clarified binary ignores for dev-only tooling.

The additions of nps and e2e-test with clear comments improve the configuration documentation.


112-134: Updated ignore rules align with Shakapacker 9 tooling changes.

The dependency ignore adjustments reflect the updated build configuration:

  • Moving mini-css-extract-plugin to root workspace ignores
  • Adding webpack-merge as a direct dependency (transitive from shakapacker)
  • Removing previously ignored loaders that may now be properly detected

The changes are consistent with the broader webpack/CSS loader configuration updates in this PR.

justin808 added a commit that referenced this pull request Nov 3, 2025
…ssing require

Addresses 3 critical issues identified in PR #1896 review:

1. Remove invalid javascript_transpiler configuration
   - Shakapacker 9.3.0 does not support a top-level javascript_transpiler key
   - Removed lines 39-42 from shakapacker.yml template
   - Transpiler selection is configured via webpack config and installed loaders

2. Update Pro package.json files to Shakapacker 9.3.0
   - Updated react_on_rails_pro/spec/dummy/package.json (8.0.0 → 9.3.0)
   - Updated react_on_rails_pro/spec/execjs-compatible-dummy/package.json (8.0.0 → 9.3.0)
   - Added swc-loader and @swc/core dependencies to both files
   - Ensures version consistency across the codebase

3. Fix missing GeneratorMessages require in generator_helper.rb
   - Added require_relative "generator_messages" to prevent NameError
   - Issue occurred when detect_package_manager_and_exact_flag found multiple lock files
   - Now consistent with other generator files (base_generator.rb, install_generator.rb)

All RuboCop checks pass.

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

Co-Authored-By: Claude <noreply@anthropic.com>
@justin808 justin808 self-assigned this Nov 3, 2025
@coderabbitai coderabbitai bot added the bug label Nov 3, 2025
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 (1)
lib/generators/react_on_rails/generator_helper.rb (1)

100-129: Consider clarifying the package manager precedence order.

The method correctly detects package managers and handles multiple lock files, but the warning message doesn't explain the precedence order (yarn → pnpm → bun → npm). Users might benefit from knowing why a particular package manager was chosen when multiple lock files exist.

Consider updating the warning message to be more explicit:

     if detected.size > 1
       GeneratorMessages.add_warning(<<~MSG.strip)
         ⚠️  Multiple package manager lock files detected:
         #{detected.map { |lf, _| "  • #{lf}" }.join("\n")}
 
         This can cause dependency conflicts. Consider using only one package manager.
-        Using #{detected.first[0]} based on file precedence.
+        Using #{detected.first[0]} based on precedence order: yarn → pnpm → bun → npm.
       MSG
     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 a5b19dd and 7fd36a8.

📒 Files selected for processing (6)
  • lib/generators/react_on_rails/generator_helper.rb (2 hunks)
  • lib/generators/react_on_rails/templates/base/base/config/shakapacker.yml (0 hunks)
  • react_on_rails_pro/spec/dummy/client/app/components/HelloWorld.module.scss (1 hunks)
  • react_on_rails_pro/spec/dummy/package.json (1 hunks)
  • react_on_rails_pro/spec/execjs-compatible-dummy/package.json (1 hunks)
  • spec/dummy/client/app/components/HelloWorld.module.scss (1 hunks)
💤 Files with no reviewable changes (1)
  • lib/generators/react_on_rails/templates/base/base/config/shakapacker.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • react_on_rails_pro/spec/dummy/client/app/components/HelloWorld.module.scss
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-01-23T18:20:45.824Z
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 1687
File: spec/dummy/package.json:0-0
Timestamp: 2025-01-23T18:20:45.824Z
Learning: When adding or updating dependencies in spec/dummy/package.json, maintain version consistency with other package.json files in the codebase to avoid potential version conflicts.

Applied to files:

  • react_on_rails_pro/spec/dummy/package.json
  • react_on_rails_pro/spec/execjs-compatible-dummy/package.json
📚 Learning: 2025-02-12T16:38:06.537Z
Learnt from: Romex91
Repo: shakacode/react_on_rails PR: 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:

  • react_on_rails_pro/spec/dummy/package.json
  • react_on_rails_pro/spec/execjs-compatible-dummy/package.json
  • lib/generators/react_on_rails/generator_helper.rb
📚 Learning: 2025-04-26T21:55:55.874Z
Learnt from: alexeyr-ci2
Repo: shakacode/react_on_rails PR: 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:

  • react_on_rails_pro/spec/dummy/package.json
  • react_on_rails_pro/spec/execjs-compatible-dummy/package.json
📚 Learning: 2025-09-16T08:01:11.146Z
Learnt from: justin808
Repo: shakacode/react_on_rails PR: 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:

  • react_on_rails_pro/spec/dummy/package.json
  • react_on_rails_pro/spec/execjs-compatible-dummy/package.json
  • spec/dummy/client/app/components/HelloWorld.module.scss
📚 Learning: 2025-10-23T17:22:01.074Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1875
File: lib/react_on_rails/utils.rb:112-124
Timestamp: 2025-10-23T17:22:01.074Z
Learning: In React on Rails, when Pro is installed but not licensed, the intended behavior is to raise an error on boot. The `react_on_rails_pro?` method validates licenses and should raise errors early (including during path resolution in methods like `server_bundle?`) to enforce licensing requirements rather than failing later with obscure errors.

Applied to files:

  • lib/generators/react_on_rails/generator_helper.rb
🧬 Code graph analysis (1)
lib/generators/react_on_rails/generator_helper.rb (1)
lib/generators/react_on_rails/generator_messages.rb (1)
  • add_warning (13-15)
⏰ 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). (1)
  • GitHub Check: examples (3.2, minimum)
🔇 Additional comments (4)
spec/dummy/client/app/components/HelloWorld.module.scss (2)

1-1: File import path verified and is accessible.

The imported app-variables.scss file exists at the expected location. The relative import path is correct and the module will load successfully.


1-4: CSS Modules configuration is correctly aligned with Shakapacker 9.3.0.

The webpack configuration explicitly sets namedExport: false and exportLocalsConvention: 'camelCase', which perfectly matches the camelCase class name .brightColor in the SCSS file. The configuration is intentionally set for backward compatibility with default imports (import styles from './file.module.css'), and the code follows this pattern correctly. No changes are needed.

react_on_rails_pro/spec/execjs-compatible-dummy/package.json (1)

33-35: Verify dependency version consistency across dummy/spec package.json files.

The PR updates shakapacker and adds SWC tooling in multiple package.json files. Ensure that versions for shakapacker, swc-loader, and @swc/core are consistent across spec/dummy/package.json and react_on_rails_pro/spec/execjs-compatible-dummy/package.json to prevent version conflicts during builds and tests.

Based on learnings from prior PRs, inconsistent versions across dummy setups can cause integration issues. Can you verify that these versions match in both locations?

lib/generators/react_on_rails/generator_helper.rb (1)

5-5: LGTM! GeneratorMessages is now accessible.

The require_relative statement properly addresses the previous concern about GeneratorMessages availability.

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7fd36a8 and ce33ba8.

📒 Files selected for processing (4)
  • package-scripts.yml (1 hunks)
  • react_on_rails_pro/spec/dummy/package.json (2 hunks)
  • react_on_rails_pro/spec/execjs-compatible-dummy/package.json (2 hunks)
  • spec/dummy/babel.config.js (1 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-02-12T16:38:06.537Z
Learnt from: Romex91
Repo: shakacode/react_on_rails PR: 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:

  • package-scripts.yml
  • react_on_rails_pro/spec/execjs-compatible-dummy/package.json
  • react_on_rails_pro/spec/dummy/package.json
📚 Learning: 2025-04-26T21:55:55.874Z
Learnt from: alexeyr-ci2
Repo: shakacode/react_on_rails PR: 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:

  • package-scripts.yml
  • react_on_rails_pro/spec/execjs-compatible-dummy/package.json
  • react_on_rails_pro/spec/dummy/package.json
📚 Learning: 2025-09-16T08:01:11.146Z
Learnt from: justin808
Repo: shakacode/react_on_rails PR: 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:

  • package-scripts.yml
  • react_on_rails_pro/spec/execjs-compatible-dummy/package.json
  • react_on_rails_pro/spec/dummy/package.json
📚 Learning: 2025-01-23T18:20:45.824Z
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 1687
File: spec/dummy/package.json:0-0
Timestamp: 2025-01-23T18:20:45.824Z
Learning: When adding or updating dependencies in spec/dummy/package.json, maintain version consistency with other package.json files in the codebase to avoid potential version conflicts.

Applied to files:

  • react_on_rails_pro/spec/execjs-compatible-dummy/package.json
  • spec/dummy/babel.config.js
  • react_on_rails_pro/spec/dummy/package.json
⏰ 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). (11)
  • GitHub Check: build-dummy-app-webpack-test-bundles (3.4, 22)
  • GitHub Check: examples (3.2, minimum)
  • GitHub Check: examples (3.4, latest)
  • GitHub Check: build-dummy-app-webpack-test-bundles (3.2, 20)
  • GitHub Check: lint-js-and-ruby
  • GitHub Check: rspec-package-tests (3.4, latest)
  • GitHub Check: claude-review
  • GitHub Check: markdown-link-check
  • GitHub Check: rspec-package-tests (3.4, minimum)
  • GitHub Check: rspec-package-tests (3.2, minimum)
  • GitHub Check: rspec-package-tests (3.2, latest)
🔇 Additional comments (3)
spec/dummy/babel.config.js (1)

1-2: LGTM! Necessary update for shakapacker 9.3.0 compatibility.

The explicit .js extension and ESLint directive are appropriate for the updated shakapacker module resolution requirements. The configuration logic remains unchanged.

react_on_rails_pro/spec/dummy/package.json (1)

81-81: Correct placement of build-time dependencies.

All build-time tools (shakapacker, @swc/core, swc-loader) are correctly placed in devDependencies, which aligns with npm conventions for spec fixtures and is consistent with the shakapacker 9.3.0 upgrade.

Also applies to: 91-92

package-scripts.yml (1)

29-29: LGTM! Package manager consistency.

The switch from npm run build to yarn run build aligns with the project's use of Yarn as the primary package manager and is consistent across the codebase updates.

justin808 added a commit that referenced this pull request Nov 3, 2025
…ssing require

Addresses 3 critical issues identified in PR #1896 review:

1. Remove invalid javascript_transpiler configuration
   - Shakapacker 9.3.0 does not support a top-level javascript_transpiler key
   - Removed lines 39-42 from shakapacker.yml template
   - Transpiler selection is configured via webpack config and installed loaders

2. Update Pro package.json files to Shakapacker 9.3.0
   - Updated react_on_rails_pro/spec/dummy/package.json (8.0.0 → 9.3.0)
   - Updated react_on_rails_pro/spec/execjs-compatible-dummy/package.json (8.0.0 → 9.3.0)
   - Added swc-loader and @swc/core dependencies to both files
   - Ensures version consistency across the codebase

3. Fix missing GeneratorMessages require in generator_helper.rb
   - Added require_relative "generator_messages" to prevent NameError
   - Issue occurred when detect_package_manager_and_exact_flag found multiple lock files
   - Now consistent with other generator files (base_generator.rb, install_generator.rb)

All RuboCop checks pass.

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

Co-Authored-By: Claude <noreply@anthropic.com>
@justin808 justin808 force-pushed the justin808/shakapacker-9.3.0 branch from ce33ba8 to 9f254fb Compare November 3, 2025 06:31
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

Caution

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

⚠️ Outside diff range comments (1)
lib/generators/react_on_rails/install_generator.rb (1)

545-555: Update manual install instructions to respect the detected package manager.

This warning always tells users to run npm install, even when we just attempted Yarn/Pnpm/Bun. On Yarn and Pnpm projects that guidance leads to duplicate lockfiles and conflicting dependency state. Please build the fallback command from detect_package_manager_and_exact_flag before emitting the message so we point developers to the right tool.

-        install_command = dev ? "npm install --save-dev" : "npm install"
+        package_manager, _exact_flag, add_command = detect_package_manager_and_exact_flag
+        install_command =
+          case package_manager
+          when "npm"
+            dev ? "npm #{add_command} --save-dev" : "npm #{add_command}"
+          when "yarn"
+            dev ? "yarn #{add_command} -D" : "yarn #{add_command}"
+          when "pnpm"
+            dev ? "pnpm #{add_command} -D" : "pnpm #{add_command}"
+          when "bun"
+            dev ? "bun #{add_command} --dev" : "bun #{add_command}"
+          else
+            dev ? "npm install --save-dev" : "npm install"
+          end
🧹 Nitpick comments (1)
package_json_issue_comment.md (1)

1-57: Clarify the file's purpose and intended location.

The filename package_json_issue_comment.md suggests this documents an issue or discussion, but it's unclear whether this is meant as permanent documentation in the codebase. Based on the enriched summary, this file appears to explain the motivation behind the package manager detection helper and exact-install flow changes.

If this is intended as permanent documentation, consider:

  1. Relocate to a dedicated directory — Move to docs/decisions/ (or similar ADR/decision-log directory) with a clearer name like package-manager-exact-install-support.md to indicate it's an architectural decision or design record.

  2. Add integration points — Reference this from relevant code files (e.g., lib/generators/react_on_rails/generator_helper.rb and lib/generators/react_on_rails/install_generator.rb) via inline comments explaining the rationale for the approach.

  3. Remove if temporary — If this is a temporary artifact (issue comment saved for reference), consider removing it or storing it in a separate issue/discussion tracker rather than committing it to the main codebase.

  4. Add cross-references — Link to the specific generator methods and explain how the problem described here is solved by the new package manager detection flow.

Based on learnings, consistent documentation across the codebase helps maintain clarity on version management decisions.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ce33ba8 and 9f254fb.

⛔ Files ignored due to path filters (3)
  • Gemfile.lock is excluded by !**/*.lock
  • spec/dummy/Gemfile.lock is excluded by !**/*.lock
  • spec/dummy/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (20)
  • .github/workflows/lint-js-and-ruby.yml (1 hunks)
  • Gemfile.development_dependencies (1 hunks)
  • ISSUE_ANALYSIS.md (1 hunks)
  • knip.ts (3 hunks)
  • lib/generators/react_on_rails/base_generator.rb (1 hunks)
  • lib/generators/react_on_rails/generator_helper.rb (2 hunks)
  • lib/generators/react_on_rails/install_generator.rb (6 hunks)
  • lib/generators/react_on_rails/templates/base/base/config/shakapacker.yml (0 hunks)
  • lib/react_on_rails/engine.rb (1 hunks)
  • package-scripts.yml (1 hunks)
  • package_json_issue_comment.md (1 hunks)
  • rakelib/shakapacker_examples.rake (1 hunks)
  • react_on_rails_pro/spec/dummy/client/app/components/HelloWorld.module.scss (1 hunks)
  • react_on_rails_pro/spec/dummy/package.json (2 hunks)
  • react_on_rails_pro/spec/execjs-compatible-dummy/package.json (2 hunks)
  • script/convert (1 hunks)
  • spec/dummy/babel.config.js (1 hunks)
  • spec/dummy/client/app/components/HelloWorld.module.scss (1 hunks)
  • spec/dummy/config/webpack/commonWebpackConfig.js (1 hunks)
  • spec/dummy/package.json (2 hunks)
💤 Files with no reviewable changes (1)
  • lib/generators/react_on_rails/templates/base/base/config/shakapacker.yml
🚧 Files skipped from review as they are similar to previous changes (10)
  • package-scripts.yml
  • react_on_rails_pro/spec/dummy/client/app/components/HelloWorld.module.scss
  • Gemfile.development_dependencies
  • react_on_rails_pro/spec/execjs-compatible-dummy/package.json
  • spec/dummy/config/webpack/commonWebpackConfig.js
  • react_on_rails_pro/spec/dummy/package.json
  • rakelib/shakapacker_examples.rake
  • knip.ts
  • spec/dummy/client/app/components/HelloWorld.module.scss
  • lib/generators/react_on_rails/generator_helper.rb
🧰 Additional context used
🧠 Learnings (11)
📚 Learning: 2025-01-23T18:20:45.824Z
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 1687
File: spec/dummy/package.json:0-0
Timestamp: 2025-01-23T18:20:45.824Z
Learning: When adding or updating dependencies in spec/dummy/package.json, maintain version consistency with other package.json files in the codebase to avoid potential version conflicts.

Applied to files:

  • spec/dummy/babel.config.js
  • script/convert
  • spec/dummy/package.json
  • ISSUE_ANALYSIS.md
  • lib/generators/react_on_rails/base_generator.rb
  • package_json_issue_comment.md
📚 Learning: 2025-04-26T21:55:55.874Z
Learnt from: alexeyr-ci2
Repo: shakacode/react_on_rails PR: 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:

  • script/convert
  • lib/generators/react_on_rails/install_generator.rb
  • .github/workflows/lint-js-and-ruby.yml
  • ISSUE_ANALYSIS.md
  • lib/generators/react_on_rails/base_generator.rb
📚 Learning: 2025-02-12T16:38:06.537Z
Learnt from: Romex91
Repo: shakacode/react_on_rails PR: 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:

  • script/convert
  • lib/generators/react_on_rails/install_generator.rb
  • lib/react_on_rails/engine.rb
  • .github/workflows/lint-js-and-ruby.yml
  • ISSUE_ANALYSIS.md
  • lib/generators/react_on_rails/base_generator.rb
📚 Learning: 2025-09-16T08:01:11.146Z
Learnt from: justin808
Repo: shakacode/react_on_rails PR: 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/generators/react_on_rails/install_generator.rb
  • .github/workflows/lint-js-and-ruby.yml
  • ISSUE_ANALYSIS.md
📚 Learning: 2025-02-18T13:08:01.477Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 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/generators/react_on_rails/install_generator.rb
  • lib/react_on_rails/engine.rb
  • ISSUE_ANALYSIS.md
📚 Learning: 2025-10-23T17:22:01.074Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1875
File: lib/react_on_rails/utils.rb:112-124
Timestamp: 2025-10-23T17:22:01.074Z
Learning: In React on Rails, when Pro is installed but not licensed, the intended behavior is to raise an error on boot. The `react_on_rails_pro?` method validates licenses and should raise errors early (including during path resolution in methods like `server_bundle?`) to enforce licensing requirements rather than failing later with obscure errors.

Applied to files:

  • lib/generators/react_on_rails/install_generator.rb
  • lib/react_on_rails/engine.rb
  • ISSUE_ANALYSIS.md
📚 Learning: 2025-07-08T05:57:29.630Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1745
File: node_package/src/RSCRequestTracker.ts:8-14
Timestamp: 2025-07-08T05:57:29.630Z
Learning: The global `generateRSCPayload` function in React on Rails Pro (RORP) is provided by the framework during rendering requests, not implemented in application code. The `declare global` statements are used to document the expected interface that RORP will inject at runtime.

Applied to files:

  • lib/generators/react_on_rails/install_generator.rb
📚 Learning: 2024-12-12T13:07:09.929Z
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 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/generators/react_on_rails/install_generator.rb
  • lib/react_on_rails/engine.rb
📚 Learning: 2025-02-13T16:50:26.861Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/turbolinksUtils.ts:34-36
Timestamp: 2025-02-13T16:50:26.861Z
Learning: In React on Rails, when checking for Turbolinks version 5 using `turbolinksVersion5()`, always ensure `Turbolinks` exists first by checking `turbolinksInstalled()` to prevent TypeError when accessing properties.

Applied to files:

  • lib/generators/react_on_rails/install_generator.rb
  • lib/react_on_rails/engine.rb
📚 Learning: 2025-09-15T21:24:48.207Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1781
File: node_package/src/ClientSideRenderer.ts:82-95
Timestamp: 2025-09-15T21:24:48.207Z
Learning: In React on Rails, the force_load feature includes both explicit `data-force-load="true"` usage and the ability to hydrate components during the page loading state (`document.readyState === 'loading'`). Both capabilities require a Pro license, so the condition `!railsContext.rorPro && (isComponentForceLoaded || document.readyState === 'loading')` correctly gates both scenarios.

Applied to files:

  • lib/react_on_rails/engine.rb
📚 Learning: 2025-02-18T13:08:01.477Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 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:

  • lib/react_on_rails/engine.rb
🧬 Code graph analysis (2)
lib/generators/react_on_rails/install_generator.rb (2)
lib/generators/react_on_rails/generator_helper.rb (2)
  • detect_package_manager_and_exact_flag (103-129)
  • add_npm_dependencies (24-40)
lib/generators/react_on_rails/base_generator.rb (1)
  • handle_npm_failure (242-254)
lib/react_on_rails/engine.rb (2)
lib/generators/react_on_rails/generator_helper.rb (1)
  • package_json (8-21)
lib/react_on_rails/version_checker.rb (5)
  • package_json_path (222-224)
  • build (12-14)
  • build (218-220)
  • react_on_rails_package? (254-256)
  • react_on_rails_pro_package? (258-260)
🪛 LanguageTool
ISSUE_ANALYSIS.md

[uncategorized] ~463-~463: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...ase failures 3. Fix Issue #2 last - Low priority defensive programming improvement ## T...

(EN_COMPOUND_ADJECTIVE_INTERNAL)

🪛 markdownlint-cli2 (0.18.1)
ISSUE_ANALYSIS.md

42-42: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


89-89: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


108-108: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


158-158: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


189-189: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


215-215: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


282-282: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


321-321: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


372-372: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


440-440: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

⏰ 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). (12)
  • GitHub Check: dummy-app-integration-tests (3.2, 20)
  • GitHub Check: dummy-app-integration-tests (3.4, 22)
  • GitHub Check: lint-js-and-ruby
  • GitHub Check: rspec-package-tests (3.4, minimum)
  • GitHub Check: rspec-package-tests (3.2, minimum)
  • GitHub Check: rspec-package-tests (3.2, latest)
  • GitHub Check: rspec-package-tests (3.4, latest)
  • GitHub Check: examples (3.4, latest)
  • GitHub Check: examples (3.2, minimum)
  • GitHub Check: build
  • GitHub Check: claude-review
  • GitHub Check: markdown-link-check
🔇 Additional comments (1)
package_json_issue_comment.md (1)

24-35: Verify this workaround is no longer needed after PR changes.

The code snippet shows a direct npm install --save-exact workaround. Confirm that the new package manager detection helper and exact-install flow (mentioned in the enriched summary) fully addresses this limitation, and that this workaround code is either replaced or deprecated in the current PR.

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: 5

🧹 Nitpick comments (2)
lib/react_on_rails/dev/pack_generator.rb (1)

46-64: IO redirection is not thread-safe.

Directly assigning to $stdout and $stderr affects all threads in the process and can cause issues if multiple threads are writing simultaneously. While this may be acceptable for a single-threaded context, consider documenting this limitation or using a thread-safe alternative like capturing output within the Rake task itself.

lib/generators/react_on_rails/base_generator.rb (1)

221-229: Refactor to use proper YAML parsing instead of string matching.

The current implementation uses simple string matching (include?), which is fragile and could lead to false positives or negatives:

  • ❌ Matches commented lines: # javascript_compiler: swc
  • ❌ Misses whitespace variations: javascript_compiler: swc (extra spaces)
  • ❌ Doesn't respect YAML structure or default sections

Apply this diff to parse YAML properly:

 def using_swc?
   # Check shakapacker.yml for javascript_compiler setting
   # Default to babel if not specified
   shakapacker_config_path = File.join(destination_root, "config", "shakapacker.yml")
   return false unless File.exist?(shakapacker_config_path)

-  config_content = File.read(shakapacker_config_path)
-  config_content.include?("javascript_compiler: swc")
+  require 'yaml'
+  config = YAML.load_file(shakapacker_config_path)
+  # Check the default section for javascript_compiler setting
+  config.dig("default", "javascript_compiler") == "swc"
+rescue StandardError
+  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 9f254fb and 3b9ad52.

📒 Files selected for processing (3)
  • lib/generators/react_on_rails/base_generator.rb (2 hunks)
  • lib/generators/react_on_rails/templates/base/base/config/shakapacker.yml (1 hunks)
  • lib/react_on_rails/dev/pack_generator.rb (2 hunks)
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-09-16T08:01:11.146Z
Learnt from: justin808
Repo: shakacode/react_on_rails PR: 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/generators/react_on_rails/templates/base/base/config/shakapacker.yml
  • lib/generators/react_on_rails/base_generator.rb
📚 Learning: 2025-04-26T21:55:55.874Z
Learnt from: alexeyr-ci2
Repo: shakacode/react_on_rails PR: 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/shakapacker.yml
  • lib/react_on_rails/dev/pack_generator.rb
  • lib/generators/react_on_rails/base_generator.rb
📚 Learning: 2025-02-12T16:38:06.537Z
Learnt from: Romex91
Repo: shakacode/react_on_rails PR: 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/generators/react_on_rails/templates/base/base/config/shakapacker.yml
  • lib/generators/react_on_rails/base_generator.rb
📚 Learning: 2025-07-08T05:57:29.630Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1745
File: node_package/src/RSCRequestTracker.ts:8-14
Timestamp: 2025-07-08T05:57:29.630Z
Learning: The global `generateRSCPayload` function in React on Rails Pro (RORP) is provided by the framework during rendering requests, not implemented in application code. The `declare global` statements are used to document the expected interface that RORP will inject at runtime.

Applied to files:

  • lib/generators/react_on_rails/templates/base/base/config/shakapacker.yml
  • lib/react_on_rails/dev/pack_generator.rb
  • lib/generators/react_on_rails/base_generator.rb
📚 Learning: 2025-09-29T14:45:42.687Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1833
File: lib/react_on_rails/dev/process_manager.rb:72-83
Timestamp: 2025-09-29T14:45:42.687Z
Learning: In Ruby bundler contexts, when bundler intercepts system commands for executables not in the Gemfile, both version checks (like `system("foreman", "--version")`) and execution commands (like `system("foreman", "start", ...)`) fail equally, both returning false. This means availability checks using version flags accurately reflect whether execution commands will work in the current bundler context.

Applied to files:

  • lib/react_on_rails/dev/pack_generator.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). (12)
  • GitHub Check: dummy-app-integration-tests (3.2, 20)
  • GitHub Check: dummy-app-integration-tests (3.4, 22)
  • GitHub Check: rspec-package-tests (3.2, latest)
  • GitHub Check: markdown-link-check
  • GitHub Check: examples (3.2, minimum)
  • GitHub Check: rspec-package-tests (3.4, minimum)
  • GitHub Check: rspec-package-tests (3.2, minimum)
  • GitHub Check: build
  • GitHub Check: lint-js-and-ruby
  • GitHub Check: rspec-package-tests (3.4, latest)
  • GitHub Check: examples (3.4, latest)
  • GitHub Check: claude-review
🔇 Additional comments (2)
lib/react_on_rails/dev/pack_generator.rb (1)

27-35: No actionable changes required—this is an established and idiomatic pattern in the codebase.

The defined?(Bundler) check is the appropriate way to verify whether the Bundler constant is available before calling Bundler methods. This pattern is already established in the same codebase (process_manager.rb lines 91, 103) and uses a consistent two-stage approach: first checking if Bundler is defined, then using respond_to? checks for specific methods (as seen in with_unbundled_context). Prior verification of this pattern in bundler contexts confirmed it correctly reflects whether execution paths will work in the current environment. The check serves its intended purpose in routing to the appropriate execution strategy.

Likely an incorrect or invalid review comment.

lib/generators/react_on_rails/base_generator.rb (1)

176-187: LGTM! Clear conditional dependency management.

The conditional logic cleanly separates SWC and Babel dependencies based on the compiler configuration, with helpful inline comments.

require "rake"

# Load Rails environment if not already loaded
require File.expand_path("config/environment", Dir.pwd) unless defined?(Rails)
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 | 🟠 Major

Rails root path assumption may fail.

Using Dir.pwd assumes the current working directory is the Rails root, which may not hold true in all contexts (e.g., when called from subdirectories or during certain deployment scenarios). Consider using Rails.root if Rails is already loaded, or searching upward for config/environment.rb.

Apply this diff to use a more robust path resolution:

-          require File.expand_path("config/environment", Dir.pwd) unless defined?(Rails)
+          unless defined?(Rails)
+            # Search upward for Rails root
+            rails_env = Dir.pwd
+            while rails_env != "/" && !File.exist?(File.join(rails_env, "config", "environment.rb"))
+              rails_env = File.dirname(rails_env)
+            end
+            raise "Could not find Rails root from #{Dir.pwd}" if rails_env == "/"
+            require File.expand_path("config/environment", rails_env)
+          end
🤖 Prompt for AI Agents
In lib/react_on_rails/dev/pack_generator.rb around line 41, replace the brittle
use of Dir.pwd when requiring config/environment with a robust path resolution:
if Rails is already defined and Rails.root is available use Rails.root,
otherwise walk upward from Dir.pwd (or __dir__) searching parent directories for
config/environment.rb and use that directory as the root; finally call require
File.expand_path("config/environment", resolved_root) unless defined?(Rails).
Ensure the search stops at filesystem root and raises a clear error if
config/environment.rb is not found.

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: 5

🧹 Nitpick comments (3)
TURBO_NAVIGATION_TEST_ISSUE.md (1)

144-157: Consider file organization: Move to dedicated directory.

This comprehensive test plan document would be better served in a dedicated documentation directory (e.g., docs/contributor-info/ or docs/testing/) rather than at the project root, aligning with the structure suggested in lines 155-157 and improving discoverability.

lib/react_on_rails/dev/server_manager.rb (1)

433-445: Consider adding verbose parameter for consistency with PackGenerator.

The method doesn't accept a verbose parameter like PackGenerator.generate(verbose: verbose) does, creating an inconsistent user experience. When users pass --verbose, they would expect to see detailed output for all build steps, including ReScript compilation.

Apply this diff to align with the PackGenerator pattern:

 def run_static_development(procfile, verbose: false, route: nil)
   print_procfile_info(procfile, route: route)
   print_server_info(
     "⚡ Starting development server with static assets...",
     [
       "Generating React on Rails packs",
       "Using shakapacker --watch (no HMR)",
       "CSS extracted to separate files (no FOUC)",
       "Development environment (source maps, faster builds)",
       "Auto-recompiles on file changes"
     ],
     route: route
   )

-  build_rescript_if_needed
+  build_rescript_if_needed(verbose: verbose)
   PackGenerator.generate(verbose: verbose)
   ProcessManager.ensure_procfile(procfile)
   ProcessManager.run_with_process_manager(procfile)
 end

 def run_development(procfile, verbose: false, route: nil)
   print_procfile_info(procfile, route: route)
-  build_rescript_if_needed
+  build_rescript_if_needed(verbose: verbose)
   PackGenerator.generate(verbose: verbose)
   ProcessManager.ensure_procfile(procfile)
   ProcessManager.run_with_process_manager(procfile)
 end

-def build_rescript_if_needed
+def build_rescript_if_needed(verbose: false)
   # Check for both old (bsconfig.json) and new (rescript.json) config files
   return unless File.exist?("bsconfig.json") || File.exist?("rescript.json")

-  print "🔧 Building ReScript... "
-  success = system("yarn build:rescript > /dev/null 2>&1")
-  puts success ? "✅" : "❌"
+  if verbose
+    puts "🔧 Building ReScript..."
+    success = system("yarn build:rescript")
+  else
+    print "🔧 Building ReScript... "
+    success = system("yarn build:rescript > /dev/null 2>&1")
+    puts success ? "✅" : "❌"
+  end

   return if success

   puts "❌ ReScript build failed"
   exit 1
 end
.github/workflows/pro-integration-tests.yml (1)

70-75: Deduplicate identical yalc publish steps across jobs.

The "Build and publish packages with yalc" steps are identical across all three jobs (lines 70–75, 190–195, 382–387). This violates the DRY principle and increases maintenance burden. Consider using a reusable workflow or composite action to eliminate duplication.

Example using a composite action:

# .github/actions/build-publish-yalc/action.yml
name: Build and Publish Packages with yalc
runs:
  using: composite
  steps:
    - name: Build and publish packages
      shell: bash
      run: |
        cd ..
        yarn run yalc:publish
        cd react_on_rails_pro
        yarn run yalc:publish

Then replace each occurrence with:

- uses: ./.github/actions/build-publish-yalc

Also applies to: 190-195, 382-387

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3b9ad52 and 792466b.

📒 Files selected for processing (4)
  • .github/workflows/pro-integration-tests.yml (3 hunks)
  • TURBO_NAVIGATION_TEST_ISSUE.md (1 hunks)
  • lib/react_on_rails/dev/server_manager.rb (1 hunks)
  • spec/dummy/app/views/layouts/application.html.erb (1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-10-23T17:22:01.074Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1875
File: lib/react_on_rails/utils.rb:112-124
Timestamp: 2025-10-23T17:22:01.074Z
Learning: In React on Rails, when Pro is installed but not licensed, the intended behavior is to raise an error on boot. The `react_on_rails_pro?` method validates licenses and should raise errors early (including during path resolution in methods like `server_bundle?`) to enforce licensing requirements rather than failing later with obscure errors.

Applied to files:

  • lib/react_on_rails/dev/server_manager.rb
📚 Learning: 2025-02-12T16:38:06.537Z
Learnt from: Romex91
Repo: shakacode/react_on_rails PR: 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/dev/server_manager.rb
📚 Learning: 2025-04-26T21:55:55.874Z
Learnt from: alexeyr-ci2
Repo: shakacode/react_on_rails PR: 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/dev/server_manager.rb
📚 Learning: 2025-02-13T16:50:26.861Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/turbolinksUtils.ts:34-36
Timestamp: 2025-02-13T16:50:26.861Z
Learning: In React on Rails, when checking for Turbolinks version 5 using `turbolinksVersion5()`, always ensure `Turbolinks` exists first by checking `turbolinksInstalled()` to prevent TypeError when accessing properties.

Applied to files:

  • TURBO_NAVIGATION_TEST_ISSUE.md
  • spec/dummy/app/views/layouts/application.html.erb
📚 Learning: 2024-10-08T20:53:47.076Z
Learnt from: theforestvn88
Repo: shakacode/react_on_rails PR: 1620
File: spec/dummy/client/app/startup/HelloTurboStream.jsx:3-3
Timestamp: 2024-10-08T20:53:47.076Z
Learning: The `RailsContext` import in `spec/dummy/client/app/startup/HelloTurboStream.jsx` is used later in the project, as clarified by the user theforestvn88.

Applied to files:

  • spec/dummy/app/views/layouts/application.html.erb
🧬 Code graph analysis (1)
lib/react_on_rails/dev/server_manager.rb (1)
lib/react_on_rails/dev/pack_generator.rb (2)
  • generate (7-75)
  • generate (9-23)
🪛 LanguageTool
TURBO_NAVIGATION_TEST_ISSUE.md

[style] ~30-~30: This sentence contains multiple usages of the word “again”. Consider removing or replacing it.
Context: ...d refreshing again → ✅ JavaScript works again This severely degraded the user experi...

(REPETITION_OF_AGAIN)

🪛 markdownlint-cli2 (0.18.1)
TURBO_NAVIGATION_TEST_ISSUE.md

146-146: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

⏰ 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). (11)
  • GitHub Check: build-dummy-app-webpack-test-bundles (3.2, 20)
  • GitHub Check: examples (3.4, latest)
  • GitHub Check: examples (3.2, minimum)
  • GitHub Check: rspec-package-tests (3.4, latest)
  • GitHub Check: rspec-package-tests (3.2, latest)
  • GitHub Check: rspec-package-tests (3.4, minimum)
  • GitHub Check: rspec-package-tests (3.2, minimum)
  • GitHub Check: claude-review
  • GitHub Check: build
  • GitHub Check: markdown-link-check
  • GitHub Check: lint-js-and-ruby
🔇 Additional comments (5)
TURBO_NAVIGATION_TEST_ISSUE.md (2)

1-10: Verify alignment with PR objectives.

This file documents a Turbo navigation regression test plan, but the PR objectives describe updating shakapacker from 8.2.0 to 9.3.0. There's no evident connection between these changes. Clarify whether this file should be included in this PR or if it belongs to a separate issue/PR.


42-84: Comprehensive test plan with strong verification approach.

The proposed Playwright test scenario is well-structured and effectively captures the regression scenario. The test matrix covering initial load, post-navigation, and back-navigation provides good coverage. The verification steps with explicit fail/pass instructions make this implementation checklist actionable.

spec/dummy/app/views/layouts/application.html.erb (2)

13-13: LGTM! Migration to Turbo and defer attribute aligns with modern Rails.

The change correctly migrates from Turbolinks to Turbo tracking (data-turbo-track: 'reload') and adds defer: true, which aligns perfectly with the comment on line 12 about using defer for proper script loading order.


13-13: Multiple ERB templates and other files still contain Turbolinks references that need updating alongside this change.

The search reveals that beyond the single change shown in application.html.erb, the following files in the main codebase (excluding fixtures/test bundles) should be reviewed and updated as part of the Turbolinks-to-Turbo migration:

  • ERB templates with data-turbolinks-track attributes: These need to be updated to data-turbo-track to match the change in the layout file.
  • ERB meta tags: <meta name="turbolinks-cache-control"> should be updated to <meta name="turbo-cache-control">.
  • Test descriptions: The integration test file contains "Turbolinks across pages" which could be updated to reflect Turbo.
  • Route names/helpers: turbolinks_cache_disabled_path is semantic but may need renaming for consistency.

The compiled JavaScript bundle files in fixtures show legacy Turbolinks event handling code (e.g., turbolinks:before-render, turbolinks:render), which appears to be intentionally preserved for fixture/snapshot purposes and likely don't require changes.

lib/react_on_rails/dev/server_manager.rb (1)

419-419: LGTM! Appropriate placement for ReScript build step.

The ReScript build is correctly positioned before pack generation in both development modes, ensuring compiled ReScript code is available when packs are generated.

Also applies to: 427-427

Comment on lines 438 to 444
success = system("yarn build:rescript > /dev/null 2>&1")
puts success ? "✅" : "❌"

return if success

puts "❌ ReScript build failed"
exit 1
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 | 🟠 Major

Suppressed error output makes debugging ReScript build failures difficult.

When the ReScript build fails, all compilation errors are discarded (> /dev/null 2>&1), leaving developers with only a generic "ReScript build failed" message. Compiler errors, type mismatches, and syntax issues won't be visible.

Consider showing the actual error output when the build fails:

-def build_rescript_if_needed
-  # Check for both old (bsconfig.json) and new (rescript.json) config files
-  return unless File.exist?("bsconfig.json") || File.exist?("rescript.json")
-
-  print "🔧 Building ReScript... "
-  success = system("yarn build:rescript > /dev/null 2>&1")
-  puts success ? "✅" : "❌"
-
-  return if success
-
-  puts "❌ ReScript build failed"
-  exit 1
-end
+def build_rescript_if_needed
+  # Check for both old (bsconfig.json) and new (rescript.json) config files
+  return unless File.exist?("bsconfig.json") || File.exist?("rescript.json")
+
+  print "🔧 Building ReScript... "
+  stdout, stderr, status = Open3.capture3("yarn", "build:rescript")
+  puts status.success? ? "✅" : "❌"
+
+  return if status.success?
+
+  puts "❌ ReScript build failed"
+  puts ""
+  puts Rainbow("📋 Build Output:").red.bold
+  puts Rainbow("─" * 60).red
+  puts stdout unless stdout.empty?
+  puts stderr unless stderr.empty?
+  puts Rainbow("─" * 60).red
+  exit 1
+end

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In lib/react_on_rails/dev/server_manager.rb around lines 438 to 444, the
ReScript build call suppresses all output ("> /dev/null 2>&1") so errors are
hidden; change the invocation so stdout/stderr are captured and only suppressed
on success — run the build without redirecting or capture the output (e.g., use
Open3.capture3 or backticks) and if the command fails print the captured
stderr/stdout before exiting so developers see the compiler errors and
diagnostics.

justin808 added a commit that referenced this pull request Nov 3, 2025
…ISSUE.md

Replaced "PR #XXXX" with "PR #1896" since commit f03b935 that fixed
the Turbo navigation bug is part of this PR.

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

Co-Authored-By: Claude <noreply@anthropic.com>
justin808 and others added 29 commits November 5, 2025 20:48
…files

These are build-time tools and should be in devDependencies, not dependencies.

Changes:
- react_on_rails_pro/spec/dummy/package.json: Moved @swc/core and swc-loader to devDependencies
- react_on_rails_pro/spec/execjs-compatible-dummy/package.json: Moved @swc/core and swc-loader to devDependencies

Both entries maintain the same version strings (^1.7.0 and ^0.2.6).

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

Co-Authored-By: Claude <noreply@anthropic.com>
Shakapacker is a build-time tool and should be in devDependencies, not dependencies.

Changed in react_on_rails_pro/spec/dummy/package.json:
- Removed "shakapacker": "9.3.0" from dependencies
- Added "shakapacker": "9.3.0" to devDependencies

This completes the correct categorization of all build-time tools
(@swc/core, swc-loader, and shakapacker) as devDependencies.

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

Co-Authored-By: Claude <noreply@anthropic.com>
Change the build.prepack script to use 'yarn run build' instead of
'npm run build'. In a yarn workspace, using npm to run scripts that
depend on workspace features (like 'yarn workspace react-on-rails run build')
causes build failures.

This fixes the yalc package publishing failures in CI where the prepack
script would fail silently, resulting in packages being published without
the built files, leading to downstream errors.

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

Co-Authored-By: Claude <noreply@anthropic.com>
1. Revert package-scripts.yml change (npm->yarn)
   - This file doesn't exist on master, so the change shouldn't be included

2. Add javascript_compiler setting to shakapacker.yml template
   - Adds configuration option to choose between 'babel' or 'swc'
   - Defaults to 'babel' for wider ecosystem support
   - Documents the tradeoffs between the two compilers

3. Fix swc/babel dependency management
   - Move swc packages (@swc/core, swc-loader) from devDependencies to dependencies
   - Make swc and babel mutually exclusive based on shakapacker.yml setting
   - Add using_swc? helper method to check javascript_compiler configuration
   - When using swc, install swc packages instead of babel packages

This ensures proper dependency installation based on the chosen JavaScript compiler.

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

Co-Authored-By: Claude <noreply@anthropic.com>
When bin/dev starts, webpack immediately tries to build bundles that
import ReScript components (HelloWorldReScript.res.js). However, these
.res.js files are generated by the ReScript compiler from .res source
files, and webpack fails if they don't exist yet.

Solution: Build ReScript files before starting the Procfile processes.
This ensures all .res.js files are generated before webpack starts.

Changes:
- lib/react_on_rails/dev/server_manager.rb:
  - Add build_rescript_if_needed method to compile ReScript before dev server
  - Check for both bsconfig.json (old) and rescript.json (new) config files
  - Run yarn build:rescript if ReScript is configured
  - Exit with error if ReScript build fails

Fixes webpack Module not found errors for HelloWorldReScript.res.js

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

Co-Authored-By: Claude <noreply@anthropic.com>
Implement explicit yalc publishing before yarn install to avoid
frozen-lockfile conflicts. This resolves the issue where preinstall
scripts triggered yalc operations that modified yarn.lock, causing
CI to fail with "--frozen-lockfile" checks.

Changes:
1. Add explicit "Build and publish packages with yalc" step that runs
   yarn run yalc:publish for both root and Pro packages before install
2. Add --ignore-scripts flag to Pro dummy app yarn install to skip
   preinstall hook (since yalc already published in previous step)
3. Apply to all 3 jobs: build, rspec, and playwright tests

This approach:
- Separates build/publish from install for better CI reproducibility
- Prevents yarn.lock modifications during install
- Maintains frozen-lockfile enforcement for dependency stability
- Faster CI (no redundant builds during preinstall)

The preinstall script remains useful for local development to auto-update
yalc packages, but in CI we use explicit steps for better control.

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

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

Documents a regression that existed for over 1 year where JavaScript failed
to work after Turbo navigation (only worked on hard refresh). This issue
provides a comprehensive plan for adding Playwright E2E tests to prevent
this type of regression in the future.

The issue includes:
- Background on what happened and when the bug was introduced (PR #1620)
- Impact on users (broken JS after navigation)
- Proposed Playwright test implementation
- Verification steps to prove the test catches the regression
- Additional test cases to consider
- Success criteria and implementation checklist

To verify Playwright is working correctly, developers can:
1. Run the test with the current fix (should pass)
2. Revert the fix in application.html.erb (should fail)
3. Restore the fix (should pass again)

This proves the test effectively catches Turbo navigation issues.

Related commits:
- Bug introduced: 56ee2bd (PR #1620, ~1 year ago)
- Bug fixed: f03b935 (this PR)

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

Co-Authored-By: Claude <noreply@anthropic.com>
Change 'yarn run yalc:publish' to 'yarn && yalc publish' for the
react_on_rails_pro package, since it doesn't have a yalc:publish script
defined (only the workspace packages do).

The workflow now:
1. Runs yarn run yalc:publish at root (publishes workspace packages)
2. Runs yarn && yalc publish in react_on_rails_pro (installs + publishes Pro)

This matches the command structure used in the preinstall script.

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

Co-Authored-By: Claude <noreply@anthropic.com>
The build.prepack script in package-scripts.yml was using `npm run build`
which causes failures in CI. This is inconsistent with the rest of the
codebase which uses yarn.

Changed line 29 from:
  (npm run build >/dev/null 2>&1 || true)
To:
  (yarn run build >/dev/null 2>&1 || true)

This matches the fix previously made in packages/react-on-rails/package.json
(commit 9f254fb) but was missed in the root package-scripts.yml file.

Fixes CI error:
  Building react-on-rails seems to have failed!

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

Co-Authored-By: Claude <noreply@anthropic.com>
Added 'tree' as the language identifier for the fenced code block showing
the file structure, changing from generic ``` to ```tree for better
syntax highlighting and clarity.

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

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

Replaced "PR #XXXX" with "PR #1896" since commit f03b935 that fixed
the Turbo navigation bug is part of this PR.

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

Co-Authored-By: Claude <noreply@anthropic.com>
The yalc workflow modifies yarn.lock when adding packages, so we cannot
use --frozen-lockfile after yalc has run. Keep --ignore-scripts to skip
the preinstall hook (since yalc already ran in the previous step).

This allows the install to succeed after yalc has modified the lockfile.

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

Co-Authored-By: Claude <noreply@anthropic.com>
Updated shakapacker gem version from 8.0.0 to 9.3.0 in Pro Gemfiles to match
the package.json changes, fixing the version mismatch error:

  "Shakapacker gem and node package versions do not match
   Detected: 9.3.0
        gem: 8.0.0"

Changed in:
- react_on_rails_pro/Gemfile.development_dependencies (8.0.0 → 9.3.0)
- react_on_rails_pro/spec/execjs-compatible-dummy/Gemfile (8.0 → 9.3.0)

This ensures gem and npm package versions match across all Pro dummy apps.

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

Co-Authored-By: Claude <noreply@anthropic.com>
Updated yarn.lock to match package.json changes for @swc/core and swc-loader
dependencies moved to devDependencies.

Fixes CI lint-js-and-ruby failure:
  "Your lockfile needs to be updated, but yarn was run with --frozen-lockfile"

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

Co-Authored-By: Claude <noreply@anthropic.com>
Updated yarn.lock to match package.json changes for @swc/core and swc-loader
dependencies moved to devDependencies in the execjs-compatible-dummy app.

Fixes CI lint-js-and-ruby failure for ExecJS dummy app:
  "Your lockfile needs to be updated, but yarn was run with --frozen-lockfile"

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

Co-Authored-By: Claude <noreply@anthropic.com>
Shakapacker 9.3.0 defaults to SWC compiler if javascript_compiler is not
explicitly set in shakapacker.yml. Update the using_swc? method to reflect
this new default behavior.

Changes:
- using_swc? now returns true (SWC) by default when config doesn't exist
- using_swc? returns true unless javascript_compiler is explicitly set to babel
- Updated template shakapacker.yml to comment out javascript_compiler setting
- Added clear documentation that Shakapacker 9.3.0+ defaults to SWC

This ensures the generator correctly detects and installs SWC dependencies
by default, matching Shakapacker 9.3.0's new default compiler.

Addresses PR review comment on lib/generators/react_on_rails/base_generator.rb:225

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

Co-Authored-By: Claude <noreply@anthropic.com>
Change using_swc? helper to parse shakapacker.yml with YAML.safe_load_file
instead of raw string matching, which incorrectly interpreted commented
lines as active configuration.

Changes:
- Add require "yaml" to base_generator.rb
- Parse YAML to read javascript_compiler from default section
- Return true only when javascript_compiler is explicitly set to "swc"
- Default to false (babel) when file is missing or key is absent
- Add error handling for YAML parsing failures
- Update template comment to reflect babel as default

This ensures commented configuration lines don't affect compiler detection
and provides more predictable behavior.

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

Co-Authored-By: Claude <noreply@anthropic.com>
Critical fixes:
1. using_swc? already properly parses YAML (no changes needed)
2. Make precompile hook cross-platform:
   - Replace Unix-specific `command -v` with Ruby's system() array form
   - Use File::NULL for cross-platform output redirection
   - Use array form of system() calls for better reliability
3. Fix fragile config detection in precompile hook:
   - Use regex to match only actual config assignments
   - Ignore comments and strings containing config names
4. Remove development documentation files:
   - ISSUE_ANALYSIS.md
   - PR_REVIEW_RESPONSE.md
   - package_json_issue_comment.md
5. Fix Rake task management:
   - Remove Rake::Task.clear (was clearing ALL tasks, not just ours)
   - Add task.reenable to support multiple invocations

These changes improve cross-platform compatibility (Windows support),
prevent false positives in config detection, and fix rake task issues.

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

Co-Authored-By: Claude <noreply@anthropic.com>
Per code review feedback:
- Remove precompile_hook from template shakapacker.yml
- Remove javascript_compiler config from template shakapacker.yml
- Remove bin/shakapacker-precompile-hook from generator templates

These features are development/testing-specific and should not be
in the default generator templates. They remain in spec/dummy for
testing purposes only.

Addresses review comments:
https://github.com/shakacode/react_on_rails/pull/1896/files#r2489115925
https://github.com/shakacode/react_on_rails/pull/1896/files#r2489114681
https://github.com/shakacode/react_on_rails/pull/1896/files#r2489120422
Add React 'use client' directive to RSCProvider.tsx to ensure this
component is treated as a client component in React Server Components
architecture.

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

Co-Authored-By: Claude <noreply@anthropic.com>
Reverted the array-form system calls back to string form to match
the test expectations in pack_generator_spec.rb.

This change (commit dabb298) was unrelated to the Shakapacker 9.3.0
upgrade and broke 3 tests:
- runs pack generation successfully in verbose mode
- runs pack generation successfully in quiet mode
- exits with error when pack generation fails

The tests expect the old string-based format:
  system "bundle exec rake react_on_rails:generate_packs"

Addresses review comment from @justin808 about unrelated changes.

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

Co-Authored-By: Claude <noreply@anthropic.com>
…er.tsx files

Files ending with .server.tsx are intended for server-side rendering and should
not have the 'use client' directive. This directive causes webpack to bundle
these files as client components, which leads to errors when React 19's server
exports don't include client-only APIs like createContext, useContext, and
Component.

This fixes CI errors:
- export 'createContext' was not found in 'react'
- export 'useContext' was not found in 'react'
- export 'Component' was not found in 'react'

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

Co-Authored-By: Claude <noreply@anthropic.com>
…ovider and RSCRoute

Remove 'use client' directives from RSCProvider.tsx and RSCRoute.tsx to fix
webpack compilation errors when these files are included in server bundles.

In React 19, the server build doesn't export client-only APIs like createContext,
useContext, and Component. When files with 'use client' are bundled into server
bundles, webpack fails with "export not found" errors.

The solution is to remove 'use client' from library files that need to work in
both server and client contexts. The 'use client' boundary should be established
in consuming components, not in the library files themselves.

Also update import style to use ReactClient from 'react/index.js' for better
compatibility with React 19's dual package structure.

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

Co-Authored-By: Claude <noreply@anthropic.com>
- Update Capybara to >= 3.40 for Rack 3 compatibility
- Fix generator to inject shakapacker 9.3.0 instead of >= 0
- Allow Ruby >= 3.0.0, < 3.5.0 in execjs-compatible-dummy

These changes fix test failures caused by Rack::Handler removal in Rack 3
and bundler conflicts from shakapacker version mismatches during generator tests.

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

Co-Authored-By: Claude <noreply@anthropic.com>
These were temporary files used to test the ESLint rule and should not
have been committed.

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

Co-Authored-By: Claude <noreply@anthropic.com>
Changed from `import ReactClient from 'react/index.js'` to the
simpler and more compatible `import * as React from 'react'`.

The 'react/index.js' path caused module resolution issues in Jest
and TypeScript errors without esModuleInterop. The simpler import
works correctly in all environments.

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

Co-Authored-By: Claude <noreply@anthropic.com>
These files MUST be client components because they use client-only React APIs:
- React.createContext and React.useContext (RSCProvider)
- React.Component class (RSCRoute)

The previous commit incorrectly removed 'use client' from these files.
The ESLint rule preventing 'use client' only applies to .server.tsx files,
not to regular .tsx files that need client-side APIs.

Without 'use client', webpack includes these files in the server bundle,
which fails because React's server exports don't include client-only APIs.

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

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

The issue was that with esModuleInterop: false in tsconfig.json, TypeScript
was compiling `import * as React from 'react'` to `import ReactClient from 'react/index.js'`,
which tried to access a default export that doesn't exist in React.

This caused webpack to fail when bundling the server bundle with errors:
- export 'createContext' was not found in 'react'
- export 'useContext' was not found in 'react'
- export 'Component' was not found in 'react'

The fix is to use named imports directly:
- `import { createContext, useContext, type ReactNode } from 'react'`
- `import { Component, use, type ReactNode } from 'react'`

This generates correct ES module imports that work with React 19's export structure.

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

Co-Authored-By: Claude <noreply@anthropic.com>
Changed from named imports to React namespace for better compatibility with React 18.0.0:
- `Component` → `React.Component`
- `createContext` → `React.createContext`
- `useContext` → `React.useContext`
- `use` → `React.use`

This fixes the build (20) CI failure where React is downgraded to 18.0.0 for
minimum version testing. Named exports may not be available in older React versions.

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

Co-Authored-By: Claude <noreply@anthropic.com>
@justin808 justin808 force-pushed the justin808/shakapacker-9.3.0 branch from a04a12f to a229abc Compare November 6, 2025 06:48
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