Skip to content

Commit 79a7efc

Browse files
authored
Migrate to Shakapacker 9.0.0-beta.8 (#665)
Updates Shakapacker from 9.0.0-beta.7 to 9.0.0-beta.8 with minimal changes. The primary fix addresses a breaking change in the webpack configuration structure introduced in beta.8. Key Changes: - Updated Shakapacker to 9.0.0-beta.8 in Gemfile and package.json - Fixed commonWebpackConfig.js to properly detect SCSS rules in the new webpack config structure - Added defensive edge case handling for missing SCSS rules - Removed redundant null checks and added ESLint-compliant formatting Technical Details: Shakapacker beta.8 introduced a new webpack rule structure with a oneOf pattern at index 0 that matches .scss files but lacks a use array. The original code would find this incorrect rule and crash when attempting to access the use property. The fix modifies the SCSS rule finder to require both a test match AND a use array, ensuring it finds the correct rule with configured loaders. An additional safety check warns if no valid SCSS rule is found, preventing runtime errors. Breaking Changes: None. This is a patch-level update with no API changes. Impact: - Existing installations: Update dependencies and rebuild assets - New installations: No special considerations - Build process remains identical - All existing webpack configurations continue to work Testing: - Full test build passes (yarn build:test) - RuboCop linting passes - Production build verified - No behavioral changes to asset pipeline Related Issues: Follow-up migrations planned in separate PRs: - Issue #666: Migrate from Babel to SWC transpiler - Issue #667: Migrate to TypeScript - Issue #668: Migrate from Webpack to Rspack
1 parent 8f7bb45 commit 79a7efc

File tree

5 files changed

+44
-40
lines changed

5 files changed

+44
-40
lines changed

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
66
ruby "3.3.4"
77

88
gem "react_on_rails", "16.1.1"
9-
gem "shakapacker", "9.0.0.beta.7"
9+
gem "shakapacker", "9.0.0.beta.8"
1010

1111
# Bundle edge Rails instead: gem "rails", github: "rails/rails"
1212
gem "listen"

Gemfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ GEM
390390
websocket (~> 1.0)
391391
semantic_range (3.1.0)
392392
sexp_processor (4.17.1)
393-
shakapacker (9.0.0.beta.7)
393+
shakapacker (9.0.0.beta.8)
394394
activesupport (>= 5.2)
395395
package_json
396396
rack-proxy (>= 0.6.1)
@@ -499,7 +499,7 @@ DEPENDENCIES
499499
scss_lint
500500
sdoc
501501
selenium-webdriver (~> 4)
502-
shakapacker (= 9.0.0.beta.7)
502+
shakapacker (= 9.0.0.beta.8)
503503
spring
504504
spring-commands-rspec
505505
stimulus-rails (~> 1.3)

config/webpack/commonWebpackConfig.js

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,45 +24,49 @@ const ignoreWarningsConfig = {
2424
};
2525

2626
const scssConfigIndex = baseClientWebpackConfig.module.rules.findIndex((config) =>
27-
'.scss'.match(config.test),
27+
'.scss'.match(config.test) && config.use,
2828
);
2929

30-
// Configure sass-loader to use the modern API
31-
const scssRule = baseClientWebpackConfig.module.rules[scssConfigIndex];
32-
const sassLoaderIndex = scssRule.use.findIndex((loader) => {
33-
if (typeof loader === 'string') {
34-
return loader.includes('sass-loader');
35-
}
36-
return loader.loader && loader.loader.includes('sass-loader');
37-
});
30+
if (scssConfigIndex === -1) {
31+
console.warn('No SCSS rule with use array found in webpack config');
32+
} else {
33+
// Configure sass-loader to use the modern API
34+
const scssRule = baseClientWebpackConfig.module.rules[scssConfigIndex];
35+
const sassLoaderIndex = scssRule.use.findIndex((loader) => {
36+
if (typeof loader === 'string') {
37+
return loader.includes('sass-loader');
38+
}
39+
return loader.loader && loader.loader.includes('sass-loader');
40+
});
3841

39-
if (sassLoaderIndex !== -1) {
40-
const sassLoader = scssRule.use[sassLoaderIndex];
41-
if (typeof sassLoader === 'string') {
42-
scssRule.use[sassLoaderIndex] = {
43-
loader: sassLoader,
44-
options: {
45-
api: 'modern'
46-
}
47-
};
48-
} else {
49-
sassLoader.options = sassLoader.options || {};
50-
sassLoader.options.api = 'modern';
42+
if (sassLoaderIndex !== -1) {
43+
const sassLoader = scssRule.use[sassLoaderIndex];
44+
if (typeof sassLoader === 'string') {
45+
scssRule.use[sassLoaderIndex] = {
46+
loader: sassLoader,
47+
options: {
48+
api: 'modern'
49+
}
50+
};
51+
} else {
52+
sassLoader.options = sassLoader.options || {};
53+
sassLoader.options.api = 'modern';
54+
}
5155
}
52-
}
5356

54-
// Fix css-loader configuration for CSS modules if namedExport is enabled
55-
// When namedExport is true, exportLocalsConvention must be camelCaseOnly or dashesOnly
56-
const cssLoader = scssRule.use.find(loader => {
57-
const loaderName = typeof loader === 'string' ? loader : loader?.loader;
58-
return loaderName?.includes('css-loader');
59-
});
57+
// Fix css-loader configuration for CSS modules if namedExport is enabled
58+
// When namedExport is true, exportLocalsConvention must be camelCaseOnly or dashesOnly
59+
const cssLoader = scssRule.use.find((loader) => {
60+
const loaderName = typeof loader === 'string' ? loader : loader?.loader;
61+
return loaderName?.includes('css-loader');
62+
});
6063

61-
if (cssLoader?.options?.modules?.namedExport) {
62-
cssLoader.options.modules.exportLocalsConvention = 'camelCaseOnly';
63-
}
64+
if (cssLoader?.options?.modules?.namedExport) {
65+
cssLoader.options.modules.exportLocalsConvention = 'camelCaseOnly';
66+
}
6467

65-
baseClientWebpackConfig.module.rules[scssConfigIndex].use.push(sassLoaderConfig);
68+
baseClientWebpackConfig.module.rules[scssConfigIndex].use.push(sassLoaderConfig);
69+
}
6670

6771
// Copy the object using merge b/c the baseClientWebpackConfig and commonOptions are mutable globals
6872
const commonWebpackConfig = () => merge({}, baseClientWebpackConfig, commonOptions, ignoreWarningsConfig);

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
"sass": "^1.58.3",
9494
"sass-loader": "^13.3.2",
9595
"sass-resources-loader": "^2.2.5",
96-
"shakapacker": "9.0.0-beta.7",
96+
"shakapacker": "9.0.0-beta.8",
9797
"stimulus": "^3.0.1",
9898
"style-loader": "^3.3.1",
9999
"tailwindcss": "^3.3.3",

yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8263,10 +8263,10 @@ setprototypeof@1.2.0:
82638263
resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
82648264
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
82658265

8266-
shakapacker@9.0.0-beta.7:
8267-
version "9.0.0-beta.7"
8268-
resolved "https://registry.npmjs.org/shakapacker/-/shakapacker-9.0.0-beta.7.tgz#c00b9590b84f365bf0fd4e7b7efdd59104901a00"
8269-
integrity sha512-m4xGyTg9yy4ys+wz44jBdygsxwKDbARBlgYqsyirwowQKWZHqnyb+ucS9yz5cKQHUtHeDlJOhPHKhRsCwhJcDQ==
8266+
shakapacker@9.0.0-beta.8:
8267+
version "9.0.0-beta.8"
8268+
resolved "https://registry.npmjs.org/shakapacker/-/shakapacker-9.0.0-beta.8.tgz#ab951f8ab575d1c178639c2048a296ae27c9a467"
8269+
integrity sha512-NPu5cTB6lL/Bzl8XDl1NfjlljLARWPH9YhjIh1CvXEuSdaNP2qJLSiIr68Bqv3IGHQmqtifgRl1iXQB8pNnAfQ==
82708270
dependencies:
82718271
js-yaml "^4.1.0"
82728272
path-complete-extname "^1.0.0"

0 commit comments

Comments
 (0)