Skip to content

Recognize TypeScript (.ts) Shakapacker config variants#2567

Merged
AbanoubGhadban merged 11 commits intomasterfrom
fix/2553-ts-config-variants
Mar 16, 2026
Merged

Recognize TypeScript (.ts) Shakapacker config variants#2567
AbanoubGhadban merged 11 commits intomasterfrom
fix/2553-ts-config-variants

Conversation

@AbanoubGhadban
Copy link
Copy Markdown
Collaborator

@AbanoubGhadban AbanoubGhadban commented Mar 8, 2026

Summary

Fixes #2553

  • base_generator.rb: bundler_main_config_path now detects .ts config files (webpack + rspack); shakapacker_default_configs adds 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_configuration dynamically detects whichever config file exists
  • Tests: 15 new test cases covering TS variant recognition, .ts path detection, and system checker ESM patterns

Test plan

  • bundle exec rspec on #standard_shakapacker_config? (11 examples, 0 failures)
  • bundle exec rspec on #bundler_main_config_path (4 examples, 0 failures)
  • bundle exec rspec on system_checker_spec.rb (49 examples, 0 failures)
  • bundle exec rubocop on all 4 changed files (0 offenses)
  • Full generator spec suite (124 examples, 0 failures)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Recognize TypeScript (.ts) bundler config variants and add ES Module (ESM) default configurations and TypeScript config templates.
  • Improvements

    • Broader bundler detection for webpack and rspack (JS/TS), prefer TS when present, treat TS configs as customizable, and deliver clearer bundler-aware diagnostic messaging.
  • Tests

    • Expanded coverage for TS/ESM and rspack/webpack detection, template selection, and standard config pattern recognition.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 8, 2026

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds TypeScript (".ts") / ESM awareness for Shakapacker configs: detection and template selection now recognize webpack and rspack TypeScript/ESM patterns, prefer .ts when present, and propagate the detected bundler config path/name through the generator and system checker.

Changes

Cohort / File(s) Summary
Config Path Resolution & Default Patterns
react_on_rails/lib/generators/react_on_rails/base_generator.rb
Prefer .ts variants when present in bundler_main_config_path; add bundler_main_config_template_path; split default lists into shakapacker_cjs_default_configs and new shakapacker_esm_default_configs; shakapacker_default_configs now concatenates CJS + ESM. Quote normalization added in normalize_config_content.
Bundler Detection & System Checks
react_on_rails/lib/react_on_rails/system_checker.rb
Add detect_bundler_config_path and bundler_config_file_exists?; check_webpack_configuration uses detector and passes resolved config_path to check_webpack_config_content(config_path); standard_shakapacker_config? expanded to recognize JS (CJS) and TS (ESM) stock patterns for webpack and rspack; messages now reference detected bundler name.
Generator Template Copying
react_on_rails/lib/generators/react_on_rails/base_generator.rb (template calls)
Switch template calls to use computed template_path/bundler_main_config_template_path to select TS vs JS templates during copy/replace operations.
Templates — TypeScript stock config
react_on_rails/lib/generators/react_on_rails/templates/.../config/webpack/webpack.config.ts.tt
Add new TypeScript webpack config template that imports and exports an env-specific configuration as the default export (ESM-style).
Tests — System Checker
react_on_rails/spec/lib/react_on_rails/system_checker_spec.rb
Expand specs to cover existence and detection of webpack.config.{js,ts} and rspack.config.{js,ts}; add tests for detect_bundler_config_path, bundler-agnostic checks, and ESM/TS pattern recognition.
Tests — Install Generator
react_on_rails/spec/react_on_rails/generators/install_generator_spec.rb
Add tests ensuring .ts preference in bundler_main_config_path, that TypeScript stock configs (typed/untyped, double quotes) are recognized, and copy uses TS template when target ends with .ts.
Changelog
CHANGELOG.md
Documented support for TypeScript (.ts) Shakapacker config variants and related generator/system-checker updates.

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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I hopped through configs, .js and .ts,
Searched for imports, exports, rspack and webpack glee.
Found stock patterns both CJS and ESM,
Chose .ts when present, no replace mayhem.
The rabbit nods: smoother installs for thee!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'Recognize TypeScript (.ts) Shakapacker config variants' directly and clearly describes the main change: adding support for TypeScript configuration files in the Shakapacker config recognition system.
Linked Issues check ✅ Passed The PR fully addresses issue #2553 by adding TypeScript pattern detection to both base_generator.rb and system_checker.rb, recognizing all four TS config variants as stock defaults rather than customized configs.
Out of Scope Changes check ✅ Passed All changes are directly related to the stated objective of recognizing TypeScript config variants. Template additions, method updates, and test expansions are all in scope for the TS config recognition goal.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/2553-ts-config-variants
📝 Coding Plan
  • Generate coding plan for human review comments

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.

