Measuring Bundle Impact with Bundlephobia and Webpack Analyzer
Track npm package size regressions using Bundlephobia and Webpack Bundle Analyzer. Set ESM and CJS size baselines, generate visual dependency maps, and gate size budgets in CI.
Isolating ESM and CJS Metrics in Webpack Analyzer
Configure separate analyzer runs to prevent cross-contamination of dual-format bundle stats. When establishing size baselines for dual-format distributions, maintain strict isolation between ESM and CJS outputs to ensure accurate regression tracking before publishing to npm, as outlined in Optimizing Bundle Size for Frontend Libraries.
Configuration:
// webpack.config.js
module.exports = (env) => ({
entry: env.format === 'esm' ? './src/index.esm.js' : './src/index.cjs.js',
output: {
filename: `index.${env.format}.js`,
library: { type: env.format === 'esm' ? 'module' : 'commonjs' }
},
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: 'json', // Generates stats.json without launching UI in headless CI
defaultSizes: 'gzip', // Reflects real-world network transfer impact
openAnalyzer: false
})
],
stats: {
all: false,
modules: true,
reasons: true,
optimizationBailout: true
}
});
Execution: Pass --env format=esm and --env format=cjs to dynamically toggle entry points per build.
Exact Error & Resolution:
Error: Cannot read properties of undefined (reading 'modules') occurs when default webpack stats omit module data. Resolve by explicitly adding stats: { all: false, modules: true, reasons: true, optimizationBailout: true } to the webpack configuration.
Automating Pre-Publish Size Regression with Bundlephobia CLI
Enforce strict bundle size thresholds before registry publication. Install bundlephobia-cli as a dev dependency and execute via npx bundlephobia-cli ./dist/esm/index.js. Leverage --format json and --max-size 15kb to fail CI pipelines automatically on threshold breaches. Validate that the CLI correctly resolves the exports field map instead of falling back to main.
Exact Error & Resolution:
Error: Failed to resolve package exports triggers when the resolver cannot parse conditional export maps. Fix by ensuring package.json exports uses "./": "./dist/esm/" with an explicit "./package.json" mapping to prevent fallback resolution failures.
Auditing Tree-Shakeability via Analyzer Bailout Flags
Identify and eliminate modules that webpack cannot safely prune. Scan optimizationBailout arrays in stats.json for ModuleConcatenation bailout: Module is not an ECMAScript module. Cross-reference sideEffects declarations with actual CSS/SCSS imports to prevent accidental dead code elimination. Use webpack-bundle-analyzer’s excludeAssets regex to strip node_modules polyfills from the report. Direct correlation between optimizationBailout flags and module concatenation failures is documented in Tree-Shaking & Bundle Optimization.
Exact Error & Resolution:
Warning: sideEffects: true blocks pruning occurs when global side-effect flags override granular tree-shaking. Resolve by explicitly declaring "sideEffects": ["**/*.css", "**/*.scss"] in package.json.
Step-by-Step Execution
- Generate isolated stats for ESM and CJS outputs
webpack --config webpack.config.js --env format=esm --json > stats-esm.json && webpack --config webpack.config.js --env format=cjs --json > stats-cjs.json
- Run Bundlephobia CLI with strict gzip threshold
npx bundlephobia-cli ./dist/esm/index.js --format json --max-size 20kb --gzip
- Patch package.json exports and sideEffects based on bailout logs
sed -i 's/"sideEffects": true/"sideEffects": ["**\/*.css", "**\/*.scss"]/' package.json && jq '.exports["."] = { "import": "./dist/esm/index.js", "require": "./dist/cjs/index.js" }' package.json > tmp.json && mv tmp.json package.json
- Integrate size validation into CI pipeline
echo '{"scripts": {"check-size": "npx bundlephobia-cli ./dist/esm/index.js --max-size 20kb --fail-on-exceed"}}' >> package.json