-
-
Notifications
You must be signed in to change notification settings - Fork 638
Refactor: Extract JS dependency management into shared module #2051
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This refactoring addresses duplicate code between BaseGenerator and InstallGenerator by extracting JavaScript dependency management into a shared JsDependencyManager module. Key improvements: - Eliminates ~270 lines of duplicated code - Centralizes dependency definitions in frozen constants - Removes Babel dependencies (now managed by Shakapacker) - Changes default transpiler to SWC in shakapacker.yml - Adds comprehensive test coverage for the new module - Simplifies dependency installation flow The module leverages package_json gem (always available via Shakapacker) for reliable cross-platform package management. Breaking change: Default webpack_loader changed from 'babel' to 'swc' in generated shakapacker.yml for better performance.
|
Warning Rate limit exceeded@justin808 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 8 minutes and 3 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the 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. 📒 Files selected for processing (2)
WalkthroughExtracts JavaScript dependency logic into a new JsDependencyManager module, updates BaseGenerator and InstallGenerator to include it and rename a gitignore method, removes inline JS-install flows, adds Rspack/TypeScript-aware dependency constants and flows, updates shakapacker.yml keys, and adds specs for message deduplication and the new manager. Changes
Sequence Diagram(s)sequenceDiagram
participant Generator as InstallGenerator / BaseGenerator
participant JSDepMgr as JsDependencyManager
participant PackageJSON as package_json gem
participant Shell as System (npm/yarn/pnpm)
rect rgba(220,235,245,0.4)
Note over Generator,JSDepMgr: Generator delegates JS dependency lifecycle
Generator->>JSDepMgr: setup_js_dependencies(options)
activate JSDepMgr
JSDepMgr->>JSDepMgr: build dependency lists (REACT/CSS/DEV)
alt options.rspack?
JSDepMgr->>JSDepMgr: include RSPACK_DEPENDENCIES
end
alt options.typescript?
JSDepMgr->>JSDepMgr: include TYPESCRIPT_DEPENDENCIES
end
JSDepMgr->>PackageJSON: add packages to package.json (idempotent)
JSDepMgr->>PackageJSON: install_js_dependencies()
activate PackageJSON
PackageJSON->>Shell: run package manager installer
Shell-->>PackageJSON: install result (success/failure)
PackageJSON-->>JSDepMgr: result
deactivate PackageJSON
JSDepMgr-->>Generator: completion (warnings on failures)
deactivate JSDepMgr
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~30–45 minutes
Possibly related issues
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
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. Comment |
Code Review: Refactor JS Dependency ManagementGreat refactoring work! This PR successfully eliminates code duplication and centralizes dependency management. Here's my detailed review: ✅ Strengths
🔍 Potential Issues & Suggestions1. Error Handling:
|
There was a problem hiding this 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
📒 Files selected for processing (5)
lib/generators/react_on_rails/base_generator.rb(2 hunks)lib/generators/react_on_rails/install_generator.rb(3 hunks)lib/generators/react_on_rails/js_dependency_manager.rb(1 hunks)lib/generators/react_on_rails/templates/base/base/config/shakapacker.yml(1 hunks)spec/react_on_rails/generators/message_deduplication_spec.rb(1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📚 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/base_generator.rblib/generators/react_on_rails/templates/base/base/config/shakapacker.ymlspec/react_on_rails/generators/message_deduplication_spec.rblib/generators/react_on_rails/js_dependency_manager.rblib/generators/react_on_rails/install_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/base_generator.rblib/generators/react_on_rails/templates/base/base/config/shakapacker.ymllib/generators/react_on_rails/js_dependency_manager.rblib/generators/react_on_rails/install_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/base_generator.rblib/generators/react_on_rails/templates/base/base/config/shakapacker.ymllib/generators/react_on_rails/js_dependency_manager.rblib/generators/react_on_rails/install_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/base_generator.rblib/generators/react_on_rails/templates/base/base/config/shakapacker.ymllib/generators/react_on_rails/js_dependency_manager.rblib/generators/react_on_rails/install_generator.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:
lib/generators/react_on_rails/base_generator.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/generators/react_on_rails/js_dependency_manager.rblib/generators/react_on_rails/install_generator.rb
🧬 Code graph analysis (4)
lib/generators/react_on_rails/base_generator.rb (1)
lib/generators/react_on_rails/install_generator.rb (1)
include(12-435)
spec/react_on_rails/generators/message_deduplication_spec.rb (4)
lib/generators/react_on_rails/base_generator.rb (1)
include(10-316)lib/generators/react_on_rails/install_generator.rb (1)
include(12-435)spec/react_on_rails/support/generator_spec_helper.rb (1)
run_generator_test_with_args(62-72)lib/generators/react_on_rails/generator_messages.rb (1)
output(5-7)
lib/generators/react_on_rails/js_dependency_manager.rb (1)
lib/generators/react_on_rails/generator_helper.rb (2)
package_json(7-20)add_npm_dependencies(23-39)
lib/generators/react_on_rails/install_generator.rb (2)
lib/generators/react_on_rails/base_generator.rb (1)
include(10-316)lib/generators/react_on_rails/js_dependency_manager.rb (2)
setup_js_dependencies(93-105)add_typescript_dependencies(176-186)
🪛 ast-grep (0.40.0)
spec/react_on_rails/generators/message_deduplication_spec.rb
[warning] 33-36: Found the use of an hardcoded passphrase for RSA. The passphrase can be easily discovered, and therefore should not be stored in source-code. It is recommended to remove the passphrase from source-code, and use system environment variables or a restricted configuration file.
Context: expect(success_count).to(
eq(1),
"Expected success message to appear exactly once, but appeared #{success_count} times"
)
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures [REFERENCES]
https://cwe.mitre.org/data/definitions/522.html
(hardcoded-secret-rsa-passphrase-ruby)
[warning] 51-54: Found the use of an hardcoded passphrase for RSA. The passphrase can be easily discovered, and therefore should not be stored in source-code. It is recommended to remove the passphrase from source-code, and use system environment variables or a restricted configuration file.
Context: expect(success_count).to(
eq(1),
"Expected success message to appear exactly once with Redux, but appeared #{success_count} times"
)
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures [REFERENCES]
https://cwe.mitre.org/data/definitions/522.html
(hardcoded-secret-rsa-passphrase-ruby)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: dummy-app-integration-tests (3.4, 22, latest)
- GitHub Check: examples (3.4, latest)
- GitHub Check: rspec-package-tests (3.4, latest)
- GitHub Check: build
- GitHub Check: claude-review
| # Select JavaScript transpiler to use | ||
| # Available options: 'swc' (default, 20x faster), 'babel', 'esbuild', or 'none' | ||
| # Use 'none' when providing a completely custom webpack configuration | ||
| # Note: When using rspack, swc is used automatically regardless of this setting | ||
| javascript_transpiler: "swc" | ||
|
|
||
| # Select assets bundler to use | ||
| # Available options: 'webpack' (default) or 'rspack' | ||
| assets_bundler: "webpack" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix Rspack transpiler key mismatch
We now emit javascript_transpiler in the template, but configure_rspack_in_shakapacker (see lib/generators/react_on_rails/base_generator.rb, Line 310) still mutates webpack_loader. If someone reruns the generator with --rspack after switching the YAML to "babel", the helper leaves javascript_transpiler untouched, so Shakapacker continues to expect Babel even though we removed the Babel deps in this refactor. The resulting build blows up under Rspack.
Please flip the helper to update the new key (and fall back to the legacy one for older configs), e.g.:
config["default"] ||= {}
- config["default"]["assets_bundler"] = "rspack"
- config["default"]["webpack_loader"] = "swc"
+ config["default"]["assets_bundler"] = "rspack"
+ if config["default"].key?("javascript_transpiler")
+ config["default"]["javascript_transpiler"] = "swc"
+ else
+ config["default"]["webpack_loader"] = "swc"
+ endCommittable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In lib/generators/react_on_rails/base_generator.rb around line 310 (changes
affect lib/generators/react_on_rails/templates/base/base/config/shakapacker.yml
lines 39-47), the configure_rspack_in_shakapacker helper currently mutates the
legacy webpack_loader key only; update the helper to prefer and modify the new
javascript_transpiler key (set it to "swc" or the appropriate value when
enabling rspack) and ensure assets_bundler is set to "rspack", and keep a
fallback to update the legacy webpack_loader key for older configs.
Code Review: PR #2051 - JsDependencyManager RefactoringThanks for this excellent refactoring! This PR successfully eliminates ~270 lines of duplicated code and centralizes dependency management. The overall direction is solid, but I've identified several issues that should be addressed before merging. 🔴 Critical Issues (Must Fix)1. Inconsistent Exception Handling StrategyProblem: The module has inconsistent error handling that could crash the generator unexpectedly. # In js_dependency_manager.rb - Methods raise exceptions:
def add_react_dependencies
if add_js_dependencies_batch(REACT_DEPENDENCIES)
@added_dependencies_to_package_json = true
else
raise "Failed to add React dependencies..."
end
end
# But install_js_dependencies catches and handles errors gracefully:
def install_js_dependencies
package_json.manager.install
true
rescue StandardError => e
GeneratorMessages.add_warning(...)
false
endImpact: If Recommendation: Use consistent error handling throughout:
2. Inadequate Test CoverageProblem: The test file Missing coverage:
Recommendation: Create describe ReactOnRails::Generators::JsDependencyManager do
describe "constants" do
it "defines frozen dependency arrays" do
expect(described_class::REACT_DEPENDENCIES).to be_frozen
end
it "does not include Babel presets in React dependencies" do
expect(described_class::REACT_DEPENDENCIES).not_to include("@babel/preset-react")
end
end
describe "#add_rspack_dependencies" do
context "when rspack option is true" do
# Test Rspack deps are added
end
end
# Test error scenarios, TypeScript deps, etc.
end3. Breaking Change in shakapacker.yml Needs DocumentationProblem: The configuration key changed from # Old (generated in previous versions)
webpack_loader: 'babel'
# New (generated now)
javascript_transpiler: "swc"
assets_bundler: "webpack"Questions:
Recommendation:
🟡 Medium Issues (Should Fix)4. Babel Dependencies Removed But Templates Still Reference ThemProblem: The spec/dummy/babel.config.js file references packages that are no longer installed: // spec/dummy/babel.config.js:12
'@babel/preset-react',
// spec/dummy/babel.config.js:23
'babel-plugin-transform-react-remove-prop-types',These were removed from
Recommendation:
5. Redundant Instance Variable TrackingProblem: The code maintains def setup_js_dependencies
@added_dependencies_to_package_json = false unless defined?(...)
add_js_dependencies
# Always run install regardless of the flag above
install_js_dependencies
endEvery method sets this flag to Recommendation: Remove the instance variable entirely or document why it's needed for future use. 6. Performance Concern: Always Running InstallProblem: The old # Old code
install_js_dependencies if @added_dependencies_to_package_json && \!@ran_direct_installsThe new code always runs install. While the comment claims package_json's install is idempotent, there's no benchmarking data. Questions:
Recommendation: Benchmark before/after on slow connections to verify no regression. 🔵 Low Priority Issues (Nice to Fix)7. Inconsistent Method Naming
8. Missing Null SafetyUse safe navigation operator for optional chaining: add_rspack_dependencies if respond_to?(:options) && options&.rspack?9. Unusual Instance Variable Initialization Pattern# Current
@added_dependencies_to_package_json = false unless defined?(...)
# Standard Ruby pattern
@added_dependencies_to_package_json ||= false10. YAML Quote Style InconsistencyNew config uses double quotes while other YAML files may use single quotes. Check consistency across the file. ✅ Positive Aspects
Overall AssessmentThis is a solid refactoring that significantly improves code maintainability. The core idea and execution are excellent. However, the critical issues with exception handling, test coverage, and breaking changes should be addressed before merging. Recommendation: Request Changes Action Items Before Merge:
Great work on this refactoring! Looking forward to seeing these issues addressed. 🚀 |
The test was failing because the mock PackageManager double only stubbed the 'install' method, but the actual code calls 'pj.manager.add(packages_array)' in add_js_dependency. This commit adds the 'add' method to the mock's allowed methods, allowing the test to properly verify that package_json gem methods are used instead of system() commands for dependency installation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Comprehensive Code Review: PR #2051Executive SummaryThis PR successfully extracts approximately 270 lines of duplicated code into a well-designed 🔴 Critical Issues (Must Fix)1. Bug: Inconsistent Config Keys in Rspack ConfigurationLocation: The template
However, the def configure_rspack_in_shakapacker
# ...
config["default"]["webpack_loader"] = "swc" # ❌ Should be 'javascript_transpiler'
endFix Required: Update to match the new naming convention. 2. Missing Unit Tests for JsDependencyManagerLocation: Only The new module lacks dedicated unit tests. Current tests only verify integration scenarios (message deduplication). Need tests for:
Recommendation: Add 3. Changed Error Handling Behavior (Undocumented Breaking Change)Location: Before: Generators gracefully degraded with warnings when package installation failed # Old behavior
success = system("npm", "install", *react_deps)
handle_npm_failure("React dependencies", react_deps) unless success # Warning only
# New behavior
else
raise "Failed to add React dependencies..." # ❌ Hard failure
endImpact: This could break existing workflows where partial failures were acceptable (e.g., offline development). Recommendation: Either preserve graceful degradation pattern or explicitly document this breaking change in the PR description and CHANGELOG. 🟡 Important Issues (Should Fix)4. Babel Config Generation MismatchLocation: Issue: The default transpiler changed to SWC, but base_files = %w[babel.config.js # Still copied even for SWC users!
config/webpack/clientWebpackConfig.js
# ...
Recommendation: Make 5. Unused Instance VariableLocation: @added_dependencies_to_package_json = false unless defined?(@added_dependencies_to_package_json)This variable is set throughout the module but never read. The old code used it to conditionally run install, but the new module always runs install. Recommendation: Remove it entirely or document why it's preserved for backward compatibility. 6. Behavior Change: Installation Now Always RunsLocation: Before: install_js_dependencies if @added_dependencies_to_package_json && !@ran_direct_installsAfter: setup_js_dependencies # Always calls install_js_dependenciesWhile the comment explains this is "safe because package_json gem's install is idempotent," this changes behavior and could add 1-2 seconds to generator execution. Recommendation: Document this behavior change in the PR description. 7. Unrelated Method RenameLocation: - def update_gitignore_for_generated_bundles
+ def update_gitignore_for_auto_registrationIssue: This rename is:
Recommendation: Revert or explain in PR description as a drive-by improvement. 🟢 Nice to Have Improvements8. Simplify Dependency Addition MethodsLocation: Two methods exist: Both delegate to def add_js_dependency(package, dev: false)
packages_array = [package] # Unnecessary wrapper
# ...
endRecommendation: Remove 9. Migration Guide for Babel UsersThe PR changes the default to SWC and removes Babel packages from installation. Users who need Babel-specific features have no clear guide on:
Recommendation: Add a section to the PR description or documentation explaining this migration path. 10. TypeScript Dependency Installation ClarityLocation: def install_typescript_dependencies
puts Rainbow("📝 Installing TypeScript dependencies...").yellow
add_typescript_dependencies # Name mismatch: install vs add
endThe method is named Recommendation: Rename for consistency or add a comment explaining the delegation. ✅ Excellent WorkCode Quality Highlights
Example of Great Documentation# Note: @babel/preset-react and babel plugins are NOT included here because:
# - Shakapacker handles JavaScript transpiler configuration (babel, swc, or esbuild)
# - Users configure their preferred transpiler via shakapacker.yml javascript_transpiler setting
# - SWC is now the default and doesn't need Babel presetsThis explains the "why" behind the change - exemplary! Security & Performance Notes✅ Security
✅ Performance
Testing NotesCurrent Coverage:
Missing Coverage:
Summary & RecommendationThis is a high-quality refactoring that successfully eliminates ~270 lines of duplication with excellent documentation. The frozen constants and module design are exemplary. However, do not merge until addressing:
The other issues are important but not blocking. Great work on this refactoring! The module design and documentation are excellent examples to follow. 🎉 Review performed using repository's CLAUDE.md conventions and best practices. |
Code Review: JS Dependency Management RefactoringOverviewThis is an excellent refactoring that eliminates significant code duplication (~270 lines) while improving maintainability and consistency. The extraction of ✅ StrengthsCode Quality
Architecture
Testing
Breaking Changes - Well Handled
|
There was a problem hiding this 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)
spec/react_on_rails/generators/message_deduplication_spec.rb (1)
89-92: Consider verified doubles if package_json gem classes are available.The unverified doubles are acceptable for external gem classes, but if the
PackageJsonandPackageManagerclasses from the package_json gem are available in the test environment (via Shakapacker), consider usinginstance_double('PackageJson::PackageJson')or similar for better test reliability.If you want to explore this, verify whether the classes are available:
# Check if we can use verified doubles begin require 'package_json' mock_manager = instance_double(PackageJson::Manager, install: true, add: true) mock_package_json = instance_double(PackageJson::PackageJson, manager: mock_manager) rescue LoadError # Fall back to unverified doubles if gem not available mock_manager = double("PackageManager", install: true, add: true) mock_package_json = double("PackageJson", manager: mock_manager) end
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
spec/react_on_rails/generators/message_deduplication_spec.rb(1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 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-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:
spec/react_on_rails/generators/message_deduplication_spec.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:
spec/react_on_rails/generators/message_deduplication_spec.rb
🧬 Code graph analysis (1)
spec/react_on_rails/generators/message_deduplication_spec.rb (4)
lib/generators/react_on_rails/base_generator.rb (1)
include(10-316)lib/generators/react_on_rails/install_generator.rb (1)
include(12-435)spec/react_on_rails/support/generator_spec_helper.rb (1)
run_generator_test_with_args(62-72)lib/generators/react_on_rails/generator_messages.rb (1)
output(5-7)
🪛 ast-grep (0.40.0)
spec/react_on_rails/generators/message_deduplication_spec.rb
[warning] 33-36: Found the use of an hardcoded passphrase for RSA. The passphrase can be easily discovered, and therefore should not be stored in source-code. It is recommended to remove the passphrase from source-code, and use system environment variables or a restricted configuration file.
Context: expect(success_count).to(
eq(1),
"Expected success message to appear exactly once, but appeared #{success_count} times"
)
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures [REFERENCES]
https://cwe.mitre.org/data/definitions/522.html
(hardcoded-secret-rsa-passphrase-ruby)
[warning] 51-54: Found the use of an hardcoded passphrase for RSA. The passphrase can be easily discovered, and therefore should not be stored in source-code. It is recommended to remove the passphrase from source-code, and use system environment variables or a restricted configuration file.
Context: expect(success_count).to(
eq(1),
"Expected success message to appear exactly once with Redux, but appeared #{success_count} times"
)
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures [REFERENCES]
https://cwe.mitre.org/data/definitions/522.html
(hardcoded-secret-rsa-passphrase-ruby)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: examples (3.4, latest)
- GitHub Check: build-dummy-app-webpack-test-bundles (3.4, 22, latest)
- GitHub Check: rspec-package-tests (3.4, latest)
- GitHub Check: build
- GitHub Check: claude-review
🔇 Additional comments (3)
spec/react_on_rails/generators/message_deduplication_spec.rb (3)
1-65: Excellent test coverage for message deduplication.The post-install message tests are well-structured and directly address the PR objectives. The mocking strategy properly isolates the generators from file system dependencies, and the tests verify both the uniqueness of success messages and the presence of expected content for both Redux and non-Redux installations.
112-140: Robust verification of the shared module refactoring.The method ownership verification using
instance_method(method).owneris an excellent approach to ensure that methods are truly shared via theJsDependencyManagermodule and not duplicated in each generator. This directly validates one of the core objectives of the refactoring.
1-141: Note: Static analysis false positives can be safely ignored.The ast-grep warnings about "hardcoded RSA passphrases" on lines 33-36 and 51-54 are false positives—these are RSpec expectation messages explaining test failures, not security credentials. Overall, this test file provides comprehensive coverage of the message deduplication objectives and validates the refactoring work effectively.
Code Review FeedbackThank you for this well-structured refactoring! This is a significant improvement that eliminates ~270 lines of code duplication. Here's my detailed review: ✅ Strengths1. Excellent Code Organization
2. Smart Architectural Decisions
3. Breaking Change Handling
4. Test Coverage
🔍 Potential Issues1. Breaking Change: Removal of Babel Dependencies The new REACT_DEPENDENCIES removes @babel/preset-react, babel-plugin-transform-react-remove-prop-types, and babel-plugin-macros. Users who configure javascript_transpiler: babel will be missing these critical packages. Recommendation: Consider conditionally adding these when Babel is configured, or document the migration clearly in CHANGELOG.md 2. TypeScript + Babel Experience Comment says users should manually add @babel/preset-typescript for TypeScript + Babel, creating poor developer experience with cryptic errors. Recommendation: Consider checking javascript_transpiler setting and conditionally adding @babel/preset-typescript 3. Configuration Key Migration Code still sets webpack_loader (old key) instead of javascript_transpiler. Verify all references are updated. 4. Error Handling Trade-offs 🤔 Consideration: Should some failures be non-fatal with clear remediation steps? 5. Redundant Install? 🎯 Code QualityExcellent:
Minor Suggestions:
🔒 Security✅ No security issues identified 📋 TestingMissing:
📝 DocumentationRequired CHANGELOG entries:
🎬 Recommendation: Approval with ChangesThis is high-quality refactoring that significantly improves maintainability! Before merging:
Overall: Great work! 🎉 Review conducted following CLAUDE.md guidelines |
Code Review - PR #2051: Refactor JS Dependency Management✅ Overall AssessmentThis is an excellent refactoring that successfully eliminates ~270 lines of duplication. The code is well-structured, documented, and follows Ruby best practices. 🎯 Strengths1. Code Organization & DRY Principle
2. Documentation Quality
3. Error Handling
4. Test Coverage
🔍 Code Quality Observations1. Dependency Constant DesignThe frozen constants are well-chosen: REACT_DEPENDENCIES = %w[react react-dom prop-types].freeze✅ Removing Babel dependencies is the right call - Shakapacker handles transpiler config 2. Installation Flowdef setup_js_dependencies
@added_dependencies_to_package_json = false unless defined?(...)
add_js_dependencies
install_js_dependencies # Always runs - idempotent
end✅ Good use of 3. Breaking Change HandlingThe switch from
🚨 Potential Issues1. Error Handling: Raise vs. Warning
|
Comprehensive Code ReviewThank you for this excellent refactoring! The extraction of ~270 lines of duplicated code into a shared module is well-executed with great documentation. However, I've identified several critical issues that should be addressed before merging. Critical Issues (Must Fix)1. 🔴 Inconsistent Error Handling PatternLocation: Problem: The code has conflicting error handling strategies:
This makes the graceful error handling pointless - if Recommendation: Either let exceptions bubble up from Suggested fix: def setup_js_dependencies
@added_dependencies_to_package_json = false unless defined?(@added_dependencies_to_package_json)
begin
add_js_dependencies
install_js_dependencies
rescue StandardError => e
GeneratorMessages.add_warning(<<~MSG.strip)
⚠️ Failed to set up JavaScript dependencies: #{e.message}
Please run manually: npm install
MSG
end
end2. 🔴 Missing
|
…anager - Add RBS type signatures for JsDependencyManager module - Add comprehensive test suite covering all dependency installation scenarios - Improve error handling with better edge case coverage - Update tests to verify Rspack and TypeScript dependency flows - Document breaking changes in CHANGELOG for Babel dependency removal 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Code Review: PR #2051This is an excellent refactoring that successfully eliminates code duplication and improves maintainability. Here's my detailed review: ✅ Strengths1. Excellent Code Organization
2. Comprehensive Test Coverage
3. Type Safety
4. Backwards Compatibility
5. Documentation Quality
🔍 Areas for Consideration1. CHANGELOG PlaceholderLocation: [PR <PLACEHOLDER>](https://github.com/shakacode/react_on_rails/pull/<PLACEHOLDER>)Issue: The PR number placeholder needs to be updated to Fix: [PR 2051](https://github.com/shakacode/react_on_rails/pull/2051)2. Potential Method Naming ImprovementLocation: The method was renamed from 3. Error Handling ConsistencyLocation: The Current behavior:
This isn't a bug, just defensive programming, but could be simplified. 4. Documentation: Installation BehaviorLocation: The comment states installation "ALWAYS" runs after adding dependencies. This is good, but consider documenting what happens if a user runs the generator twice - does it re-install everything or skip already-installed packages? The comment mentions idempotency, which is great. 🔒 Security Review✅ No security concerns identified:
⚡ Performance Considerations✅ Performance impact is positive:
🎯 Best Practices AlignmentFollows Repository Standards:
Breaking Change Management:
📝 RecommendationsRequired Before Merge:
Optional Improvements:
🎉 SummaryOverall Assessment: ✅ Excellent refactoring ready for merge after CHANGELOG fix This PR demonstrates:
The only blocking issue is the CHANGELOG placeholder. Everything else is either minor or optional. Estimated Risk: Low Great work! This refactoring significantly improves the codebase quality. 🚀 |
Address code review feedback to enhance error handling and consistency: - Add exact: true flag to add_package method for consistency with add_npm_dependencies - Add nil check for package_json in install_js_dependencies to prevent nil pointer errors - Remove orphaned comment at end of module - Update tests to verify exact: true flag is passed correctly - Add test coverage for nil package_json scenario in install_js_dependencies These changes improve code robustness while maintaining backward compatibility. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Code Review: JS Dependency Management RefactoringSummaryExcellent refactoring that eliminates ~270 lines of duplicated code by extracting shared JavaScript dependency management into a dedicated module. The code is well-structured, thoroughly tested, and properly documented. ✅ StrengthsCode Quality
Testing
Architecture
|
Address code review feedback: - Update CHANGELOG.md placeholder with PR #2051 - Simplify error warning messages - remove misleading comments about shakapacker dependency since failures can occur for multiple reasons (network errors, permissions, etc.) - Remove redundant puts statement in add_package rescue block since calling methods already add appropriate warnings These changes improve code clarity and user-facing error messages. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Updated Code Review: JS Dependency Manager RefactoringExcellent refactoring work! This PR successfully eliminates code duplication and modernizes the dependency management approach. Here's a comprehensive review: ✅ Major Strengths1. Outstanding Code Organization
2. Smart Dependency Decisions
3. Robust Test Coverage
4. RBS Type Signatures
🔍 Issues Found & RecommendationsCritical: Error Handling Inconsistency
|
There was a problem hiding this 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 (6)
spec/react_on_rails/generators/message_deduplication_spec.rb (2)
12-43: Post‑install message coverage looks good; consider tightening duplicate checksThese examples nicely assert that the success banner is emitted exactly once and that the key sections (“📋 QUICK START:”, “✨ KEY FEATURES:”) are present.
If the original bug involved duplication of the whole post‑install block (not just the headline), you might optionally also count occurrences of “📋 QUICK START:” and “✨ KEY FEATURES:” to ensure they are each emitted once as well. That would guard against future regressions where the body gets duplicated but the headline does not.
67-107: Good isolation of package_json‑based install pathThe “NPM install execution” example cleanly verifies that
setup_js_dependenciesuses thepackage_jsonmanager and does not fall back tosystemwhen the gem is available, which directly exercises the new flow.One small optional improvement: the initial
receive_messagessetsadd_npm_dependencies: falseand the innerbeforeimmediately overrides it withadd_npm_dependencies: true, so the first stub isn’t needed anymore and can be dropped to reduce noise.lib/generators/react_on_rails/js_dependency_manager.rb (2)
84-95: Ensure TypeScript dependencies are actually wired into the setup flowThis module defines
TYPESCRIPT_DEPENDENCIESandadd_typescript_dependencies, butadd_js_dependenciescurrently only calls:
add_react_on_rails_packageadd_react_dependenciesadd_css_dependenciesadd_rspack_dependencies(whenoptions.rspack?)add_dev_dependenciesThere’s no call to
add_typescript_dependencieshere. If the intent is for this module to own all JS dependency installation, it would be more consistent (and less error‑prone) to gate TypeScript installation here as well, e.g.:def add_js_dependencies add_react_on_rails_package add_react_dependencies add_css_dependencies + add_typescript_dependencies if respond_to?(:options) && options&.typescript? # Rspack dependencies are only added when --rspack flag is used add_rspack_dependencies if respond_to?(:options) && options&.rspack? # Dev dependencies vary based on bundler choice add_dev_dependencies endIf
InstallGenerator(or another caller) already invokesadd_typescript_dependenciesdirectly behind--typescript, just ensure that’s the single path so TypeScript installs can’t be accidentally skipped.Also applies to: 109-117
119-148: Simplify error handling aroundadd_react_on_rails_package
add_react_on_rails_packagewrapsadd_packageand then also rescuesStandardError, butadd_packageitself already rescuesStandardErrorand converts failures intofalse. In practice that means errors frompj.manager.addwill always surface via the"Failed to add react-on-rails package."warning, and the"Error adding react-on-rails package: #{e.message}"branch is effectively unreachable.You could either:
- Let
add_packagepropagate exceptions (and rely on therescuehere), or- Drop the outer
rescueand keep the simpler “failed” warning path,to reduce duplication and make it clearer where errors are actually logged.
Also applies to: 262-278
spec/react_on_rails/generators/js_dependency_manager_spec.rb (2)
47-55:warnings/errorshelpers assume a specific message prefixThese helpers filter
GeneratorMessages.outputby checking whetherto_sincludes"WARNING"or"ERROR". That’s fine ifGeneratorMessages.add_warning/add_errorconsistently prefixes messages that way, but it’s a tight coupling: if those methods ever switch to a different label or rely solely on the leading “⚠️ ” glyph, these specs will silently stop seeing warnings.If you want the tests to be more robust, consider either:
- Adding dedicated
GeneratorMessages.warnings/errorsaccessors and using those here, or- Matching on a phrase that comes from the JsDependencyManager messages themselves (e.g.,
"Failed to add React dependencies"), rather than the generic prefix.
217-225: Tighten the failure scenario foradd_react_on_rails_packageIn this example you stub both
mock_manager.addand setinstance.package_json = nil. Becauseadd_packageimmediately returnsfalsewhenpackage_jsonisnil, themock_managerstub is never exercised; the warning is driven solely by the nil package_json case.To make the intent clearer, you could either:
- Drop the
allow(mock_manager).to receive(:add).and_return(false)here and treat this as the “no package_json” path, or- Keep
package_jsonset and rely onmock_manager.addreturningfalseto simulate an API-level failure.Either way, the test will still validate that a warning is emitted when adding the package fails, but with less ambiguity about which failure path you’re targeting.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
CHANGELOG.md(1 hunks)lib/generators/react_on_rails/js_dependency_manager.rb(1 hunks)sig/react_on_rails/generators/js_dependency_manager.rbs(1 hunks)spec/react_on_rails/generators/js_dependency_manager_spec.rb(1 hunks)spec/react_on_rails/generators/message_deduplication_spec.rb(1 hunks)
🧰 Additional context used
🧠 Learnings (9)
📓 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:
CHANGELOG.mdspec/react_on_rails/generators/js_dependency_manager_spec.rblib/generators/react_on_rails/js_dependency_manager.rbsig/react_on_rails/generators/js_dependency_manager.rbs
📚 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:
CHANGELOG.mdspec/react_on_rails/generators/js_dependency_manager_spec.rblib/generators/react_on_rails/js_dependency_manager.rbsig/react_on_rails/generators/js_dependency_manager.rbsspec/react_on_rails/generators/message_deduplication_spec.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:
CHANGELOG.mdspec/react_on_rails/generators/js_dependency_manager_spec.rblib/generators/react_on_rails/js_dependency_manager.rbsig/react_on_rails/generators/js_dependency_manager.rbsspec/react_on_rails/generators/message_deduplication_spec.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:
spec/react_on_rails/generators/js_dependency_manager_spec.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:
spec/react_on_rails/generators/js_dependency_manager_spec.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:
spec/react_on_rails/generators/js_dependency_manager_spec.rblib/generators/react_on_rails/js_dependency_manager.rbsig/react_on_rails/generators/js_dependency_manager.rbs
📚 Learning: 2025-02-13T14:29:49.267Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: spec/react_on_rails/utils_spec.rb:218-218
Timestamp: 2025-02-13T14:29:49.267Z
Learning: In RSpec tests, prefer using local variables over constants within test blocks to avoid constant redefinition warnings and maintain better test isolation.
Applied to files:
spec/react_on_rails/generators/js_dependency_manager_spec.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/js_dependency_manager.rbsig/react_on_rails/generators/js_dependency_manager.rbs
🧬 Code graph analysis (3)
spec/react_on_rails/generators/js_dependency_manager_spec.rb (2)
lib/generators/react_on_rails/generator_messages.rb (1)
output(5-7)lib/generators/react_on_rails/generator_helper.rb (1)
package_json(7-20)
lib/generators/react_on_rails/js_dependency_manager.rb (2)
lib/generators/react_on_rails/generator_helper.rb (1)
package_json(7-20)spec/react_on_rails/generators/js_dependency_manager_spec.rb (1)
add_npm_dependencies(14-18)
spec/react_on_rails/generators/message_deduplication_spec.rb (4)
lib/generators/react_on_rails/base_generator.rb (1)
include(10-316)lib/generators/react_on_rails/install_generator.rb (1)
include(12-435)spec/react_on_rails/support/generator_spec_helper.rb (1)
run_generator_test_with_args(62-72)lib/generators/react_on_rails/generator_messages.rb (1)
output(5-7)
🪛 ast-grep (0.40.0)
spec/react_on_rails/generators/message_deduplication_spec.rb
[warning] 33-36: Found the use of an hardcoded passphrase for RSA. The passphrase can be easily discovered, and therefore should not be stored in source-code. It is recommended to remove the passphrase from source-code, and use system environment variables or a restricted configuration file.
Context: expect(success_count).to(
eq(1),
"Expected success message to appear exactly once, but appeared #{success_count} times"
)
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures [REFERENCES]
https://cwe.mitre.org/data/definitions/522.html
(hardcoded-secret-rsa-passphrase-ruby)
[warning] 51-54: Found the use of an hardcoded passphrase for RSA. The passphrase can be easily discovered, and therefore should not be stored in source-code. It is recommended to remove the passphrase from source-code, and use system environment variables or a restricted configuration file.
Context: expect(success_count).to(
eq(1),
"Expected success message to appear exactly once with Redux, but appeared #{success_count} times"
)
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures [REFERENCES]
https://cwe.mitre.org/data/definitions/522.html
(hardcoded-secret-rsa-passphrase-ruby)
⏰ 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: build-dummy-app-webpack-test-bundles (3.4, 22, latest)
- GitHub Check: build-dummy-app-webpack-test-bundles (3.2, 20, minimum)
- GitHub Check: rspec-package-tests (3.2, minimum)
- GitHub Check: rspec-package-tests (3.4, latest)
- GitHub Check: examples (3.2, minimum)
- GitHub Check: examples (3.4, latest)
- GitHub Check: build-dummy-app-webpack-test-bundles
- GitHub Check: pro-lint-js-and-ruby
- GitHub Check: build-dummy-app-webpack-test-bundles
- GitHub Check: build
- GitHub Check: markdown-link-check
- GitHub Check: claude-review
🔇 Additional comments (2)
sig/react_on_rails/generators/js_dependency_manager.rbs (1)
3-121: RBS signatures align with the Ruby moduleThe constant and method signatures here match the implementation in
lib/generators/react_on_rails/js_dependency_manager.rb(including boolean returns foradd_package,add_packages, andinstall_js_dependencies, and void for the orchestration helpers). This should give Steep/Sorbet a precise view of the new module without over‑constraining callers.CHANGELOG.md (1)
46-52: ****The flagged CHANGELOG entries are not contradictory. The "Shakapacker 9.0.0 Upgrade" entry (PR 1904) documents the decision to configure Babel specifically for that application upgrade due to SWC's PropTypes handling issues. The "Removed Babel Dependency Installation" entry (PR 2051) is a separate changelog item describing a later decision to stop installing Babel in the generator and rely on SWC as the default for new applications. These describe different contexts (upgrading existing apps vs. generating new ones) and different PRs, so no clarification or consolidation is needed.
Likely an incorrect or invalid review comment.
Address code review suggestions:
- Expand module documentation to explain graceful degradation philosophy
in detail, including specific failure scenarios (network, permissions,
package_json gem states)
- Add comprehensive tests for graceful degradation:
* Verify setup_js_dependencies completes without raising when all
package operations fail
* Verify completion when install fails but add succeeds
* Ensure warnings are generated but no errors that crash generators
- Improve add_package method documentation to clarify that exact: true
flag ensures version pinning aligns with gem version, preventing
mismatches between Ruby gem and NPM package
These changes improve code documentation and test coverage without
changing functionality. All 38 tests pass.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Code Review - PR #2051: Refactor JS dependency management into shared moduleSummaryThis is an excellent refactoring that successfully eliminates ~270 lines of duplicated code by extracting JavaScript dependency management into a shared ✅ Strengths1. Excellent Code Organization
2. Strong Test Coverage
3. Type Safety
4. Breaking Change Well Documented
🔍 Code Quality Observations1. Graceful Error Handling ✅The error handling approach is well thought out:
Example from rescue StandardError => e
GeneratorMessages.add_warning(<<~MSG.strip)
⚠️ Error adding React dependencies: #{e.message}
You can install them manually by running:
npm install #{REACT_DEPENDENCIES.join(' ')}
MSG
end2. Removal of Babel Dependencies ✅Smart decision to remove Babel-related packages:
Rationale (from comments):
3. Configuration Changes
|
Code Review: JS Dependency Manager RefactorThank you for this excellent refactoring! This PR significantly improves code maintainability by extracting ~270 lines of duplicated code into a shared module. Here's my detailed review: ✅ Strengths1. Excellent Code Organization
2. Robust Error Handling
3. Smart Babel Removal
4. Type Safety
🔍 Potential Issues & Suggestions1. Breaking Change Documentation
|
Code Review - PR #2051: Refactor JS Dependency ManagementOverall Assessment: Excellent refactoring ✅ This PR successfully eliminates ~270 lines of duplicated code and introduces a well-architected shared module for dependency management. The implementation is solid with comprehensive test coverage and excellent documentation. Strengths 💪Architecture & Design
Code Quality
Breaking Changes Handled Well
Potential Issues & Suggestions 🔍1. Error Handling - Minor ConcernLocation: The def add_package(package, dev: false)
# ...
begin
# ...
rescue StandardError
return false # Caught here
end
end
def add_react_on_rails_package
return if add_package(react_on_rails_pkg)
# Warning added here if false returned
rescue StandardError => e
# Also caught here - might be unreachable?
GeneratorMessages.add_warning(...)
endImpact: Low - The outer rescue blocks in calling methods may be unreachable since Suggestion: Consider simplifying to single-level error handling if the inner rescue always catches everything. 2. Dependency Version ControlLocation: All dependencies except
Example: REACT_DEPENDENCIES = %w[
react # Could install any version
react-dom # Could install any version
prop-types
].freezeImpact: Medium - Users could get different dependency versions depending on when they run the generator. Suggestion: Consider adding version constraints to critical dependencies: REACT_DEPENDENCIES = %w[
react@^18.0.0
react-dom@^18.0.0
prop-types
].freezeHowever, this may be intentional to allow users flexibility. If so, document the reasoning. 3. Test Mock VerificationLocation: Tests use unverified doubles which could mask interface changes: # rubocop:disable RSpec/VerifiedDoubles
let(:mock_manager) { double("PackageManager", install: true, add: true) }
let(:mock_package_json) { double("PackageJson", manager: mock_manager) }
# rubocop:enable RSpec/VerifiedDoublesImpact: Low - Tests could pass even if the actual package_json gem API changes. Suggestion: Consider using verified doubles or instance_double if the package_json gem supports it: let(:mock_manager) { instance_double("PackageJson::Manager", install: true, add: true) }4. Missing TypeScript Integration TestLocation: Test coverage gap The Impact: Low - Unit tests exist, but integration coverage would be more complete. Suggestion: Add test in context "with TypeScript installation" do
it "adds TypeScript dependencies" do
run_generator_test_with_args(%w[--typescript], package_json: true)
# Verify TypeScript packages were added
end
end5. Rspack Dependency CompletenessLocation: When using Rspack, the generator adds Rspack-specific dependencies but still adds Webpack CSS dependencies (CSS_DEPENDENCIES). This might be intentional, but could lead to unused Webpack packages in Rspack projects. Impact: Low - Extra dependencies consume disk space but don't break functionality. Suggestion: Clarify whether CSS_DEPENDENCIES are needed for both Webpack and Rspack, or if Rspack needs its own CSS dependency set. Security Considerations 🔒✅ No security concerns identified
Performance Considerations ⚡✅ Well optimized
Minor observation: The Test Coverage 🧪Excellent coverage (387 lines of tests): ✅ All public methods tested One gap: Missing integration test for TypeScript flag (see #4 above) Documentation 📚Outstanding documentation: ✅ Comprehensive module-level docs The documentation explaining why Babel presets were removed is particularly helpful for users upgrading. Best Practices Alignment 📋✅ Follows repository conventions per CLAUDE.md Recommendations 📝Must FixNone - PR is ready to merge as-is Should Consider
Nice to Have
Conclusion ✨This is excellent work. The refactoring achieves its goals:
The concerns raised are minor and don't block merging. This PR sets a high bar for code quality in the project. Recommendation: ✅ Approve and merge Review generated using repository's CLAUDE.md conventions and React on Rails best practices |
…se-otp-timing * origin/master: (27 commits) Fix doctor command false version mismatch for beta/prerelease versions (#2064) Fix beta/RC version handling in generator (#2066) Document Rails Engine development nuances and add tests for automatic rake task loading (#2067) Add /run-skipped-tests as alias for /run-skipped-ci (#XXXX) (#2068) Fix: Add Rails 5.2-6.0 compatibility for compact_blank (#2058) Break CI circular dependency with non-docs change (#2065) Fix CI safety check to evaluate latest workflow attempt (#2062) Fix yalc publish (#2054) Add Shakapacker 9.0+ private_output_path integration for server bundles (#2028) Consolidate all beta versions into v16.2.0.beta.10 (#2057) Improve reliability of CI debugging scripts (#2056) Clarify monorepo changelog structure in documentation (#2055) Bump version to 16.2.0.beta.10 Bump version to 16.2.0.beta.9 Fix duplicate rake task execution by removing explicit task loading (#2052) Simplify precompile hook and restore Pro dummy app to async loading (#2053) Add Shakapacker precompile hook with ReScript support to Pro dummy app (#1977) Guard master docs-only pushes and ensure full CI runs (#2042) Refactor: Extract JS dependency management into shared module (#2051) Add workflow to detect invalid CI command attempts (#2037) ... # Conflicts: # rakelib/release.rake
Summary
This PR refactors JavaScript dependency management in React on Rails generators by extracting duplicated code into a shared
JsDependencyManagermodule.Changes
BaseGeneratorandInstallGeneratorKey Improvements
Code Organization
Dependency Management
Default Configuration
webpack_loaderchanged from'babel'to'swc'in generated shakapacker.ymlTesting
New test file
spec/react_on_rails/generators/message_deduplication_spec.rbverifies:Migration Notes
For new installations, this change is transparent. Existing projects are not affected as this only impacts the generator output for new setups.
Supersedes and closes #2030 (that PR had merge conflict issues, so starting fresh with a clean branch)
Summary by CodeRabbit
Refactor
Configuration
Tests
Changelog