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 devtool flags balancing build speed vs. trace accuracy
  • Implement hidden-source-map to prevent public exposure while retaining symbolication
  • Configure output.sourceMapFilename for 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, and nosources-source-map performance trade-offs
  • Set devtool: 'hidden-source-map' in webpack.config.js for production mode
  • Verify SourceMapDevToolPlugin fallback 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 publicPath dynamically via __webpack_public_path__ for multi-CDN setups
  • Implement webpack.DefinePlugin to 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-loader options: { presets: [['@babel/preset-env', { modules: false }]], sourceMaps: true }
  • Enable inputSourceMap to chain Webpack-generated maps through Babel
  • Disable compact: true in Babel to prevent aggressive line collapsing
  • Verify source-map-loader placement in module.rules for 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 location blocks to return 403 for *.map requests
  • Implement IP-allowlisted reverse proxy endpoints for error tracking crawlers
  • Set Content-Security-Policy headers to restrict unauthorized source map fetching
  • Automate .map file 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 .map files. This exposes unminified source code, internal logic, and potential secrets to attackers.
  • Hardcoding publicPath without CDN awareness: Causes //# sourceMappingURL= comments to point to incorrect origins. Automated stack trace symbolication fails with 404 errors.
  • Omitting source-map-loader for third-party dependencies: Prevents Webpack from consuming pre-existing maps from node_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.