Configuring Webpack for Production Source Maps
Production-grade error tracking requires precise mapping between minified assets and original source files. This guide details the exact Webpack devtool configurations, output.publicPath overrides, and security headers needed to maintain environment parity. While foundational concepts are covered in Source Map Generation & Stack Trace Debugging, this cluster focuses on actionable Webpack 5 implementation for SREs and platform engineers.
Key implementation priorities:
- Select optimal
devtoolflags balancing build speed vs. trace accuracy - Implement
hidden-source-mapto prevent public exposure while retaining symbolication - Configure
output.sourceMapFilenamefor CDN path resolution - Validate stack trace fidelity across minified and transpiled outputs
Webpack devtool Configuration Matrix
Define exact devtool values for production builds. Prioritize hidden-source-map and nosources-source-map to balance observability with security. Teams migrating from alternative bundlers should reference Vite Build Settings for Accurate Stack Traces for comparative path strategies.
- Compare
eval,source-map,hidden-source-map, andnosources-source-mapperformance trade-offs - Set
devtool: 'hidden-source-map'inwebpack.config.jsfor production mode - Verify
SourceMapDevToolPluginfallback for advanced filtering - Benchmark build times and output bundle sizes across configurations
const path = require('path');
const webpack = require('webpack');
module.exports = {
mode: 'production',
devtool: 'hidden-source-map',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js',
sourceMapFilename: '[name].[contenthash].js.map',
publicPath: process.env.CDN_URL || '/'
},
plugins: [
new webpack.SourceMapDevToolPlugin({
filename: '[file].map',
exclude: ['vendor.js']
})
]
};
This configuration demonstrates hidden-source-map generation. The plugin strips inline mapping comments from the final bundle. Content-hashed filenames enforce deterministic cache busting. Explicit sourceMapFilename prevents path collisions during CDN synchronization.
CDN Path Resolution & Asset Mapping
Resolve output.publicPath and sourceMapFilename mismatches that cause 404s during automated symbolication pipelines. Misconfigured origins break the automated ingestion workflow.
- Configure
output.sourceMapFilename: '[file].map'to enforce deterministic paths - Override
publicPathdynamically via__webpack_public_path__for multi-CDN setups - Implement
webpack.DefinePluginto inject environment-specific base URLs - Validate
//# sourceMappingURL=comments in compiled assets against Understanding Source Map v3 Specification and Formats
Webpack resolves relative paths at runtime. Hardcoded publicPath values fail when assets shift across edge networks. Inject dynamic origins during the CI/CD pipeline. Verify the trailing comment in your compiled .js files matches the exact CDN origin.
Babel Integration & Transpilation Chain
Ensure babel-loader preserves original line/column mappings by configuring sourceMaps: true and inputSourceMap passthrough. Misaligned transpilation chains frequently corrupt mappings, as detailed in Why source maps break after Babel transpilation.
- Set
babel-loaderoptions:{ presets: [['@babel/preset-env', { modules: false }]], sourceMaps: true } - Enable
inputSourceMapto chain Webpack-generated maps through Babel - Disable
compact: truein Babel to prevent aggressive line collapsing - Verify
source-map-loaderplacement inmodule.rulesfor pre-processing
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
presets: [['@babel/preset-env', { modules: false }]],
sourceMaps: true,
inputSourceMap: true,
compact: false
}
}
]
}
]
}
This chain configures babel-loader to accept Webpack’s initial mapping via inputSourceMap. Disabling compact prevents aggressive line compaction. The loader preserves original line/column references across ES6+ syntax transformations.
Security Hardening & Access Control
Deploy server-side routing rules and CSP directives to block public access to .map files while allowing authorized symbolication services to retrieve them. For edge-case routing failures, consult Fixing incorrect source map paths after CDN deployment.
- Configure Nginx/Apache
locationblocks to return 403 for*.maprequests - Implement IP-allowlisted reverse proxy endpoints for error tracking crawlers
- Set
Content-Security-Policyheaders to restrict unauthorized source map fetching - Automate
.mapfile cleanup post-deployment using CI/CD artifact pruning
location ~* \.map$ {
deny all;
return 404;
}
location /internal/symbolication {
allow 10.0.0.0/8;
allow 172.16.0.0/12;
deny all;
proxy_pass http://error-tracker-api;
}
This configuration enforces strict access control. Public requests for .map files receive a 404 response. Internal symbolication crawlers route through an allowlisted reverse proxy. Deploy this alongside strict X-Content-Type-Options: nosniff headers.
Common Mistakes
- Using
devtool: 'source-map'in production: Generates publicly accessible.mapfiles. This exposes unminified source code, internal logic, and potential secrets to attackers. - Hardcoding
publicPathwithout CDN awareness: Causes//# sourceMappingURL=comments to point to incorrect origins. Automated stack trace symbolication fails with 404 errors. - Omitting
source-map-loaderfor third-party dependencies: Prevents Webpack from consuming pre-existing maps fromnode_modules. Stack traces resolve to minified vendor code instead of original libraries. - Enabling Babel
compact: true: Aggressively collapses whitespace and newlines. Original line numbers are destroyed, making cross-referenced stack traces inaccurate.
FAQ
Should I use hidden-source-map or nosources-source-map for production?
Use hidden-source-map if your error tracking service requires full source context for accurate symbolication. Use nosources-source-map only when legal or compliance constraints forbid exposing original source code to the symbolication service.
How do I verify that Webpack generated valid source maps before deployment?
Run source-map-explorer dist/*.js or use webpack-bundle-analyzer with --stats. Validate sourcesContent arrays and cross-reference generated line/column mappings against original files.
Why are my stack traces still pointing to minified code despite correct Webpack config?
Check for missing source-map-loader in module.rules. Verify inputSourceMap: true in Babel options. Ensure your error tracking SDK correctly uploads .map artifacts to the symbolication endpoint.