Skip to content

Conversation

justin808
Copy link
Member

@justin808 justin808 commented Oct 3, 2025

Summary

Updates Shakapacker from 9.0.0-beta.7 to 9.0.0-beta.8.

Changes

  • Updated Shakapacker version in Gemfile and package.json
  • Fixed commonWebpackConfig.js to properly detect SCSS rules with the new webpack config structure in beta.8
  • Added null safety checks for SCSS rule properties

Technical Details

In beta.8, the webpack rules structure changed to include a new oneOf pattern at index 0 that matches .scss but doesn't have a use array. The fix ensures we find the SCSS rule that actually has loaders configured.

Test Plan

  • Build passes (yarn build:test)
  • RuboCop linter passes
  • No extraneous changes

🤖 Generated with Claude Code


This change is Reviewable

Summary by CodeRabbit

  • Bug Fixes

    • Added a safety guard to SCSS processing so builds no longer fail when certain SCSS configurations are absent; reduces build errors and logs a warning in those cases.
  • Chores

    • Upgraded shakapacker to 9.0.0-beta.8 for improved compatibility and stability.

Copy link

coderabbitai bot commented Oct 3, 2025

Walkthrough

Shakapacker upgraded from 9.0.0.beta.7 → 9.0.0.beta.8 in Gemfile and package.json. Webpack SCSS rule handling in config/webpack/commonWebpackConfig.js gained a guard: modifications to loaders occur only when a SCSS rule with a use array is found.

Changes

Cohort / File(s) Summary
Dependency version bump
Gemfile, package.json
Updated shakapacker from 9.0.0.beta.7 / 9.0.0-beta.7 to 9.0.0.beta.8 / 9.0.0-beta.8.
Webpack SCSS loader safety
config/webpack/commonWebpackConfig.js
Added an early guard when no SCSS rule with a use array exists; wrapped Sass/CSS loader lookup and injection in a conditional branch so loader modifications run only if a valid SCSS use array is present (preserves existing loader lookup logic).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Dev as Developer / Process
  participant WP as commonWebpackConfig.js
  participant Rules as Rules Array
  participant Inject as Loader Injection

  Dev->>WP: require/load config
  WP->>Rules: find rule where test matches /\.scss/
  alt SCSS rule with use[] found
    Rules-->>WP: return scssRule with use[]
    WP->>Rules: locate sass-loader & css-loader indices (optional chaining)
    alt loader indices valid
      WP->>Inject: push/insert sassLoaderConfig into scssRule.use
      Inject-->>WP: updated rule
    else missing loaders
      WP-->>Dev: skip injection (guarded)
    end
  else no SCSS rule or no use[]
    WP-->>Dev: no-op / warning (guarded)
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested reviewers

  • ahangarha

Poem

A rabbit taps the pack with glee,
Upgraded hops from seven to three—er—eight, you see.
It peeks for scss before it roams,
Guards the loaders, checks the domes.
Quiet hops, no broken thread—builds a path of carrot-red. 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit's high-level summary is enabled.
Title Check ✅ Passed The title succinctly captures the primary intent of the PR—upgrading and adapting to Shakapacker 9.0.0-beta.8—by naming the exact version change, matching the dependency bumps and associated config updates described in the changeset.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch justin808/shakapacker-9-beta8

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.

Copy link

github-actions bot commented Oct 3, 2025

🚀 Quick Review App Commands

Welcome! Here are the commands you can use in this PR:

/deploy-review-app

Deploy your PR branch for testing

/delete-review-app

Remove the review app when done

/help

Show detailed instructions, environment setup, and configuration options.


Copy link

claude bot commented Oct 3, 2025

PR Review: Migrate to Shakapacker 9.0.0-beta.8

Summary

This PR updates Shakapacker from beta.7 to beta.8 and fixes webpack configuration to handle the new SCSS rule structure. Overall, this is a well-executed dependency update with appropriate defensive coding.

Code Quality ✅

Strengths:

  • Excellent use of optional chaining (?.) for null safety
  • Clear, focused changes that directly address the breaking change in beta.8
  • Good defensive programming with multiple null checks

