Skip to content

Improve CSS Modules backward compatibility documentation (#809)#810

Merged
justin808 merged 2 commits intomainfrom
justin808/css-modules-compat-docs
Nov 10, 2025
Merged

Improve CSS Modules backward compatibility documentation (#809)#810
justin808 merged 2 commits intomainfrom
justin808/css-modules-compat-docs

Conversation

@justin808
Copy link
Copy Markdown
Member

@justin808 justin808 commented Nov 6, 2025

Summary

Adds comprehensive backward compatibility documentation to the v9 upgrade guide, addressing issue #809. Users upgrading from Shakapacker 8.x to 9.x now have a complete working example showing how to restore the v8 CSS Modules behavior in large codebases.

Changes

  • Added "Restoring v8 Behavior (Backward Compatibility)" section to the CSS Modules breaking change documentation
  • Included complete working webpack config override example
  • Added detailed explanations of each configuration option
  • Provided debugging tips for inspecting webpack configuration
  • Documented clear migration path from temporary workaround to full v9 adoption
  • Referenced real-world example from React on Rails PR #1921

Key Improvements

  1. Complete working example - No longer just a reference to other docs, but a full copy-paste solution
  2. Detailed explanations - Each configuration option is explained with comments
  3. Debugging guidance - Shows how to inspect webpack config structure
  4. Migration clarity - Clear steps from v8 behavior to v9 named exports
  5. Real-world validation - Links to successful implementation in React on Rails

Problem Solved

The previous documentation mentioned overriding CSS Modules configuration but didn't provide a complete example. Users had to:

  • Figure out which webpack config file to modify
  • Understand how to iterate through webpack rules
  • Determine exact options needed for backward compatibility

This led to runtime failures (components not rendering) that were difficult to debug since webpack builds succeeded but CSS classes were undefined at runtime.

Test Plan

  • Documentation change only, no code changes required
  • Verified markdown formatting with yarn lint
  • Confirmed example matches working solution from React on Rails upgrade

Related

Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Updated v9 upgrade documentation with detailed webpack configuration options for CSS Modules. Includes practical code examples for configuring settings, implementation safety checks, migration guidance, and best practices to help users maintain compatibility with previous versions while successfully upgrading to v9.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Nov 6, 2025

Warning

Rate limit exceeded

@justin808 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 3 minutes and 52 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 2a7ee5e and 542515d.

📒 Files selected for processing (1)
  • docs/v9_upgrade.md (1 hunks)

Walkthrough

Updates docs/v9_upgrade.md with a concrete webpack override example for preserving CSS Modules v8 behavior (default exports) in v9. Includes programmatic css-loader option modifications with safety checks and guidance on this approach being temporary.

Changes

Cohort / File(s) Summary
CSS Modules v9 Upgrade Documentation
docs/v9_upgrade.md
Adds complete webpack-based override example for restoring CSS Modules default exports by programmatically setting namedExport: false and exportLocalsConvention: "camelCase" on css-loader, with safety checks and clarification that this is a temporary backward-compatibility solution

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

  • Documentation-only change with no code logic modifications
  • Single file with additional guidance and code example
  • No complex reasoning required; primarily content review

Possibly related issues

Possibly related PRs

Suggested reviewers

  • tomdracz

Poem

🐰 A hop, skip, and CSS Module leap,
Where defaults and exports no longer sleep,
With webpack config, a path to restore,
v8's cozy defaults, forevermore! ✨
Safe checks and clear guidance now light the way,
For bundlers and builders—what a great day! 📦

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding backward compatibility documentation for CSS Modules in the v9 upgrade guide.
Linked Issues check ✅ Passed The PR fully addresses all coding requirements from issue #809: provides a complete working webpack config example, explains where to add the override, shows exact loader options (namedExport: false, exportLocalsConvention: 'camelCase'), includes safety checks, and documents the temporary nature with migration guidance.
Out of Scope Changes check ✅ Passed All changes are directly within scope: the PR only modifies the v9_upgrade.md documentation file to add the backward compatibility section and example requested in issue #809, with no extraneous modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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.

justin808 added a commit that referenced this pull request Nov 6, 2025
Introduce a simple configuration option to control CSS Modules export mode,
making it much easier for users to restore v8 behavior without manually
overriding webpack configuration.

Changes:
- Add `css_modules_export_mode` option to shakapacker.yml
  - 'named' (default): Use named exports with camelCaseOnly (v9 behavior)
  - 'default': Use default exports with camelCase (v8 behavior)
- Implement logic in getStyleRule.ts to apply configuration
- Add TypeScript type definition for new config option
- Update CSS Modules documentation with new configuration approach
- Update v9 upgrade guide to highlight the simple config option

Benefits:
- Users can set one line in shakapacker.yml instead of writing custom webpack config
- Reduces migration friction for large codebases
- Provides clear, documented path for gradual migration
- Maintains backward compatibility while encouraging modern practices

Example usage:
```yaml
# config/shakapacker.yml
css_modules_export_mode: "default"  # Restore v8 behavior
```

This complements the documentation improvements in PR #810 by providing
a user-friendly configuration option that doesn't require webpack expertise.

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

Co-Authored-By: Claude <[email protected]>
justin808 added a commit that referenced this pull request Nov 7, 2025
Introduce a simple configuration option to control CSS Modules export mode,
making it much easier for users to restore v8 behavior without manually
overriding webpack configuration.

Changes:
- Add `css_modules_export_mode` option to shakapacker.yml
  - 'named' (default): Use named exports with camelCaseOnly (v9 behavior)
  - 'default': Use default exports with camelCase (v8 behavior)
- Implement logic in getStyleRule.ts to apply configuration
- Add TypeScript type definition for new config option
- Update CSS Modules documentation with new configuration approach
- Update v9 upgrade guide to highlight the simple config option

Benefits:
- Users can set one line in shakapacker.yml instead of writing custom webpack config
- Reduces migration friction for large codebases
- Provides clear, documented path for gradual migration
- Maintains backward compatibility while encouraging modern practices

Example usage:
```yaml
# config/shakapacker.yml
css_modules_export_mode: "default"  # Restore v8 behavior
```

This complements the documentation improvements in PR #810 by providing
a user-friendly configuration option that doesn't require webpack expertise.

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

Co-Authored-By: Claude <[email protected]>
justin808 added a commit that referenced this pull request Nov 7, 2025
Introduce a simple configuration option to control CSS Modules export mode,
making it much easier for users to restore v8 behavior without manually
overriding webpack configuration.

Changes:
- Add `css_modules_export_mode` option to shakapacker.yml
  - 'named' (default): Use named exports with camelCaseOnly (v9 behavior)
  - 'default': Use default exports with camelCase (v8 behavior)
- Implement logic in getStyleRule.ts to apply configuration
- Add TypeScript type definition for new config option
- Update CSS Modules documentation with new configuration approach
- Update v9 upgrade guide to highlight the simple config option

Benefits:
- Users can set one line in shakapacker.yml instead of writing custom webpack config
- Reduces migration friction for large codebases
- Provides clear, documented path for gradual migration
- Maintains backward compatibility while encouraging modern practices

Example usage:
```yaml
# config/shakapacker.yml
css_modules_export_mode: "default"  # Restore v8 behavior
```

This complements the documentation improvements in PR #810 by providing
a user-friendly configuration option that doesn't require webpack expertise.

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

Co-Authored-By: Claude <[email protected]>
justin808 added a commit that referenced this pull request Nov 8, 2025
## Summary

Introduces a simple, user-friendly configuration option to control CSS
Modules export mode, making it much easier to restore v8 behavior
without manual webpack configuration overrides.

## Problem Solved

Issue #809 identified that upgrading from Shakapacker v8 to v9 requires
complex webpack configuration overrides to maintain v8 CSS Modules
behavior. This creates a high barrier for teams with large codebases who
need to migrate gradually.

## Solution

Add a `css_modules_export_mode` configuration option to
`shakapacker.yml`:

```yaml
# config/shakapacker.yml
default: &default
  # CSS Modules export mode
  # 'named' (default) - Use named exports with camelCase conversion (v9 default)
  # 'default' - Use default export with both original and camelCase names (v8 behavior)
  css_modules_export_mode: "named"
```

## Changes

1. **Configuration Schema** (`lib/install/config/shakapacker.yml`)
   - Added `css_modules_export_mode` option with clear documentation
   - Defaults to `"named"` to maintain v9 behavior

2. **TypeScript Types** (`package/types.ts`)
- Added `css_modules_export_mode?: "named" | "default"` to Config
interface
   - Provides type safety and IDE autocomplete

3. **Implementation** (`package/utils/getStyleRule.ts`)
   - Reads configuration and applies appropriate CSS loader settings
- `"named"`: Sets `namedExport: true` and `exportLocalsConvention:
"camelCaseOnly"` (v9 default)
- `"default"`: Sets `namedExport: false` and `exportLocalsConvention:
"camelCase"` (v8 behavior)

4. **Documentation Updates**
- Updated `docs/css-modules-export-mode.md` with new configuration
approach
- Updated `docs/v9_upgrade.md` to highlight the simple config option
first
   - Reorganized migration options to emphasize the easiest approach

## Benefits

- **No webpack expertise required** - Users just change one line in YAML
- **Reduced migration friction** - Large codebases can upgrade
immediately
- **Clear migration path** - Simple to enable v8 mode, then gradually
migrate
- **Maintains best practices** - Defaults to v9 behavior, but provides
escape hatch
- **Better than PR #810** - While that PR improved documentation, this
provides a programmatic solution

## Example Usage

### Keeping v8 Behavior
```yaml
# config/shakapacker.yml
css_modules_export_mode: "default"
```

Then continue using v8-style imports:
```javascript
import styles from './Component.module.css';
<button className={styles.button} />
```

### Using v9 Behavior (Default)
```yaml
# config/shakapacker.yml
css_modules_export_mode: "named"  # or omit this line
```

Use v9-style imports:
```javascript
// JavaScript
import { button } from './Component.module.css';
<button className={button} />

// TypeScript
import * as styles from './Component.module.css';
<button className={styles.button} />
```

## Migration Strategy

1. **Immediate upgrade**: Set `css_modules_export_mode: "default"` to
maintain v8 behavior
2. **Gradual migration**: Update components incrementally to use named
exports
3. **Complete migration**: Remove the config option to use v9 default

## Test Plan

- [x] Linting passes (`yarn lint`)
- [x] RuboCop passes (`bundle exec rubocop`)
- [x] TypeScript type checking passes (`yarn run tsc --noEmit`)
- [x] Configuration is properly typed
- [x] Documentation is clear and comprehensive

## Related

- Addresses issue #809
- Complements PR #810 (documentation improvements)
- Supersedes manual webpack configuration approach

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

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added a configurable CSS Modules export mode allowing projects to use
either v8-style default imports or v9-style named exports.

* **Documentation**
* Expanded upgrade and CSS Modules guides with step-by-step
configuration examples and migration options (easy config-driven or
advanced manual approaches).

* **Tests**
* Updated test coverage to validate mode-dependent CSS Modules behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude <[email protected]>
Add complete working example to v9 upgrade guide showing how to restore
v8 CSS Modules behavior using webpack configuration. This addresses the
documentation gap where users needed to figure out the exact
configuration on their own.

The example includes:
- Complete working webpack config code
- Detailed explanation of each step
- Key points about file extensions and validation
- Clear note that this is a temporary solution

Fixes #809

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

Co-Authored-By: Claude <[email protected]>
@justin808 justin808 force-pushed the justin808/css-modules-compat-docs branch from a0edfc7 to 2a7ee5e Compare November 9, 2025 21:40
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
docs/v9_upgrade.md (1)

157-206: Excellent documentation of webpack override with defensive programming approach.

The webpack configuration override example is well-structured with appropriate safety checks (property existence, Array validation, loader identification). The code handles the common rule structure effectively and documents key points clearly.

One minor suggestion: Consider adding a brief note about testing the override (e.g., bin/shakapacker or yarn build to verify the config applies correctly and doesn't break the build). This would help developers validate their implementation.

Optional enhancement – Add verification guidance:

// At the end of commonWebpackConfig function, optionally add:
if (process.env.DEBUG_WEBPACK_CONFIG) {
  console.log("CSS Module loader options:", config.module.rules
    .filter(r => r.test?.test?.("example.module.css"))
    .flatMap(r => r.use?.filter(l => l.loader?.includes("css-loader")))
  )
}

This allows developers to run DEBUG_WEBPACK_CONFIG=true yarn build to verify the override took effect.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1c13a1a and 2a7ee5e.

📒 Files selected for processing (1)
  • docs/v9_upgrade.md (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: claude-review
🔇 Additional comments (1)
docs/v9_upgrade.md (1)

198-206: Clear and appropriately-scoped documentation of override mechanics.

The key points section effectively reinforces the important safeguards and sets proper expectations (temporary solution with migration guidance). The progression from simple YAML configuration → advanced webpack override → full migration aligns well with typical user needs and decision-making flow.

@justin808
Copy link
Copy Markdown
Member Author

@claude review this PR.

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Nov 9, 2025

Claude Code is working…

I'll analyze this and get back to you.

View job run

@justin808
Copy link
Copy Markdown
Member Author

@claude review this PR

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Nov 9, 2025

Claude finished @justin808's task —— View job


PR Review Complete

Tasks

  • Read the changed documentation file
  • Review the git diff to see exact changes
  • Analyze documentation quality and technical accuracy
  • Provide comprehensive review feedback

Review Feedback

This is an excellent documentation improvement that addresses issue #809 comprehensively. The additions provide exactly what users need to restore v8 CSS Modules behavior during migration.

Strengths

1. Complete, Copy-Paste Solution
The webpack override example (lines 161-196) is production-ready with:

  • Correct use of generateWebpackConfig and merge from shakapacker
  • Proper iteration through config.module.rules
  • Defensive programming with property existence checks
  • Correct identification of CSS/SCSS module files
  • Proper targeting of css-loader in the loader chain

2. Clear Technical Accuracy
The code correctly:

  • Tests both .module.scss and .module.css extensions
  • Uses .includes('css-loader') to handle varying loader paths
  • Sets both required options: namedExport: false and exportLocalsConvention: 'camelCase'
  • Validates the rule structure before accessing nested properties

3. Well-Structured Guidance
The documentation provides:

  • Context about when to use this approach (line 159)
  • Detailed inline code comments explaining each step
  • "Key points" summary highlighting important implementation details (lines 198-202)
  • Clear migration path with the note about this being temporary (line 204)
  • Reference to more detailed documentation

4. Proper Integration
The addition fits naturally into the existing document structure:

Minor Suggestions

1. Consider Adding Debugging Tip
While the code is solid, you might consider adding a brief debugging tip to help users verify the override works. For example:

// Optional: Verify the override is applied during build
if (process.env.DEBUG_WEBPACK_CONFIG) {
  console.log("CSS Module loader options:", JSON.stringify(
    config.module.rules
      .filter(r => r.test?.test?.("example.module.css"))
      .flatMap(r => r.use?.filter(l => l.loader?.includes("css-loader"))),
    null, 2
  ))
}

This would allow users to run DEBUG_WEBPACK_CONFIG=true bin/shakapacker to inspect the configuration.

2. File Path Clarity
The comment says "config/webpack/commonWebpackConfig.js (or similar)" - you might briefly mention where this file should be created if it doesn't exist, or point to shakapacker's webpack config documentation.

Technical Validation

I verified the code against:

  • ✅ Shakapacker's generateWebpackConfig API
  • ✅ webpack's rule structure for module rules
  • ✅ css-loader's options schema
  • ✅ The defensive checks match webpack's actual rule structure

The example should work correctly for users upgrading from v8 to v9.

CodeRabbit Feedback Addressed

CodeRabbit's review suggested adding verification guidance (similar to my suggestion #1 above), which is a valid enhancement but not blocking for merge. The current PR fully addresses issue #809's requirements.

Recommendation

Approve and merge. This is a high-quality documentation improvement that will significantly help users with large codebases migrate to v9. The suggestions above are optional enhancements that could be added in a follow-up PR if desired.

The documentation is:

  • Technically accurate
  • Complete and actionable
  • Well-explained with appropriate warnings
  • Properly integrated into the existing guide

Great work addressing issue #809!


Enhanced the webpack configuration override example with:
- Clear instructions on where to create the config file
- Reference to webpack configuration documentation
- Debugging snippet to verify the override works
- Example command to run with debug output

This makes it easier for users to verify their configuration is
correct and troubleshoot any issues.

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

Co-Authored-By: Claude <[email protected]>
@justin808 justin808 merged commit 9af7271 into main Nov 10, 2025
2 checks passed
@justin808 justin808 deleted the justin808/css-modules-compat-docs branch November 10, 2025 02:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve CSS Modules backward compatibility documentation in v9 upgrade guide

1 participant