Tip

You can make CodeRabbit's review stricter and more nitpicky using the `assertive` profile, if that's what you prefer.

Change the reviews.profile setting to assertive to make CodeRabbit's nitpick more issues in your PRs.

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 8, 2026

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: detect_bundler_config_path fixed ordering in system_checker.rb

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 config/webpack/webpack.config.js, the system checker would silently validate the wrong config file.

base_generator.rb's bundler_main_config_path correctly gates on using_rspack? first. The system checker does not have access to that flag, but could check rspack paths before webpack paths (rspack configs are newer and more likely intentional when co-present), or at least document the ordering choice.

Approach inconsistency between the two affected files

base_generator.rb standard_shakapacker_config? uses exact string matching (after normalization), while system_checker.rb standard_shakapacker_config? uses regex matching. This is intentional and correct, but a brief comment in each method explaining the rationale would help future maintainers.

Tests

The new test suite is thorough. Particularly good: the before block in system_checker_spec.rb that defaults all 4 config paths to false, ensuring each test is isolated.

Comment thread CHANGELOG.md Outdated
Comment thread react_on_rails/lib/react_on_rails/system_checker.rb
Comment thread react_on_rails/lib/react_on_rails/system_checker.rb
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Mar 8, 2026

Greptile Summary

This PR extends the install generator and system checker to recognise TypeScript (.ts) Shakapacker config variants introduced in Shakapacker 9.4+. The fix adds ESM regex patterns to standard_shakapacker_config?, updates bundler_main_config_path to prefer .ts files when they exist, and broadens shakapacker_configured? and detect_bundler_config_path to cover all four config variants (webpack.config.{js,ts} and rspack.config.{js,ts}).

Key remaining issues:

  • Template mismatch: All three template() call-sites in copy_webpack_main_config still use the JavaScript template unconditionally. When a TypeScript config is detected and replaced, the generated file at the .ts path will contain CommonJS JavaScript content rather than idiomatic TypeScript, silently downgrading TypeScript-first projects.
  • Ordering inconsistency: detect_bundler_config_path (system checker) prefers .js over .ts, while bundler_main_config_path (generator) prefers .ts over .js. In the unlikely edge case where both coexist, they would operate on different files.
  • Stale debug hint: suggest_webpack_inspection hardcodes config/webpack/webpack.config.js and module.exports syntax, which is misleading for TypeScript or rspack users seeking debugging guidance.
  • CHANGELOG typo: The PR link references Pin npm shakapacker version to match gem in example generation #2558 instead of the current PR Recognize TypeScript (.ts) Shakapacker config variants #2567.

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 .ts variants. However, the logic gap where the generator replaces a .ts config with CommonJS JavaScript content should be addressed before merging.

Confidence Score: 3/5

  • Safe to merge for detection improvements, but the JS-template-to-TS-path issue should be addressed to avoid silently downgrading TypeScript projects.
  • The PR successfully achieves its core goal — stopping false "customised config" prompts for TypeScript Shakapacker users. Detection logic is sound, pattern matching is comprehensive, and tests are thorough. However, there is a logic gap where the generator replaces a detected .ts config file using the CommonJS JavaScript template, which downgrades TypeScript-first setups. This is a real regression that should be fixed before merging. Additionally, there are three minor but worth-noting issues: ordering inconsistency between checker and generator, stale hardcoded debugging instructions, and a CHANGELOG PR link typo.
  • react_on_rails/lib/generators/react_on_rails/base_generator.rb — the template selection logic needs to be dynamic (choose between .js.tt and .ts.tt based on the detected config path).

