Skip to content

Commit 9af7271

Browse files
justin808claude
andauthored
Improve CSS Modules backward compatibility documentation (#809) (#810)
## 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 - Fixes #809 - Referenced implementation: shakacode/react_on_rails#1921 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## 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. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude <[email protected]>
1 parent 1c13a1a commit 9af7271

File tree

1 file changed

+68
-2
lines changed

1 file changed

+68
-2
lines changed

docs/v9_upgrade.md

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,74 @@ import * as styles from './Component.module.css';
155155
This allows you to keep using default imports while migrating gradually
156156
157157
3. **Keep v8 behavior** using webpack configuration (Advanced):
158-
- Override the css-loader configuration as shown in [CSS Modules Export Mode documentation](./css-modules-export-mode.md)
159-
- Provides more control over the configuration
158+
159+
If you need more control over the configuration, you can override the css-loader settings directly in your webpack config.
160+
161+
**Where to add this:** Create or modify `config/webpack/webpack.config.js`. If this file doesn't exist, create it and ensure your `config/webpacker.yml` or build process loads it. See [Webpack Configuration](./webpack.md) for details on customizing webpack.
162+
163+
```javascript
164+
// config/webpack/webpack.config.js
165+
const { generateWebpackConfig, merge } = require("shakapacker")
166+
167+
const customConfig = () => {
168+
const config = merge({}, generateWebpackConfig())
169+
170+
// Override CSS Modules to use default exports (v8 behavior)
171+
config.module.rules.forEach((rule) => {
172+
if (
173+
rule.test &&
174+
(rule.test.test("example.module.scss") ||
175+
rule.test.test("example.module.css"))
176+
) {
177+
if (Array.isArray(rule.use)) {
178+
rule.use.forEach((loader) => {
179+
if (
180+
loader.loader &&
181+
loader.loader.includes("css-loader") &&
182+
loader.options &&
183+
loader.options.modules
184+
) {
185+
// Disable named exports to support default imports
186+
loader.options.modules.namedExport = false
187+
loader.options.modules.exportLocalsConvention = "camelCase"
188+
}
189+
})
190+
}
191+
}
192+
})
193+
194+
return config
195+
}
196+
197+
module.exports = customConfig
198+
```
199+
200+
**Key points:**
201+
- Test both `.module.scss` and `.module.css` file extensions
202+
- Validate all loader properties exist before accessing them
203+
- Use `.includes('css-loader')` since the loader path may vary
204+
- Set both `namedExport: false` and `exportLocalsConvention: 'camelCase'` for full v8 compatibility
205+
206+
**Debugging tip:** To verify the override is applied correctly, you can inspect the webpack config:
207+
208+
```javascript
209+
// Add this temporarily to verify your changes
210+
if (process.env.DEBUG_WEBPACK_CONFIG) {
211+
const cssModuleRules = config.module.rules
212+
.filter((r) => r.test?.test?.("example.module.css"))
213+
.flatMap((r) => r.use?.filter((l) => l.loader?.includes("css-loader")))
214+
console.log(
215+
"CSS Module loader options:",
216+
JSON.stringify(cssModuleRules, null, 2)
217+
)
218+
}
219+
```
220+
221+
Then run: `DEBUG_WEBPACK_CONFIG=true bin/shakapacker`
222+
223+
**Note:** This is a temporary solution. The recommended approach is to migrate your imports to use named exports as shown in the main documentation.
224+
225+
For detailed configuration options, see the [CSS Modules Export Mode documentation](./css-modules-export-mode.md)
160226

161227
**Benefits of the change:**
162228

0 commit comments

Comments
 (0)