-
Notifications
You must be signed in to change notification settings - Fork 16
Description
Summary
VLT's razzle.extend.js plugin filter compares objects to a string, which is always true, so the built-in SCSS plugin is never removed. This results in two duplicate SCSS webpack rules that cause SCSS imports to silently produce zero CSS output.
Environment
- Volto 19.0.0-alpha.24 (monorepo at
packages/volto) - volto-light-theme 7.7.0 (also confirmed in 7.6.0 — identical code)
- Node 22.22.0, pnpm via corepack
Root Cause
VLT's razzle.extend.js line 2:
const newPlugins = defaultPlugins.filter((plugin) => plugin !== 'scss');But Volto registers plugins as objects, not strings:
// Volto's razzle.config.js line 427:
const defaultPlugins = [
{ object: require('./webpack-plugins/webpack-less-plugin')({ registry }) },
{ object: require('./webpack-plugins/webpack-svg-plugin') },
{ object: require('./webpack-plugins/webpack-bundle-analyze-plugin') },
{ object: require('./webpack-plugins/webpack-scss-plugin') }, // <-- unnamed object
];An object is never === to a string, so the filter removes nothing. The built-in SCSS plugin survives. VLT then pushes its own { name: 'scss', options: {...} } entry, resulting in two SCSS webpack rules for /\.(sa|sc)ss$/.
The duplicate rules cause SCSS imports to silently produce zero CSS output (likely due to duplicate MiniCssExtractPlugin.loader extraction conflicting).
Evidence
- Two SCSS rules exist in the client webpack config — both match
/\.(sa|sc)ss$/, both have 5 loaders import './test.css'produces changed CSS output (new hash, larger file)import './test.scss'with trivial content produces identical CSS output (same hash, same size)sass.compile()from Node successfully compiles VLT's fullmain.scssto 334KB of CSS- Removing the built-in SCSS plugin fixes the issue — VLT's SCSS compiles correctly
Suggested Fix
The filter was likely written for an older Volto/Razzle format where plugins were passed as strings (['less', 'svg', 'scss']). It needs to handle the object format:
const plugins = (defaultPlugins) => {
const newPlugins = defaultPlugins.filter((plugin) => {
if (typeof plugin === 'string') return plugin !== 'scss';
if (typeof plugin === 'object' && plugin !== null && plugin.name === 'scss') return false;
return true;
});
// ... rest unchangedThis also requires Volto to tag its SCSS plugin with a name:
- { object: require('./webpack-plugins/webpack-scss-plugin') },
+ { name: 'scss', object: require('./webpack-plugins/webpack-scss-plugin') },Alternatively, VLT could filter by checking the object structure (e.g., inspecting the plugin's modifyWebpackConfig function).
Workaround
We applied both changes locally (tag + filter fix) and VLT's SCSS now compiles natively through webpack. CSS bundle is correct at ~1.09MB (785KB Semantic UI + 303KB VLT).
🤖 Generated with Claude Code