Add css_modules_export_mode configuration option#817
Conversation
|
Warning Rate limit exceeded@justin808 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 5 minutes and 40 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (8)
WalkthroughAdds a new configuration option Changes
Sequence Diagram(s)sequenceDiagram
participant Dev as Developer
participant Config as shakapacker.yml
participant App as Shakapacker Runtime
participant Loader as css-loader
Dev->>Config: set css_modules_export_mode: "default" or "named"
Dev->>App: start/restart dev server
App->>App: read config.css_modules_export_mode
alt mode == "named"
App->>Loader: set namedExport: true\nexportLocalsConvention: camelCaseOnly
else mode == "default"
App->>Loader: set namedExport: false\nexportLocalsConvention: camelCase
end
Loader-->>App: compiled CSS modules with chosen export mode
App-->>Dev: assets built with selected export behavior
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
docs/css-modules-export-mode.md (2)
153-233: ClarifyexportLocalsConventioninconsistency between options.Option 1 (configuration file, lines 172-173) states it uses
exportLocalsConvention: 'camelCase'to export both original and camelCase versions. However, Option 2 (manual webpack config, line 214) showsexportLocalsConvention: "asIs", which only exports the original names.This discrepancy could confuse users who expect Options 1 and 2 to produce equivalent v8 behavior. Consider either:
- Aligning the manual configuration examples to use
'camelCase'to match Option 1- Adding a note explaining that Option 2 provides more flexibility and why
"asIs"might be preferred in some casesApply this documentation clarification:
# Override CSS Modules configuration to use v8-style default exports const overrideCssModulesConfig = (config) => { // Find the CSS rule in the module rules const cssRule = config.module.rules.find( (rule) => rule.test && rule.test.toString().includes("css") ) if (cssRule && cssRule.use) { const cssLoaderUse = cssRule.use.find( (use) => use.loader && use.loader.includes("css-loader") ) if (cssLoaderUse && cssLoaderUse.options && cssLoaderUse.options.modules) { // Override v9 default to use v8-style default exports cssLoaderUse.options.modules.namedExport = false - cssLoaderUse.options.modules.exportLocalsConvention = "asIs" + // Use 'camelCase' to match Option 1 behavior (exports both original and camelCase) + // Or use 'asIs' to keep only original class names + cssLoaderUse.options.modules.exportLocalsConvention = "camelCase" } }
235-274: SameexportLocalsConventioninconsistency in Option 3.Similar to Option 2, this environment.js example (line 251) uses
exportLocalsConvention: "asIs"instead of"camelCase", which differs from the configuration file approach in Option 1.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
docs/css-modules-export-mode.md(3 hunks)docs/v9_upgrade.md(1 hunks)lib/install/config/shakapacker.yml(1 hunks)package/types.ts(1 hunks)package/utils/getStyleRule.ts(2 hunks)
🔇 Additional comments (5)
package/types.ts (1)
18-18: LGTM! Type definition is well-designed.The optional union type correctly models the configuration option while maintaining type safety. When undefined, the implementation defaults to "named" (v9 behavior), ensuring backward compatibility.
package/utils/getStyleRule.ts (2)
32-35: LGTM! Logic correctly handles all configuration states.The conditional correctly defaults to named exports (v9 behavior) when
css_modules_export_modeis undefined, while explicitly checking for "default" to enable v8 compatibility.
46-52: LGTM! CSS loader options correctly implement the configuration.The conditional assignment properly switches between:
- v9 (named exports):
namedExport: truewithcamelCaseOnly- v8 (default export):
namedExport: falsewithcamelCaseThis aligns with css-loader's requirements where
namedExport: truemust usecamelCaseOnlyordashesOnly.lib/install/config/shakapacker.yml (1)
22-31: Excellent documentation and sensible default.The configuration is well-documented with clear examples for both modes and a helpful reference link. Setting "named" as the default aligns with the v9 upgrade strategy.
docs/v9_upgrade.md (1)
148-159: LGTM! Clear migration guidance.The new configuration-based approach is well-positioned as the easiest option for maintaining v8 behavior during gradual migration. The YAML example is correct and matches the implementation.
Code Review - PR #817I've reviewed this pull request and overall it's a well-designed solution that effectively addresses issue #809. Here's my detailed feedback: ✅ Strengths1. Excellent User Experience Design
2. Clean Implementation
3. Strong Documentation
🔍 Issues & Suggestions1. Missing Test Coverage (High Priority) The PR description mentions linting and type checking pass, but there are no automated tests for this new configuration option. According to CLAUDE.md guidelines, you should add RSpec tests when changing source files. Recommendation: Add tests covering:
Suggested test file: 2. Missing CHANGELOG Entry (Required) According to CLAUDE.md, this is a user-visible feature that requires a CHANGELOG entry. The format should be: ### Added
- **CSS Modules export mode configuration option**. [PR #817](https://github.com/shakacode/shakapacker/pull/817) by [justin808](https://github.com/justin808). Added `css_modules_export_mode` configuration option in `shakapacker.yml` to easily switch between v9's named exports and v8's default exports. Set to `"default"` to maintain v8 behavior during gradual migration.3. Documentation Inconsistency (Low Priority) In
This creates confusion about whether the manual approaches truly replicate v8 behavior. Consider either:
4. Type Safety Enhancement (Nice to Have) While the current type definition works well, you could add runtime validation to catch typos early: // In getStyleRule.ts, add validation
const validModes = ['named', 'default'] as const
if (config.css_modules_export_mode && !validModes.includes(config.css_modules_export_mode)) {
console.warn(
`Invalid css_modules_export_mode: "${config.css_modules_export_mode}". ` +
`Expected "named" or "default". Defaulting to "named".`
)
}
const useNamedExports = config.css_modules_export_mode !== "default"🔒 Security & Performance
📝 Code Quality
✅ Pre-merge ChecklistBefore merging, please:
🎯 Overall AssessmentThis is a high-quality PR that solves a real pain point with an elegant solution. The code implementation is solid, but it needs test coverage and a CHANGELOG entry before merging. Once those are addressed, this will be a valuable addition to Shakapacker. Recommendation: Request changes for tests and CHANGELOG, then approve. |
Code Review for PR #817: Add css_modules_export_mode configuration optionOverviewThis is a well-designed and thoughtful PR that addresses a real pain point (#809) for teams upgrading from v8 to v9. The solution is elegant, user-friendly, and maintains backward compatibility while preserving best practices. ✅ Strengths1. Excellent User Experience
2. Code Quality
3. Documentation
4. Security & Best Practices
🔍 Issues & RecommendationsCRITICAL: Missing Trailing NewlinesPer Need to verify all modified files end with a newline:
Run CRITICAL: Missing CHANGELOG EntryThis is a user-visible feature addition and should have a CHANGELOG entry. Based on the project's format: ### Added
- **CSS Modules export mode configuration option**. [PR #817](https://github.com/shakacode/shakapacker/pull/817) by [justin808](https://github.com/justin808). Adds `css_modules_export_mode` configuration option to `shakapacker.yml` to easily switch between v9 named exports (default) and v8 default export behavior. Simplifies migration for large codebases by eliminating the need for manual webpack configuration overrides. Set to `"default"` to maintain v8 behavior during gradual migration.Test Coverage ConcernWhile the PR description mentions linting passes, there are no new automated tests for this feature:
Recommendation: Add integration tests to verify: describe "css_modules_export_mode configuration" do
context "when set to 'default'" do
it "configures css-loader with namedExport: false and exportLocalsConvention: camelCase"
end
context "when set to 'named' or omitted" do
it "configures css-loader with namedExport: true and exportLocalsConvention: camelCaseOnly"
end
endEven if these require Node.js integration, consider at least testing the configuration parsing. Minor: Type Safety EnhancementThe // Current
css_modules_export_mode?: "named" | "default"
// Consider adding a note or default
css_modules_export_mode?: "named" | "default" // defaults to "named"Or validate at runtime that the value is one of the two allowed strings. Minor: Documentation ClarityIn css_modules_export_mode: "named"This makes it look like users should keep this line. Consider clarifying: # css_modules_export_mode: "named" # This is the default; uncomment to changeOr simply omit the line to demonstrate it's optional. 🎯 Performance Considerations
🔐 Security Considerations
📋 Testing RecommendationsBefore merging:
Manual testing to verify:
🎉 Overall AssessmentRating: 8.5/10 This is a high-quality PR that solves a real problem elegantly. The implementation is clean, well-documented, and follows good practices. The main gaps are:
Once the CHANGELOG is added and trailing newlines verified, this is ready to merge. Adding tests would make it excellent, but given the thorough manual testing mentioned in the PR description, it's acceptable to merge without them if the maintainers are comfortable. Recommendation: Approve with minor changes required (CHANGELOG + linting checks) Great work on making Shakapacker more migration-friendly! 🚀 |
PR Review: Add css_modules_export_mode configuration optionSummaryThis PR provides an excellent, user-friendly solution to issue #809 by adding a simple YAML configuration option to control CSS Modules export mode. The implementation is clean, well-documented, and maintains backward compatibility while defaulting to v9 behavior. Code Quality & Best Practices ✅Strengths:
Minor observations:
Potential Issues & Concerns
|
Pull Request Review: Add css_modules_export_mode configuration optionOverall AssessmentThis is a well-designed, high-quality PR that solves a real migration pain point with a clean, user-friendly solution. The implementation is solid, documentation is comprehensive, and the approach is superior to manual webpack configuration overrides. Strengths1. Excellent Problem-Solution Fit
2. Clean Implementation
3. Comprehensive Documentation
4. Test Coverage
Code Quality Issues & SuggestionsCritical: Missing Trailing Newline
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
spec/shakapacker/css_modules_spec.rb (1)
179-199: Consider more flexible string matching for implementation verification.The exact string matching (e.g.,
"namedExport: useNamedExports") is fragile to formatting changes like whitespace variations, trailing commas, or code style adjustments. While this approach provides lightweight verification when integration tests are skipped, consider using regex patterns or more flexible matching to reduce test brittleness.For example, you could use patterns like:
- expect(style_rule_content).to include("namedExport: useNamedExports") + expect(style_rule_content).to match(/namedExport:\s*useNamedExports/)This would tolerate minor formatting variations while still verifying the core logic is present.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
spec/shakapacker/css_modules_spec.rb(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). (9)
- GitHub Check: Generator specs (ubuntu-latest, 3.3, gemfiles/Gemfile-rails.7.0.x)
- GitHub Check: Generator specs (ubuntu-latest, 3.1, gemfiles/Gemfile-rails.7.2.x)
- GitHub Check: Generator specs (ubuntu-latest, 3.0, gemfiles/Gemfile-rails.7.1.x)
- GitHub Check: Generator specs (ubuntu-latest, 3.0, gemfiles/Gemfile-rails.7.0.x)
- GitHub Check: Testing (ubuntu-latest, 3.1, gemfiles/Gemfile-rails.7.0.x)
- GitHub Check: Testing (ubuntu-latest, 2.7, gemfiles/Gemfile-rails.6.0.x)
- GitHub Check: test
- GitHub Check: Linting
- GitHub Check: claude-review
Code ReviewI've reviewed PR #817 and overall this is a well-designed and thoughtfully implemented feature. The solution elegantly addresses issue #809 by providing a simple configuration option to control CSS Modules export mode. Here's my detailed feedback: ✅ Strengths1. Excellent Design & User Experience
2. Comprehensive Documentation
3. Strong Validation & Error Handling
4. Type Safety
5. Test Coverage
🔍 Observations & Minor Suggestions1. Optional TypeScript FieldIn css_modules_export_mode?: "named" | "default"The field is optional ( Impact: Low - current implementation is safe, just a potential type refinement 2. Code Comment ClarityIn // Use named exports for v9 (default), or default exports for v8 compatibility
namedExport: useNamedExports,The comment is clear, but the boolean logic could be more explicit for future maintainers: // true = named exports (v9 default), false = default export (v8 behavior)
namedExport: useNamedExports,Impact: Very low - style preference 3. Test IsolationThe tests in Current approach is fine, just noting that integration-style tests with real config files could complement the unit tests. 4. Documentation Cross-ReferencesThe documentation updates are excellent. One minor suggestion: in 🎯 Code Quality Assessment
🔒 Security Review
⚡ Performance Considerations
🧪 Test CoverageThe test suite covers:
Suggestion: Consider adding an integration test that actually compiles CSS modules with both modes and verifies the output format (though this may already exist elsewhere in the test suite). 📋 Checklist ReviewBased on the PR description:
Note: The PR description mentions these pass, but I recommend running them again before merge to ensure no regressions. 🎬 RecommendationAPPROVE - This PR is ready to merge after addressing any final linting/test requirements. The implementation is solid, well-tested, and provides significant value to users upgrading from v8. The code quality is excellent and follows Shakapacker conventions. The documentation updates make this feature discoverable and easy to use. Great work! This will make v8→v9 migrations much smoother for teams. 🚀 📝 Pre-Merge ChecklistBefore merging, please ensure:
Review generated by Claude Code |
Code Review - PR #817: Add css_modules_export_mode configuration optionOverall, this is a well-implemented PR that addresses a real pain point for teams migrating from v8 to v9. The solution is elegant, user-friendly, and maintains backward compatibility. ✅ Strengths1. Excellent Problem-Solution Fit
2. Code Quality
3. Documentation
4. Test Coverage
|
Code Review for PR #817I've conducted a comprehensive review of this pull request. Overall, this is a well-designed and well-implemented feature that addresses a real pain point for teams upgrading from v8 to v9. Here's my detailed feedback: ✅ Strengths1. Excellent Problem-Solution Fit
2. High Code Quality
3. Comprehensive Documentation
4. Strong Test Coverage
🔍 Observations & SuggestionsMinor Issues1. Ruby Method Naming Convention (configuration.rb:350-363)The method 2. Default Value Handling (configuration.rb:351)mode = fetch(:css_modules_export_mode) || "named"This works fine, but it means if someone explicitly sets it to 3. TypeScript Optional Field (package/types.ts:18)css_modules_export_mode?: "named" | "default"The field is optional in TypeScript, which is good. The Ruby code handles the default correctly, so this is consistent. ✅ Good design. Potential Enhancements (Not Required)1. Integration TestThe current tests use mocking (
However, the existing tests may be sufficient given the simple nature of this feature. 2. Runtime ValidationCurrently, validation happens when 3. CHANGELOG EntryBased on the project's CLAUDE.md guidelines, this PR should have a CHANGELOG entry since it's a user-visible feature. The entry should follow the format: ### Added
- **CSS Modules export mode configuration option**. [PR #817](https://github.com/shakacode/shakapacker/pull/817) by [justin808](https://github.com/justin808).
- Added `css_modules_export_mode` configuration option to easily switch between v9 named exports and v8 default exports
- Set `css_modules_export_mode: default` in `config/shakapacker.yml` to maintain v8 behavior
- Reduces migration friction for teams upgrading from v8 to v9🔒 Security & Performance
🐛 Potential BugsI didn't identify any bugs in the implementation. The logic is straightforward and well-tested. 📋 Code Style & Best Practices
🎯 RecommendationsMust Have (Before Merge)
Nice to Have (Optional)
📝 Final VerdictThis is a high-quality pull request that:
The only required change before merge is adding a CHANGELOG entry. Everything else is optional polish. Recommendation: Approve with minor changes (add CHANGELOG entry) 🤖 Generated with Claude Code |
14aea63 to
3496905
Compare
|
@claude review this PR |
|
Claude finished @justin808's task —— View job Code Review for PR #817I've completed a comprehensive review of this PR. Overall, this is excellent work that solves a real migration pain point with an elegant, user-friendly solution. SummaryThis PR introduces a Strengths1. Excellent Problem-Solution Fit ✅
2. High Code Quality ✅
3. Comprehensive Test Coverage ✅
4. Excellent Documentation ✅
5. Strong Validation & Error Handling ✅
Code Review DetailsRuby Implementation (lib/shakapacker/configuration.rb:342-363)Excellent:
Note: The validation only runs when the method is called, not at config load time. This is consistent with other config methods in the codebase, so this is acceptable. TypeScript Implementation (package/utils/getStyleRule.ts:32-52)Excellent:
Note: The TypeScript type definition uses optional field ( Test Coverage (spec/shakapacker/css_modules_spec.rb)Excellent:
Minor observation: The string matching tests (lines 179-199) are somewhat fragile to formatting changes, but they provide valuable verification that the implementation has the conditional logic. This is acceptable given the integration tests are skipped. Documentation (Multiple files)Excellent:
Potential Improvements (Optional)1. Consider Adding Runtime Warning for Invalid ValuesWhile the Ruby validation will catch invalid values, the TypeScript side could also validate and warn if an invalid value is encountered: const validModes = ['named', 'default'] as const
const mode = config.css_modules_export_mode
if (mode && !validModes.includes(mode as any)) {
console.warn(
`Invalid css_modules_export_mode: "${mode}". ` +
`Expected "named" or "default". Defaulting to "named".`
)
}
const useNamedExports = mode !== "default"Impact: Low priority - Ruby validation is sufficient, but this would provide defense-in-depth. 2. Consider More Flexible Test AssertionsThe string matching in spec/shakapacker/css_modules_spec.rb:179-199 could use regex for more flexible matching: expect(style_rule_content).to match(/namedExport:\s*useNamedExports/)Impact: Very low priority - current approach works fine. Security & Performance
Adherence to Project Guidelines (CLAUDE.md)
Final AssessmentRating: 9.5/10 - This is exemplary work. What Makes This PR Excellent:
Why Not 10/10:The only minor improvements would be:
These are truly minor polish items - the PR is production-ready as-is. RecommendationAPPROVE - This PR is ready to merge. This is high-quality work that significantly improves the v8→v9 migration experience. The implementation is solid, well-tested, and thoroughly documented. Great job! 🎉 |
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]>
Update the spec test to check for conditional logic based on css_modules_export_mode instead of hardcoded values. The test now validates that: - Conditional logic exists for css_modules_export_mode - namedExport and exportLocalsConvention are set conditionally - Both 'camelCaseOnly' and 'camelCase' options are present in code - Comments explain v9 and v8 behavior This fixes the CI failure in Testing (ubuntu-latest, 2.7, gemfiles/Gemfile-rails.6.1.x) Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Improvements based on code review feedback: 1. Configuration Validation: - Added css_modules_export_mode() method in Configuration class - Validates that value is either 'named' or 'default' - Raises ArgumentError with helpful message for invalid values - Includes documentation link in error messages - Defaults to 'named' when not specified 2. Comprehensive Test Coverage: - Added 5 integration tests for configuration validation - Tests default behavior (named mode) - Tests valid 'default' mode - Tests error handling for invalid values - Verifies helpful error messages with valid options list - Confirms documentation link is included in errors 3. Code Quality: - All files verified to have trailing newlines - RuboCop passes with no offenses - Tests use existing config fixture (no redundant setup) This provides robust validation to catch configuration errors early with clear, actionable error messages pointing users to documentation. Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Addressed code review comments about YAML quote usage: Changes: - Removed quotes from css_modules_export_mode values (named/default) - Updated shakapacker.yml config file - Updated documentation examples in css-modules-export-mode.md - Updated v9_upgrade.md examples - Removed quotes from comments describing the values Rationale: - YAML doesn't require quotes for simple string values like 'named' and 'default' - These are not YAML keywords (unlike true, false, null) - Matches existing style in shakapacker.yml for values like: - public_root_path: public - compiler_strategy: digest - etc. - More readable and consistent with the rest of the config The values still parse correctly as strings in Ruby (verified with tests). Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
3496905 to
debc95b
Compare
Code ReviewThis PR provides an elegant solution to the CSS Modules migration challenge between v8 and v9. Overall, the implementation is well-designed and follows good practices. Here's my detailed feedback: ✅ Strengths
🔍 Issues & Recommendations1. CHANGELOG Entry Needs PR Number- [PR #TBD](https://github.com/shakacode/shakapacker/pull/TBD)
+ [PR #817](https://github.com/shakacode/shakapacker/pull/817)Location: 2. Validation Performance ConsiderationThe def css_modules_export_mode
@css_modules_export_mode ||= begin
mode = fetch(:css_modules_export_mode) || "named"
valid_modes = ["named", "default"]
unless valid_modes.include?(mode)
raise ArgumentError,
"Invalid css_modules_export_mode: '#{mode}'. " \
"Valid values are: #{valid_modes.map { |m| "'#{m}" }.join(', ')}. " \
"See https://github.com/shakacode/shakapacker/blob/main/docs/css-modules-export-mode.md"
end
mode
end
end3. Test Coverage GapThe tests validate the Ruby configuration method, but there's no integration test verifying that the TypeScript code actually reads and applies the configuration correctly. Consider adding a test that:
4. Documentation ClarityIn css_modules_export_mode: namedThis could confuse users who think they need to explicitly set it. Consider adding a note: # Defaults to 'named' if not specified. Uncomment and change to 'default' for v8 behavior.
# css_modules_export_mode: namedOr remove the line entirely since it's the default. 🔒 SecurityNo security concerns identified. The validation properly rejects invalid values. ⚡ PerformanceThe configuration is read at build time, so performance impact is negligible. The validation overhead mentioned in issue #2 is minor but worth addressing for cleanliness. 🧪 Testing Recommendations
📝 Minor Nitpicks
const useNamedExports = config.css_modules_export_mode === "named" ||
config.css_modules_export_mode === undefinedThough the current approach is fine given the default handling in Ruby. SummaryThis is a well-crafted PR that solves a real migration pain point. The main action items are:
Great work! This will make v8→v9 migrations much smoother for teams with large codebases. Review generated with Claude Code |
- Update PR number from TBD to #817 in CHANGELOG.md - Add memoization to css_modules_export_mode method for performance - Improve shakapacker.yml comment to clarify default behavior - Comment out default value to avoid confusion about explicit setting
Code Review: CSS Modules Export Mode ConfigurationI've completed a comprehensive review of PR #817. Overall, this is a well-implemented, well-tested, and well-documented feature that solves a real migration pain point. Here's my detailed feedback: ✅ Strengths1. Excellent Problem-Solution Fit
2. Robust Implementation
3. Comprehensive Test Coverage
4. Outstanding Documentation
🔍 Code Quality ObservationsType Safety
Configuration Flow
Error Handling
🎯 Best Practices AdherenceBased on CLAUDE.md project guidelines:
💡 Minor Suggestions (Optional)1. Consider Integration TestWhile unit tests are comprehensive, consider adding an integration test that:
Example location: 2. TypeScript Runtime ValidationThe TypeScript code trusts the Ruby-provided config. Consider adding a runtime check for defense-in-depth if config validation is bypassed somehow. 3. Documentation: Restart RequirementThe docs mention "Restart your development server" once. Consider adding this to:
🔒 Security Considerations
⚡ Performance Considerations
🐛 Potential IssuesNone identified. The implementation is solid. Minor note: The test at spec/shakapacker/css_modules_spec.rb:182 reads the TypeScript source file directly to verify implementation. While clever, this is somewhat brittle if the file is reformatted. Consider whether testing behavior rather than implementation details would be more maintainable. However, given the test comments explain this is intentional validation of the actual webpack config, it's acceptable. 📊 Test Coverage AssessmentExcellent coverage:
🎓 Migration Path ValidationThe PR provides three clear migration options in increasing complexity:
This graduated approach is excellent UX design. ✅ 📝 SummaryThis is production-ready code that:
Recommendation: APPROVE ✅The minor suggestions above are truly optional enhancements. The PR can be merged as-is with confidence. Great work on this feature! The attention to documentation and user experience really shows. This will significantly reduce the friction for teams upgrading from v8 to v9. 🤖 Review generated with Claude Code |
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_modeconfiguration option toshakapacker.yml:Changes
Configuration Schema (
lib/install/config/shakapacker.yml)css_modules_export_modeoption with clear documentation"named"to maintain v9 behaviorTypeScript Types (
package/types.ts)css_modules_export_mode?: "named" | "default"to Config interfaceImplementation (
package/utils/getStyleRule.ts)"named": SetsnamedExport: trueandexportLocalsConvention: "camelCaseOnly"(v9 default)"default": SetsnamedExport: falseandexportLocalsConvention: "camelCase"(v8 behavior)Documentation Updates
docs/css-modules-export-mode.mdwith new configuration approachdocs/v9_upgrade.mdto highlight the simple config option firstBenefits
Example Usage
Keeping v8 Behavior
Then continue using v8-style imports:
Using v9 Behavior (Default)
Use v9-style imports:
Migration Strategy
css_modules_export_mode: "default"to maintain v8 behaviorTest Plan
yarn lint)bundle exec rubocop)yarn run tsc --noEmit)Related
Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation
Tests