Recognize TypeScript (.ts) Shakapacker config variants#2567
Recognize TypeScript (.ts) Shakapacker config variants#2567AbanoubGhadban merged 11 commits intomasterfrom
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds TypeScript (".ts") / ESM awareness for Shakapacker configs: detection and template selection now recognize webpack and rspack TypeScript/ESM patterns, prefer Changes
Sequence Diagram(s)sequenceDiagram
participant Generator as InstallGenerator
participant Checker as SystemChecker
participant FS as FileSystem
participant User as Project
rect rgba(200,230,255,0.5)
Generator->>Checker: request bundler_main_config_path / standard check
end
Checker->>FS: detect_bundler_config_path (check rspack.ts -> rspack.js -> webpack.ts -> webpack.js)
FS-->>Checker: path or nil
alt path found
Checker->>FS: read config content
FS-->>Checker: file contents
Checker->>Generator: return detected path + bundler name + stock-pattern match result
else no path
Checker-->>Generator: nil (no bundler config)
end
Generator->>User: proceed (treat as standard vs customized) based on Checker result
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
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 Tip You can make CodeRabbit's review stricter and more nitpicky using the `assertive` profile, if that's what you prefer.Change the |
|
Overall this is a clean, well-motivated fix with good test coverage. A couple of issues to address before merging. Bug: Wrong PR number in CHANGELOG The CHANGELOG entry links to PR 2558 but this PR is 2567. See inline comment. Design: The method always prefers webpack over rspack (webpack.js -> webpack.ts -> rspack.js -> rspack.ts). In the edge case where a project migrated from webpack to rspack and still has a stale
Approach inconsistency between the two affected files
Tests The new test suite is thorough. Particularly good: the |
Greptile SummaryThis PR extends the install generator and system checker to recognise TypeScript ( Key remaining issues:
The core goal — stopping false "customised config" prompts for TypeScript Shakapacker users — is achieved and well-tested. Tests are comprehensive for the new patterns and cover path detection for Confidence Score: 3/5
|
|
All three review comments addressed in 08c0895:
|
Code ReviewOverall this is a clean, well-tested addition. The core logic for detecting 1. Stale hardcoded
|
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
react_on_rails/lib/react_on_rails/system_checker.rb (1)
363-379:⚠️ Potential issue | 🟡 MinorUse bundler-neutral messaging in the content check.
When
webpack_config_pathpoints toconfig/rspack/rspack.config.{js,ts}, these branches still report “Webpack config…”. That makesreact_on_rails:doctoroutput misleading for the new rspack paths this PR adds. Deriving the label from the detected path or switching these messages to “bundler config” would keep the output accurate.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@react_on_rails/lib/react_on_rails/system_checker.rb` around lines 363 - 379, The messages assume "Webpack" but the checker can also detect rspack paths; update the text emitted by the branches using react_on_rails_config?, standard_shakapacker_config?, and the else branch to be bundler-neutral (e.g., use "Bundler config" or derive the label from webpack_config_path when it contains "rspack") so react_on_rails:doctor reports accurate labels for rspack configs; change the add_success/add_info/add_warning strings accordingly to avoid hardcoding "Webpack".
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@CHANGELOG.md`:
- Line 35: Update the changelog entry to reference the correct pull request
number and URL: replace `[PR
2558](https://github.com/shakacode/react_on_rails/pull/2558)` with `[PR
2567](https://github.com/shakacode/react_on_rails/pull/2567)` (keeping the
existing author attribution
`[AbanoubGhadban](https://github.com/AbanoubGhadban)`); ensure the PR link uses
the exact format shown in the guidelines so the entry points to PR 2567 instead
of 2558.
In `@react_on_rails/lib/generators/react_on_rails/base_generator.rb`:
- Around line 341-356: The shakapacker_esm_default_configs method is missing the
TypeScript/ESM stock variant that imports webpackConfig directly; add a third
heredoc entry matching "import { webpackConfig } from 'shakapacker' ... export
default webpackConfig" to shakapacker_esm_default_configs so apps using that
exact template are recognized as unmodified, and update the corresponding regex
mirror in system_checker.rb (the pattern that checks for ESM Shakapacker
defaults) to include this new variant so the system checker treats that stock
template as unchanged.
---
Outside diff comments:
In `@react_on_rails/lib/react_on_rails/system_checker.rb`:
- Around line 363-379: The messages assume "Webpack" but the checker can also
detect rspack paths; update the text emitted by the branches using
react_on_rails_config?, standard_shakapacker_config?, and the else branch to be
bundler-neutral (e.g., use "Bundler config" or derive the label from
webpack_config_path when it contains "rspack") so react_on_rails:doctor reports
accurate labels for rspack configs; change the add_success/add_info/add_warning
strings accordingly to avoid hardcoding "Webpack".
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 689c49c0-337e-4d32-a73f-baaf70c1f0ab
📒 Files selected for processing (5)
CHANGELOG.mdreact_on_rails/lib/generators/react_on_rails/base_generator.rbreact_on_rails/lib/react_on_rails/system_checker.rbreact_on_rails/spec/lib/react_on_rails/system_checker_spec.rbreact_on_rails/spec/react_on_rails/generators/install_generator_spec.rb
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 39b01638e7
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
Also addressed CodeRabbit's outside-diff suggestion in 6d3cac2: |
PR Review: Recognize TypeScript (.ts) Shakapacker config variantsOverall, this is a well-scoped fix for a real pain point: Shakapacker 9.4+ TypeScript configs being incorrectly treated as customized. The approach is sound and the test coverage is solid. A few issues worth addressing: Bug:
Fragile: ESM template exact matching does not handle double-quoted imports
Minor: Priority assumption in The comment says "rspack is more likely to be the active bundler (it's the newer default)" to justify checking rspack paths first. This does not hold for a project mid-migration where both config files coexist with webpack being active. The heuristic is a reasonable default, but the comment overstates its reliability. |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@react_on_rails/lib/react_on_rails/system_checker.rb`:
- Around line 309-317: detect_bundler_config_path currently returns the first
matching config path and can misidentify the active bundler when both rspack and
webpack configs exist; update detect_bundler_config_path to detect both rspack
and webpack files (e.g., collect matches for the rspack paths and webpack
paths), and if both sets are present, resolve the active bundler by checking for
a Shakapacker indicator (such as presence/contents of a shakapacker config or
gem usage) or emit a clear warning about ambiguity instead of silently picking
the first match; ensure the method still returns a single path when unambiguous
and document/return a distinct value (or nil) when ambiguous so callers (e.g.,
any callers expecting "standard/custom" diagnosis) can handle the ambiguity.
- Around line 294-298: The follow-up guidance in suggest_webpack_inspection is
still generic for webpack and doesn't account for rspack/TS configs; update the
call site in system_checker.rb (where detect_bundler_config_path sets
config_path and check_webpack_config_content is called) to pass the detected
config identifier (config_path or a derived bundler_name) into
suggest_webpack_inspection, and then modify suggest_webpack_inspection to
customize its messages based on that parameter (e.g., show
rspack/rspack.config.ts inspection hints vs. webpack/config/webpack.config.js
and module.exports), or alternatively create separate helpers for webpack vs
rspack and call the appropriate one using the detected bundler.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 777e11dd-89c9-4e1c-9da2-e7067a166d7a
📒 Files selected for processing (1)
react_on_rails/lib/react_on_rails/system_checker.rb
ReviewOverall: This is a clean, well-scoped fix. The core logic — adding ESM/TS patterns to One practical leftover worth addressing:
Minor notes (non-blocking):
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
react_on_rails/lib/generators/react_on_rails/base_generator.rb (1)
365-368: ESMwebpackConfigvariant may be unnecessary.Per the retrieved learnings: "the
webpackConfigobject export (v6-style) only ever existed as CommonJS." Shakapacker v9.4+ exclusively usesgenerateWebpackConfig/generateRspackConfig. This ESM pattern:import { webpackConfig } from 'shakapacker' export default webpackConfig...doesn't match any stock Shakapacker template. Including it is harmless but adds dead code that will never match a real configuration.
Based on learnings: "In Shakapacker, the
webpackConfigobject export (v6-style) only ever existed as CommonJS."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@react_on_rails/lib/generators/react_on_rails/base_generator.rb` around lines 365 - 368, The generated ESM variant that imports and exports a v6-style webpackConfig is dead code; remove the block that adds "import { webpackConfig } from 'shakapacker' / export default webpackConfig" to the configs array in the generator (the snippet that references webpackConfig) and only emit the modern patterns (generateWebpackConfig / generateRspackConfig) used by Shakapacker v9.4+ so the generator produces realistic templates; locate the configs construction in BaseGenerator (the code that appends the ESM webpackConfig string) and delete that append or guard it behind a Shakapacker-version check that prevents emitting the obsolete webpackConfig export.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@react_on_rails/lib/generators/react_on_rails/base_generator.rb`:
- Around line 286-289: The helper bundler_main_config_template_path currently
always returns a webpack template; update it to choose rspack templates when the
target is an rspack config: inspect config_path (or its basename) for "rspack"
(e.g., "config/rspack/" or "rspack.config.*") and set template_file_name to
"rspack.config.ts.tt" or "rspack.config.js.tt" when appropriate, otherwise fall
back to the existing "webpack.config.ts.tt"/"webpack.config.js.tt"; modify
bundler_main_config_template_path to use that conditional logic so rspack
configs receive the correct template.
---
Nitpick comments:
In `@react_on_rails/lib/generators/react_on_rails/base_generator.rb`:
- Around line 365-368: The generated ESM variant that imports and exports a
v6-style webpackConfig is dead code; remove the block that adds "import {
webpackConfig } from 'shakapacker' / export default webpackConfig" to the
configs array in the generator (the snippet that references webpackConfig) and
only emit the modern patterns (generateWebpackConfig / generateRspackConfig)
used by Shakapacker v9.4+ so the generator produces realistic templates; locate
the configs construction in BaseGenerator (the code that appends the ESM
webpackConfig string) and delete that append or guard it behind a
Shakapacker-version check that prevents emitting the obsolete webpackConfig
export.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: c277ce15-ca42-43cd-83fc-44335ac14fd8
📒 Files selected for processing (5)
react_on_rails/lib/generators/react_on_rails/base_generator.rbreact_on_rails/lib/generators/react_on_rails/templates/base/base/config/webpack/webpack.config.ts.ttreact_on_rails/lib/react_on_rails/system_checker.rbreact_on_rails/spec/lib/react_on_rails/system_checker_spec.rbreact_on_rails/spec/react_on_rails/generators/install_generator_spec.rb
🚧 Files skipped from review as they are similar to previous changes (1)
- react_on_rails/spec/react_on_rails/generators/install_generator_spec.rb
| add_info("ℹ️ Custom webpack config detected") | ||
| add_info("ℹ️ Custom #{bundler_name} config detected") | ||
| add_info(" 💡 Ensure config supports both client and server rendering") | ||
| add_info(" 💡 Verify React JSX transformation is configured") |
There was a problem hiding this comment.
This regex scans the entire YAML file and returns the first assets_bundler: match regardless of which environment block it belongs to. If a project sets assets_bundler: rspack only under test:, this will report rspack even when default: uses webpack. Consider parsing the YAML properly (e.g., YAML.safe_load(config_content).dig("default", "assets_bundler")) or at least noting this limitation in a comment.
| # count as potential customizations and keep cleanup conservative. | ||
| normalized_content.gsub(/\s+/, " ").strip | ||
| normalized_content.gsub(/\s+/, " ") | ||
| .tr('"', "'") # Normalize quote style for import/require statements |
There was a problem hiding this comment.
The comment "Normalize quote style for import/require statements" is slightly misleading — .tr transforms ALL double-quote characters in the string, not just those in import/require lines. This is harmless since both sides of every comparison are normalized identically, but the comment should say something like "Normalize all double quotes to single quotes for consistent string comparison" to avoid confusing future readers.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f5091c5399
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| return nil unless File.exist?(shakapacker_config_path) | ||
|
|
||
| config_content = File.read(shakapacker_config_path) | ||
| match = config_content.match(/^\s*assets_bundler:\s*["']?(webpack|rspack)["']?\s*$/) |
There was a problem hiding this comment.
Parse assets_bundler from YAML instead of strict regex
configured_assets_bundler only matches lines that end immediately after webpack|rspack, so common valid forms like assets_bundler: "webpack" # comment (or ERB-expanded variants) return nil. When both webpack and rspack config files exist, detect_bundler_config_path then falls back to rspack and the doctor checks the wrong bundler config, which can produce misleading diagnostics about whether the active setup is standard/custom. Parsing config/shakapacker.yml via YAML (as done elsewhere) or relaxing this pattern to allow trailing comments would avoid that mis-detection.
Useful? React with 👍 / 👎.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
ReviewSolid fix for a real user-facing pain point. The structure is clean and the test coverage is thorough. A few items worth addressing: 1. 2. YAML parsed with regex in 3. Minor template style inconsistency — |
| ) | ||
|
|
||
| add_info("💡 To analyze bundle size:") | ||
| if bundle_analyzer_available? |
There was a problem hiding this comment.
The bundle_analyzer_available? check is bundler-agnostic (it only looks for webpack-bundle-analyzer), but this branch is hit regardless of which bundler is active. If an rspack project has a leftover webpack-bundle-analyzer in package.json, this branch fires and the output says "This opens the configured bundle analyzer in your browser" — misleading because webpack-bundle-analyzer doesn't support rspack.
Consider guarding by bundler name too:
| if bundle_analyzer_available? | |
| add_info("💡 To analyze bundle size:") | |
| if bundle_analyzer_available? && bundler_name == "webpack" |
| return nil unless File.exist?(shakapacker_config_path) | ||
|
|
||
| config_content = File.read(shakapacker_config_path) | ||
| match = config_content.match(/^\s*assets_bundler:\s*["']?(webpack|rspack)["']?\s*$/) |
There was a problem hiding this comment.
Parsing YAML with a line-anchored regex is fragile. It will miss:
- Values inherited via anchors/aliases (e.g.,
default: &default\n assets_bundler: rspackthenproduction:\n <<: *default) - Any whitespace/quoting variation not covered by the regex
YAML.safe_load is more robust and the rescue StandardError already guards against malformed files:
| match = config_content.match(/^\s*assets_bundler:\s*["']?(webpack|rspack)["']?\s*$/) | |
| config = YAML.safe_load(config_content, symbolize_names: false) | |
| config.is_a?(Hash) && config.values.flat_map { |v| v.is_a?(Hash) ? [v["assets_bundler"]] : [] }.compact.first || | |
| config["assets_bundler"] |
Or more simply — since only the default key matters in most Shakapacker setups:
parsed = YAML.safe_load(config_content) || {}
(parsed.dig("default", "assets_bundler") || parsed["assets_bundler"])&.then { |v| %w[webpack rspack].include?(v) ? v : nil }| const path = resolve(__dirname, `${env.nodeEnv}.js`) | ||
| if (existsSync(path)) { | ||
| console.log(`Loading ENV specific rspack configuration file ${path}`) | ||
| return require(path) |
There was a problem hiding this comment.
The .js.tt templates use if/else, but the new .ts.tt counterparts use early-return style (no else). Minor inconsistency — worth aligning so the CJS and ESM templates read the same way. Either direction is fine, just pick one.
| # count as potential customizations and keep cleanup conservative. | ||
| normalized_content.gsub(/\s+/, " ").strip | ||
| normalized_content.gsub(/\s+/, " ") | ||
| .tr('"', "'") # Normalize quote style for import/require statements |
There was a problem hiding this comment.
.tr('"', "'") does a character-level replacement across the entire file content, including inside comments when strip_comments: false (the default). A line like // see "https://example.com" becomes // see 'https://example.com' before comparison. This won't cause false positives on current templates, but it's a broader transform than intended. If the goal is only to normalise import/require string delimiters, a more targeted approach (e.g., gsub(/from\s+"([^"]+)"/, "from '\\1'")) would be safer and self-documenting.
Fixes #2553 Shakapacker 9.4+ generates TypeScript configs with ESM syntax when tsconfig.json exists, but the generator and system checker only recognized CommonJS (.js) patterns — causing false "customized config" prompts. Changes: - Detect .ts config files in bundler_main_config_path - Add ESM/TypeScript stock config templates for exact-match detection - Add dedicated replacement templates for webpack TS, rspack JS, rspack TS - Select correct template via bundler_main_config_template_path - System checker: detect all 4 config paths, consult shakapacker.yml for active bundler, bundler-neutral diagnostic messages - Quote normalization in config content matching - 15+ new test cases Co-Authored-By: Justin Gordon <[email protected]> Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Fixes #2553 Shakapacker 9.4+ generates TypeScript configs with ESM syntax when tsconfig.json exists, but the generator and system checker only recognized CommonJS (.js) patterns — causing false "customized config" prompts. Changes: - Detect .ts config files in bundler_main_config_path - Add ESM/TypeScript stock config templates for exact-match detection - Add dedicated replacement templates for webpack TS, rspack JS, rspack TS - Select correct template via bundler_main_config_template_path - System checker: detect all 4 config paths, consult shakapacker.yml for active bundler, bundler-neutral diagnostic messages - Quote normalization in config content matching - 15+ new test cases Co-Authored-By: Justin Gordon <[email protected]> Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Fixes #2553 Shakapacker 9.4+ generates TypeScript configs with ESM syntax when tsconfig.json exists, but the generator and system checker only recognized CommonJS (.js) patterns — causing false "customized config" prompts. Changes: - Detect .ts config files in bundler_main_config_path - Add ESM/TypeScript stock config templates for exact-match detection - Add dedicated replacement templates for webpack TS, rspack JS, rspack TS - Select correct template via bundler_main_config_template_path - System checker: detect all 4 config paths, consult shakapacker.yml for active bundler, bundler-neutral diagnostic messages - Quote normalization in config content matching - 15+ new test cases Co-Authored-By: Justin Gordon <[email protected]> Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Summary
Fixes #2553
base_generator.rb:bundler_main_config_pathnow detects.tsconfig files (webpack + rspack);shakapacker_default_configsadds 4 ESM/TypeScript template patterns for Shakapacker 9.4+system_checker.rb:shakapacker_configured?checks all 4 config paths (.js/.ts× webpack/rspack);standard_shakapacker_config?adds ESM + rspack regex patterns;check_webpack_configurationdynamically detects whichever config file exists.tspath detection, and system checker ESM patternsTest plan
bundle exec rspecon#standard_shakapacker_config?(11 examples, 0 failures)bundle exec rspecon#bundler_main_config_path(4 examples, 0 failures)bundle exec rspeconsystem_checker_spec.rb(49 examples, 0 failures)bundle exec rubocopon all 4 changed files (0 offenses)🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Improvements
Tests