Verified on Shopware 6.7
Webpack in Shopware 6
While Shopware is moving toward Vite, many production shops still run on Webpack for their storefront builds. Whether you're maintaining an existing shop or can't migrate to Vite yet, here's how to customize the Webpack configuration effectively.
How Shopware Loads Webpack Config
Shopware's build system looks for a webpack.config.js in your plugin's storefront build directory:
YourPlugin/
└── src/
└── Resources/
└── app/
└── storefront/
├── build/
│ └── webpack.config.js ← Your overrides go here
└── src/
└── main.js
The config file exports a function that receives the base webpack config and returns the modified version:
// webpack.config.js
module.exports = function (webpackConfig) {
// Modify webpackConfig here
return webpackConfig;
};
1. Adding Custom Loaders
Need to process a file type that Shopware doesn't handle by default? Add a loader:
module.exports = function (webpackConfig) {
// Add SVG inline loader for custom icon system
webpackConfig.module.rules.push({
test: /\.svg$/,
include: /icons/,
use: [
{
loader: 'raw-loader',
},
],
});
return webpackConfig;
};
Install the loader in your plugin:
cd custom/plugins/YourPlugin/src/Resources/app/storefront/
npm install raw-loader -save-dev
2. SCSS Variable Injection
Override Shopware's SCSS variables globally without duplicating files:
const path = require('path');
module.exports = function (webpackConfig) {
// Find the sass-loader rule and prepend custom variables
const sassRule = webpackConfig.module.rules.find(
rule => rule.test && rule.test.toString().includes('scss')
);
if (sassRule && sassRule.use) {
const sassLoader = sassRule.use.find(
use => use.loader && use.loader.includes('sass-loader')
);
if (sassLoader) {
sassLoader.options = {
...sassLoader.options,
additionalData: `
$sw-color-brand-primary: #5288c1;
$sw-color-brand-secondary: #1e2c3a;
$sw-border-radius: 8px;
`,
};
}
}
return webpackConfig;
};
3. Bundle Analysis
See exactly what's making your storefront bundle large:
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = function (webpackConfig) {
if (process.env.ANALYZE) {
webpackConfig.plugins.push(
new BundleAnalyzerPlugin({
analyzerMode: 'static',
reportFilename: 'bundle-report.html',
openAnalyzer: false,
})
);
}
return webpackConfig;
};
Run with:
ANALYZE=true bin/build-storefront.sh
# Open bundle-report.html in your browser
4. Tree-Shaking Fixes
Sometimes Webpack includes entire libraries when you only need one function:
module.exports = function (webpackConfig) {
// Ensure tree-shaking works properly
webpackConfig.optimization = {
...webpackConfig.optimization,
usedExports: true,
sideEffects: true,
};
// Replace heavy imports with lighter alternatives
webpackConfig.resolve.alias = {
...webpackConfig.resolve.alias,
// Use lodash-es instead of lodash for tree-shaking
'lodash': 'lodash-es',
};
return webpackConfig;
};
Also check your imports:
// Bad - imports entire library
import _ from 'lodash';
_.debounce(fn, 300);
// Good - imports only what's needed
import debounce from 'lodash-es/debounce';
debounce(fn, 300);
5. Multi-Theme Builds
If you run multiple sales channels with different themes:
const path = require('path');
module.exports = function (webpackConfig) {
// Add theme-specific entry points
webpackConfig.entry = {
...webpackConfig.entry,
'theme-b2b': path.resolve(__dirname, '../src/themes/b2b/main.js'),
'theme-b2c': path.resolve(__dirname, '../src/themes/b2c/main.js'),
};
return webpackConfig;
};
Each entry gets its own bundle, loaded based on the active sales channel theme.
6. Source Maps for Production Debugging
When you need to debug production issues without exposing source code:
module.exports = function (webpackConfig) {
if (webpackConfig.mode === 'production') {
// Hidden source maps - uploaded to error tracking, not served to users
webpackConfig.devtool = 'hidden-source-map';
}
return webpackConfig;
};
Upload the generated .map files to your error tracking service (Sentry, Bugsnag) and delete them from the public directory.
Common Debugging Commands
# Build with verbose output
bin/build-storefront.sh -verbose
# Build specific plugin only (faster during development)
bin/build-storefront.sh -only YourPlugin
# Watch mode for development
bin/watch-storefront.sh
Gotchas
- Don't replace the entire config - always modify and return the existing
webpackConfig - Plugin load order affects merge order - last plugin to modify a config key wins
- Clear cache after config changes -
bin/console cache:clearand deletevar/cache/ - Node version matters - check
.nvmrcin Shopware root for the expected version - Production vs dev - always test with
bin/build-storefront.sh(production mode), not just watch mode
Need help optimizing your Shopware storefront build? Talk to us.