Comments Outside Diff (2)

  1. react_on_rails/lib/generators/react_on_rails/base_generator.rb, line 207-221 (link)

    JS template applied to TypeScript config path

    When a .ts config is detected as a standard Shakapacker config (lines 251–252, 256–257 of bundler_main_config_path), the generator removes it and re-creates the file using the webpack.config.js.tt template — but writes it back to the .ts path. This means a TypeScript config (webpack.config.ts) gets overwritten with CommonJS JavaScript content (require/module.exports), which is syntactically valid JavaScript but defeats the purpose of TypeScript-first projects.

    The same problem occurs at line 221 (fresh install) and line 241 (user-consented replacement).

    Consider either:

    1. Generating a separate .ts.tt template and choosing the template based on the detected config extension, or
    2. Logging a note that the TypeScript config is being replaced with JavaScript-flavoured template content.
  2. react_on_rails/lib/react_on_rails/system_checker.rb, line 324-328 (link)

    Stale hardcoded path and CommonJS-specific instruction

    Line 325 hardcodes a reference to config/webpack/webpack.config.js and module.exports syntax, neither of which applies to rspack or TypeScript ESM setups. A user with webpack.config.ts or rspack.config.ts would follow advice pointing them at the wrong file and referencing syntax that doesn't exist in their config.

    Consider making the hint dynamic by detecting the actual config path:

Last reviewed commit: 39b0163

Comment thread react_on_rails/lib/react_on_rails/system_checker.rb
Comment thread CHANGELOG.md Outdated
@AbanoubGhadban
Copy link
Copy Markdown
Collaborator Author

All three review comments addressed in 08c0895:

  1. CHANGELOG PR number: Fixed link from PR 2558 → PR 2567
  2. detect_bundler_config_path ordering: Reordered to check rspack paths first (rspack is newer, more likely the active bundler when both co-exist). Added explanatory comment.
  3. Regex vs exact matching comment: Added clarifying comment to system_checker.rb's standard_shakapacker_config? explaining the intentional difference from base_generator.rb's exact-string approach.

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 8, 2026

Code Review

Overall this is a clean, well-tested addition. The core logic for detecting .ts configs and recognizing ESM syntax is correct. A few issues worth addressing:

1. Stale hardcoded webpack.config.js paths in suggest_webpack_inspection

suggest_webpack_inspection (system_checker.rb ~L327, L338) still references config/webpack/webpack.config.js literally in its user-facing hint strings. Rspack users who trigger this code path will see webpack-specific debug instructions that don't apply to their setup. This method should either receive the detected config_path as an argument and interpolate it, or update the references to be more generic.

2. check_webpack_config_content messages say "Webpack config" for all bundlers

Lines ~366 and ~370 in system_checker.rb emit messages like "✅ Webpack config includes React on Rails environment configuration" and "⚠️ Standard Shakapacker webpack config detected." These are shown even when the detected file is an rspack config. The method is now bundler-agnostic but its output strings are not.

3. detect_bundler_config_path priority ordering may surprise users

The comment justifies checking rspack paths first with "rspack is more likely to be the active bundler (it's the newer default)" — but the vast majority of existing installs use webpack. The consequence is: if someone has both a leftover rspack config and an active webpack config, the checker silently audits the wrong file.

base_generator.rb resolves this correctly by using using_rspack? (option-driven) rather than file-system heuristics. Consider passing a bundler hint to detect_bundler_config_path, or at least reversing the priority so webpack-first matches align with what most users have.

4. Missing comment-banner variants for ESM configs in shakapacker_esm_default_configs