Suggestions:

  1. Potential edge case in scssConfigIndex (config/webpack/commonWebpackConfig.js:26-28):

    const scssConfigIndex = baseClientWebpackConfig.module.rules.findIndex((config) =>
      '.scss'.match(config.test) && config.use,
    );

    If no matching rule is found, findIndex returns -1, which could cause issues later. Consider adding validation:

    if (scssConfigIndex === -1) {
      console.warn('No SCSS rule found in webpack config');
      // Early return or handle gracefully
    }
  2. Redundant check at line 39 (config/webpack/commonWebpackConfig.js:39):

    if (sassLoaderIndex !== -1 && sassLoaderIndex !== undefined) {

    The !== undefined check is redundant because findIndex() always returns a number (either valid index or -1), never undefined. Simplify to:

    if (sassLoaderIndex !== -1) {

Potential Bugs 🔍

Minor Issue:

  • Line 66-67: If scssConfigIndex is -1 (no SCSS rule found), this will access an invalid array index:
    if (scssRule?.use) {
      baseClientWebpackConfig.module.rules[scssConfigIndex].use.push(sassLoaderConfig);
    }
    Should check scssConfigIndex !== -1 as well:
    if (scssConfigIndex !== -1 && scssRule?.use) {
      baseClientWebpackConfig.module.rules[scssConfigIndex].use.push(sassLoaderConfig);
    }

Performance Considerations ⚡

No performance concerns. The changes are configuration-time operations that run once during webpack setup.

Security Concerns 🔒

No security issues identified. This is a dependency update with configuration adjustments.

Test Coverage 📋

Observations:

  • ✅ Manual testing confirmed (build passes per PR description)
  • ⚠️ No automated tests for commonWebpackConfig.js

Recommendation:
Consider adding basic tests to verify:

  • SCSS rule is found correctly
  • Sass loader configuration is applied
  • Graceful handling when SCSS rules are missing

Additional Comments

  1. Documentation: The PR description is excellent - it clearly explains the breaking change and the fix.

  2. Dependency Update Best Practice: Good practice pinning beta versions and testing thoroughly before merging.

  3. Code Comment Opportunity: Consider adding a comment explaining why the config.use check was added in the findIndex:

    // In beta.8, there's a oneOf rule at index 0 that matches .scss but has no 'use' array
    // We need to find the SCSS rule that actually has loaders configured
    const scssConfigIndex = baseClientWebpackConfig.module.rules.findIndex((config) =>
      '.scss'.match(config.test) && config.use,
    );

Verdict

Approve with minor suggestions. The core fix is correct and addresses the breaking change appropriately. The suggested improvements are minor and focus on edge case handling and code clarity.


🤖 Generated by Claude Code

Copy link

@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)
config/webpack/commonWebpackConfig.js (1)

39-52: Minor: Redundant undefined check.

The sassLoaderIndex !== undefined check is technically redundant since Array.prototype.findIndex only returns -1 (when not found) or a valid index (0 or positive integer), never undefined. However, this defensive check is harmless and may improve code clarity.

If you prefer to remove the redundant check:

-if (sassLoaderIndex !== -1 && sassLoaderIndex !== undefined) {
+if (sassLoaderIndex !== -1) {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8f7bb45 and 2d00493.

⛔ Files ignored due to path filters (2)
  • Gemfile.lock is excluded by !**/*.lock
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (3)
  • Gemfile (1 hunks)
  • config/webpack/commonWebpackConfig.js (3 hunks)
  • package.json (1 hunks)
🧰 Additional context used
🪛 ESLint
config/webpack/commonWebpackConfig.js

[error] 56-56: Replace loader with (loader)

(prettier/prettier)

⏰ 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: test (22.x, 3.3.4)
🔇 Additional comments (5)
Gemfile (1)

9-9: LGTM!

Version bump to Shakapacker 9.0.0.beta.8 aligns with the PR objectives and matches the corresponding package.json update.

package.json (1)

96-96: LGTM!

Shakapacker dependency updated to 9.0.0-beta.8, consistent with the Gemfile change.

config/webpack/commonWebpackConfig.js (3)

27-28: LGTM!

The additional config.use check correctly filters for SCSS rules that actually contain loaders, avoiding the new oneOf pattern at index 0 in beta.8 that matches .scss but lacks a use array.


32-37: LGTM!

Optional chaining safely navigates the scssRule.use array, preventing errors when the SCSS rule lacks loaders.


65-67: LGTM!

The guard correctly prevents attempting to push to a non-existent use array, aligning with the defensive null-safety approach throughout this change.

@justin808
Copy link
Member Author

/deploy-review-app

Copy link

github-actions bot commented Oct 3, 2025

✅ Deployment complete for PR #665, commit 2d00493

🚀 Review App for PR #665
🎮 Control Plane Console

📋 View Completed Action Build and Deploy Logs

Updates Shakapacker from beta.7 to beta.8. The main change required was
fixing the webpack config to properly detect SCSS rules, as the rule
structure changed in beta.8 to include a new oneOf pattern at index 0.

Changes:
- Update Shakapacker version in Gemfile and package.json
- Fix commonWebpackConfig.js to find SCSS rules that have a 'use' array
- Add null safety checks for scssRule properties

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

Co-Authored-By: Claude <noreply@anthropic.com>
@justin808 justin808 force-pushed the justin808/shakapacker-9-beta8 branch from 2d00493 to ccea269 Compare October 3, 2025 06:47
Copy link

github-actions bot commented Oct 3, 2025

✅ Deployment complete for PR #665, commit ccea269

🚀 Review App for PR #665
🎮 Control Plane Console

📋 View Completed Action Build and Deploy Logs

Copy link

claude bot commented Oct 3, 2025

Pull Request Review: Migrate to Shakapacker 9.0.0-beta.8

Summary

This PR successfully updates Shakapacker from beta.7 to beta.8 and addresses a critical webpack configuration issue introduced by structural changes in the new version. The implementation is solid with good defensive programming practices.


✅ Code Quality & Best Practices

Strengths:

  • Excellent defensive programming: The added null safety check (config.use in the findIndex predicate at line 27) properly handles the new oneOf pattern in beta.8
  • Appropriate warning message: The console.warn at line 31 provides useful debugging information if the configuration isn't found
  • Clean guard clause: The if (scssConfigIndex === -1) check prevents runtime errors when the expected config structure isn't present
  • Consistent indentation: Code maintains proper indentation and formatting throughout
  • Good scope management: All SCSS configuration logic is now properly contained within the else block

Suggestions:

  1. Add more context to the warning message (config/webpack/commonWebpackConfig.js:31):

    console.warn('No SCSS rule with use array found in webpack config. SCSS processing may not work correctly.');

    This helps developers understand the impact of the missing configuration.

  2. Consider logging the actual rule structure for debugging:

    if (scssConfigIndex === -1) {
      console.warn('No SCSS rule with use array found in webpack config');
      console.debug('Available rules:', baseClientWebpackConfig.module.rules);
    } else {

🐛 Potential Bugs or Issues

No critical bugs found, but some considerations:

  1. Silent failure risk: If scssConfigIndex === -1, the code logs a warning but continues execution. The sassLoaderConfig won't be pushed to the rules array. While this is appropriate defensive behavior, it means SCSS features might silently fail. Consider whether this should throw an error in development mode:

    if (scssConfigIndex === -1) {
      const message = 'No SCSS rule with use array found in webpack config';
      if (process.env.NODE_ENV === 'development') {
        throw new Error(message);
      } else {
        console.warn(message);
      }
    }
  2. Mutation of global config: The code still mutates baseClientWebpackConfig.module.rules[scssConfigIndex] (line 68). While this works, the comment at line 71 acknowledges this is a mutable global. Consider whether a defensive copy should be made earlier in the function.


⚡ Performance Considerations

No performance concerns identified:

  • The additional .use check in findIndex is a trivial operation (property access)
  • The nested if-else structure is well-optimized with early returns via the guard clause
  • No redundant iterations or unnecessary computations

🔒 Security Concerns

No security issues found:

  • Version bump from beta.7 to beta.8 appears to be a routine update
  • No new dependencies or external inputs introduced
  • Configuration changes are internal webpack setup only
  • Optional chaining (?.) is used appropriately for safe property access (lines 60, 64)

Recommendation: Consider reviewing the Shakapacker 9.0.0-beta.8 changelog for any security-related updates or breaking changes beyond the webpack rules structure.


🧪 Test Coverage

Current state:

  • ✅ PR description indicates build passes (yarn build:test)
  • ✅ RuboCop linter passes
  • ❌ No unit tests found for commonWebpackConfig.js

Recommendations:

  1. Add webpack config tests: Consider adding a test file to verify the SCSS rule finding logic:

    // config/webpack/__tests__/commonWebpackConfig.test.js
    describe('commonWebpackConfig', () => {
      it('finds SCSS rule with use array', () => {
        // Test the findIndex logic
      });
      
      it('handles missing SCSS rule gracefully', () => {
        // Test the warning path
      });
      
      it('configures sass-loader with modern API', () => {
        // Verify sass-loader configuration
      });
    });
  2. Integration test: Verify that SCSS files actually compile with the new configuration. A simple test could build a component with SCSS modules and verify the output.


📋 Additional Notes

  1. Technical details in PR description: Excellent job documenting the oneOf pattern change in beta.8. This will help future maintainers understand why this code exists.

  2. Consistency with serverWebpackConfig.js: The server webpack config also iterates over module.rules and filters items (lines 33-39, 75-106). Consider whether similar defensive checks are needed there for the beta.8 changes.

  3. Documentation: Consider adding a comment explaining the oneOf pattern for future reference:

    // In Shakapacker 9.0.0-beta.8, webpack rules include a new oneOf pattern
    // at index 0 that matches .scss but doesn't have a use array.
    // We need to find the SCSS rule that actually has loaders configured.
    const scssConfigIndex = baseClientWebpackConfig.module.rules.findIndex((config) =>
      '.scss'.match(config.test) && config.use,
    );

✨ Conclusion

This is a well-implemented fix for a breaking change in Shakapacker beta.8. The defensive programming approach is appropriate, and the code quality is high.

Recommendation: Approve with minor suggestions

The suggestions above are optional improvements that would enhance debuggability and test coverage, but they don't block merging this PR. The core fix is sound and addresses the issue correctly.

Great work on identifying and fixing the oneOf pattern issue! 🎉


Review conducted with focus on code quality, potential bugs, performance, security, and test coverage as requested.

Copy link

@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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2d00493 and ccea269.

⛔ Files ignored due to path filters (2)
  • Gemfile.lock is excluded by !**/*.lock
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (3)
  • Gemfile (1 hunks)
  • config/webpack/commonWebpackConfig.js (1 hunks)
  • package.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • package.json
  • Gemfile
🧰 Additional context used
🪛 ESLint
config/webpack/commonWebpackConfig.js

[error] 48-48: Insert ,

(prettier/prettier)


[error] 49-49: Insert ,

(prettier/prettier)

⏰ 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). (2)
  • GitHub Check: deploy
  • GitHub Check: test (22.x, 3.3.4)
🔇 Additional comments (5)
config/webpack/commonWebpackConfig.js (5)

26-28: LGTM: Proper filtering for SCSS rules with loaders.

The addition of && config.use correctly filters out SCSS rules that match the test pattern but lack a use array, ensuring only rules with actual loaders are selected. This addresses the structural changes in Shakapacker 9.0.0-beta.8.


30-32: LGTM: Defensive guard clause.

The early return with a warning message provides clear feedback when no SCSS rule with a use array is found, preventing potential runtime errors in the configuration logic below.


34-40: LGTM: Robust sass-loader detection.

The logic correctly handles both string and object loader formats with proper null-safety checks, ensuring the sass-loader is accurately identified regardless of its configuration format.


57-66: LGTM: CSS modules configuration.

The css-loader lookup and exportLocalsConvention adjustment properly ensures compatibility when namedExport is enabled, preventing potential runtime errors with CSS modules.


68-68: LGTM: Safe sass-resources-loader addition.

Moving this line inside the guarded else block ensures the sass-resources-loader is only added when a valid SCSS rule with a use array exists, preventing potential runtime errors.

Comment on lines +42 to 55
if (sassLoaderIndex !== -1) {
const sassLoader = scssRule.use[sassLoaderIndex];
if (typeof sassLoader === 'string') {
scssRule.use[sassLoaderIndex] = {
loader: sassLoader,
options: {
api: 'modern'
}
};
} else {
sassLoader.options = sassLoader.options || {};
sassLoader.options.api = 'modern';
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix ESLint formatting issues.

ESLint/Prettier flagged missing trailing commas on lines 48 and 49.

Apply this diff:

         loader: sassLoader,
         options: {
-          api: 'modern'
+          api: 'modern',
         }

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 ESLint

[error] 48-48: Insert ,

(prettier/prettier)


[error] 49-49: Insert ,

(prettier/prettier)

🤖 Prompt for AI Agents
In config/webpack/commonWebpackConfig.js around lines 42 to 55, ESLint/Prettier
reported missing trailing commas on lines 48 and 49; update the object literals
to include trailing commas (add a trailing comma after the api: 'modern'
property and ensure the enclosing options object/loader object entries end with
trailing commas) so the scssRule.use replacement conforms to the project's
formatting rules.

@justin808 justin808 merged commit 79a7efc into master Oct 3, 2025
8 checks passed
@justin808 justin808 deleted the justin808/shakapacker-9-beta8 branch October 3, 2025 07:33
Copy link

github-actions bot commented Oct 3, 2025

✅ Review app for PR #665 was successfully deleted

View Completed Delete Logs

Control Plane Organization

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.

1 participant