Debuggable builds and maintainable configs both depend on these choices.
Source maps map bundled code back to your sources in DevTools and error trackers. The devtool option picks the strategy, trading build speed against quality:
eval-cheap-module-source-map(oreval-source-map): fast rebuilds with good mappings; typical for development.source-map: full, separate.mapfiles; best quality, slowest. Use in production if you serve or upload maps.hidden-source-map: produces maps without the//# sourceMappingURLcomment, so browsers do not download them but you can upload them to Sentry or similar.false: no maps (production default).
Words in the name mean: eval (each module wrapped in eval, fast rebuilds), cheap (line-only mappings), module (maps through loaders to original sources), inline (embedded as data URLs, never in production).
Splitting config: as configs grow, keep webpack.common.js and merge mode-specific files with webpack-merge, or export a function and branch on argv.mode. Pick one approach and stay consistent.
Environment values: read process.env in the config (Node), then expose only what the client needs through DefinePlugin or EnvironmentPlugin. dotenv-webpack loads .env files. Again: everything defined ends up in the bundle.
Example
// webpack.common.js
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/index.js",
plugins: [new HtmlWebpackPlugin()],
};
// webpack.prod.js
const { merge } = require("webpack-merge");
const webpack = require("webpack");
const common = require("./webpack.common.js");
module.exports = merge(common, {
mode: "production",
devtool: "hidden-source-map", // maps for Sentry, not for browsers
output: { filename: "[name].[contenthash].js", clean: true },
plugins: [new webpack.EnvironmentPlugin({ API_URL: "https://api.example.com" })],
});
// webpack.dev.js: merge(common, { mode: "development", devtool: "eval-cheap-module-source-map" })
// package.json: "build": "webpack -c webpack.prod.js", "dev": "webpack serve -c webpack.dev.js"Remember
- Dev: eval-cheap-module-source-map; prod: source-map or hidden-source-map
inlinemaps never belong in production- webpack-merge composes common + mode-specific configs
- EnvironmentPlugin/DefinePlugin expose only what the client needs
Watch out for
- Shipping
evalorinlinesource maps in production bundles.