The CJS config list (shakapacker_cjs_default_configs) includes both the comment-banner version (with the // See the shakacode/shakapacker README... header) and the plain version for each template. The new ESM configs only include the plain versions. If Shakapacker 9.4+ generates .ts configs with that comment header, standard_shakapacker_config? in base_generator.rb will return false and incorrectly treat the file as customized. Worth either checking what Shakapacker 9.4 actually generates or adding comment-banner variants defensively.

5. No test coverage for detect_bundler_config_path

The new detect_bundler_config_path method has no dedicated unit test. Given that its priority ordering is a deliberate design choice (rspack before webpack), a test verifying "when both rspack and webpack configs exist, rspack path is returned" would prevent accidental future regression — and also force a conversation about whether that priority is intentional.

Comment thread react_on_rails/lib/react_on_rails/system_checker.rb Outdated
Comment thread react_on_rails/lib/generators/react_on_rails/base_generator.rb
Comment thread react_on_rails/lib/react_on_rails/system_checker.rb Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

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

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

363-379: ⚠️ Potential issue | 🟡 Minor

Use bundler-neutral messaging in the content check.

When webpack_config_path points to config/rspack/rspack.config.{js,ts}, these branches still report “Webpack config…”. That makes react_on_rails:doctor output 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

📥 Commits

Reviewing files that changed from the base of the PR and between 61b1f49 and 39b0163.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • react_on_rails/lib/generators/react_on_rails/base_generator.rb
  • react_on_rails/lib/react_on_rails/system_checker.rb
  • react_on_rails/spec/lib/react_on_rails/system_checker_spec.rb
  • react_on_rails/spec/react_on_rails/generators/install_generator_spec.rb

Comment thread CHANGELOG.md Outdated
Comment thread react_on_rails/lib/generators/react_on_rails/base_generator.rb
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 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".

Comment thread react_on_rails/lib/generators/react_on_rails/base_generator.rb
Comment thread react_on_rails/lib/react_on_rails/system_checker.rb Outdated
@AbanoubGhadban
Copy link
Copy Markdown
Collaborator Author

Also addressed CodeRabbit's outside-diff suggestion in 6d3cac2: check_webpack_config_content now derives bundler name from the config path, so react_on_rails:doctor shows "rspack" or "webpack" accurately instead of always saying "Webpack".

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 8, 2026

PR Review: Recognize TypeScript (.ts) Shakapacker config variants

Overall, 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: suggest_webpack_inspection gives wrong advice for rspack users

check_webpack_configuration now correctly handles rspack configs, but it calls suggest_webpack_inspection unconditionally. That method still has hardcoded webpack-specific advice: it instructs users to add debugger; before module.exports in config/webpack/webpack.config.js (wrong for rspack), and recommends yarn add --dev webpack-bundle-analyzer with edits to config/webpack/webpack.config.js for bundle analysis (webpack-bundle-analyzer is webpack-specific; rspack uses @rspack/plugin-bundle-analyzer). An rspack user running the system checker will see these incorrect instructions.

Fragile: ESM template exact matching does not handle double-quoted imports

shakapacker_esm_default_configs uses single-quoted import paths. normalize_config_content only strips comments and collapses whitespace — it does not normalize quote style. If Shakapacker or a user's Prettier config generates the TypeScript config with double quotes, content_matches_template? will not match and the generator will treat a stock config as customized. TypeScript/ESM projects with Prettier commonly use singleQuote: false.

Minor: Priority assumption in detect_bundler_config_path is weak

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.

Comment thread react_on_rails/lib/react_on_rails/system_checker.rb Outdated
Comment thread react_on_rails/lib/react_on_rails/system_checker.rb Outdated
Comment thread react_on_rails/lib/generators/react_on_rails/base_generator.rb
Copy link
Copy Markdown
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

🤖 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

📥 Commits

Reviewing files that changed from the base of the PR and between 08c0895 and 6d3cac2.

📒 Files selected for processing (1)
  • react_on_rails/lib/react_on_rails/system_checker.rb

Comment thread react_on_rails/lib/react_on_rails/system_checker.rb Outdated
Comment thread react_on_rails/lib/react_on_rails/system_checker.rb Outdated
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 8, 2026

Review

Overall: This is a clean, well-scoped fix. The core logic — adding ESM/TS patterns to shakapacker_default_configs and making shakapacker_configured?/check_webpack_configuration bundler-agnostic — is correct and well-tested. Good use of exact-string matching in base_generator.rb vs. looser regex matching in system_checker.rb; the explanatory comment at line 454 calling out the intentional difference is appreciated.

One practical leftover worth addressing:

suggest_webpack_inspection is invoked unconditionally from check_webpack_configuration for all bundler configs, yet it still hardcodes webpack-specific file paths in its tips. An rspack user running rails react_on_rails:doctor will see advice pointing to config/webpack/webpack.config.js — a path that does not exist in their project. This is a pre-existing issue, but the PR is the first to route rspack configs through this method, so now is the right moment to address it (see inline comment).

Minor notes (non-blocking):

  • bundler_config_file_exists? and detect_bundler_config_path check paths in opposite order (webpack-first vs rspack-first). Different purposes so it is fine, but a short comment on bundler_config_file_exists? noting that order is insignificant there would prevent future confusion.
  • The test "rejects customized TypeScript config with user modifications" in install_generator_spec.rb uses resolve!.extensions! which is not valid TypeScript syntax. The assertion is still correct (exact-match normalisation rejects the content regardless), but using a realistic modification like appending a plugin would make the test intent clearer.

Comment thread react_on_rails/lib/react_on_rails/system_checker.rb
@AbanoubGhadban AbanoubGhadban requested a review from ihabadham March 8, 2026 16:30
@justin808 justin808 added bug P2 Backlog priority codex PRs created from codex-named branches labels Mar 11, 2026
Copy link
Copy Markdown
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 (1)
react_on_rails/lib/generators/react_on_rails/base_generator.rb (1)

365-368: ESM webpackConfig variant may be unnecessary.

Per the retrieved learnings: "the webpackConfig object export (v6-style) only ever existed as CommonJS." Shakapacker v9.4+ exclusively uses generateWebpackConfig/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 webpackConfig object 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

📥 Commits

Reviewing files that changed from the base of the PR and between 1f3dd6d and 9da159c.

📒 Files selected for processing (5)
  • react_on_rails/lib/generators/react_on_rails/base_generator.rb
  • react_on_rails/lib/generators/react_on_rails/templates/base/base/config/webpack/webpack.config.ts.tt
  • react_on_rails/lib/react_on_rails/system_checker.rb
  • react_on_rails/spec/lib/react_on_rails/system_checker_spec.rb
  • react_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

Comment thread react_on_rails/lib/generators/react_on_rails/base_generator.rb
Comment thread react_on_rails/lib/generators/react_on_rails/base_generator.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")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 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*$/)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge 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 👍 / 👎.

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 16, 2026

Review

Solid fix for a real user-facing pain point. The structure is clean and the test coverage is thorough. A few items worth addressing:

1. bundle_analyzer_available? false-positive for rspack — the method only checks for webpack-bundle-analyzer. If an rspack project has that package in package.json (e.g., from a webpack migration), suggest_webpack_inspection takes the if bundle_analyzer_available? branch and shows "This opens the configured bundle analyzer in your browser" even though webpack-bundle-analyzer does not support rspack. The bundler_name guard only exists in the elsif branch.

2. YAML parsed with regex in configured_assets_bundler — the regex won't match values arriving via YAML anchors/aliases (<<: *default) or values that only exist inside environment-specific blocks. YAML.safe_load would handle these cases and is equally safe given the existing rescue StandardError guard.

3. Minor template style inconsistencywebpack.config.js.tt and rspack.config.js.tt use an if/else pattern; the two new .ts.tt templates use early-return (no else). Worth aligning for consistency.

)

add_info("💡 To analyze bundle size:")
if bundle_analyzer_available?
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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:

Suggested change
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*$/)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Parsing YAML with a line-anchored regex is fragile. It will miss:

  • Values inherited via anchors/aliases (e.g., default: &default\n assets_bundler: rspack then production:\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:

Suggested change
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)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

.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.

@AbanoubGhadban AbanoubGhadban merged commit 1a4e032 into master Mar 16, 2026
32 checks passed
@AbanoubGhadban AbanoubGhadban deleted the fix/2553-ts-config-variants branch March 16, 2026 14:37
justin808 added a commit that referenced this pull request Mar 17, 2026
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]>
justin808 added a commit that referenced this pull request Mar 30, 2026
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]>
justin808 added a commit that referenced this pull request Apr 6, 2026
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]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug codex PRs created from codex-named branches P2 Backlog priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

standard_shakapacker_config? does not recognize TypeScript (.ts) config variants

3 participants