From 301990e93ee708583c544083be2c9e7883e803bd Mon Sep 17 00:00:00 2001 From: Peter Mathis Date: Thu, 17 Sep 2026 07:47:39 +0200 Subject: [PATCH] maint(bundle): ship smaller source maps in production builds The production build shipped full source maps with the embedded sources of every chunk. With the lazy locale-data chunks this amounts to 159 MB of maps for the Plone bundle, all of it committed to plone.staticresources and installed on every deployment. nosources-source-map keeps the mappings, so stack traces still point to the original file and line, but drops the sources: 12 MB instead of 159 MB. css-loader and sass-loader derive their sourceMap option from devtool, and style-loader embeds the resulting CSS source maps into the JS chunks, where every browser downloads and parses them: the TinyMCE chunk alone grew from 1.9 MB to 3.2 MB (481 KB to 662 KB gzipped) with full maps, and all non-locale chunks together carried 1.8 MB (330 KB gzipped) of CSS maps. Switch them off explicitly for production builds. Development builds keep the full source maps. --- webpack.config.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/webpack.config.js b/webpack.config.js index f91899761..57a2a94ce 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -240,6 +240,33 @@ module.exports = () => { config.devServer.static.directory = path.resolve(__dirname, "./_site/"); } + if (process.env.NODE_ENV === "production") { + // Source maps without the embedded sources: stack traces still map to + // the original file and line, but the maps are more than 10x smaller. + // The full sources of every lazy chunk would otherwise be shipped with + // plone.staticresources and every Plone deployment. + config.devtool = "nosources-source-map"; + + // css-loader and sass-loader derive their sourceMap option from + // devtool, and style-loader embeds the resulting CSS source maps into + // the JS chunks, where every browser downloads and parses them (the + // TinyMCE chunk alone grows by more than 1 MB with full maps). + // Nobody debugs the compiled CSS of a production site down to the + // SCSS line, so switch them off explicitly. + for (const rule of config.module.rules) { + if (!Array.isArray(rule.use)) { + continue; + } + rule.use = rule.use.map((loader) => { + const name = typeof loader === "string" ? loader : loader.loader; + if (name !== "css-loader" && name !== "sass-loader") { + return loader; + } + return { loader: name, options: { ...loader.options, sourceMap: false } }; + }); + } + } + if (process.env.DEPLOYMENT === "docs") { config.output.path = path.resolve( __dirname,