Skip to content

optimization.minimize: true crashes in 5.110.0 when a plugin sets it on already-normalized options #21844

Description

@AgentEnder

Bug report

optimization.minimize: true crashes in 5.110.0 when a plugin sets it on already-normalized options

What is the current behavior?

A build throws during createCompiler:

TypeError: Cannot create property 'javascript' on boolean 'true'
    at F (webpack/lib/config/defaults.js:260:13)
    at applyOptimizationDefaults (webpack/lib/config/defaults.js:2471:3)
    at applyWebpackOptionsDefaults (webpack/lib/config/defaults.js:572:2)
    at createCompiler (webpack/lib/webpack.js:174:33)

The new per-asset-type canonicalization added in 5.110.0 (#21663, #21537) guards on truthiness rather than type:

F(optimization, "minimize", () => (production ? {} : false));
const { minimize } = optimization;
if (minimize) {
  F(minimize, "javascript", () => ({ compress: { passes: 2 } }));
  F(minimize, "css", () => ({}));
  F(minimize, "html", () => ({}));
}

F assigns when the property is undefined, so with minimize === true this evaluates true.javascript = {...}, which throws in strict mode.

getNormalizedOptimizationMinimize already maps true to {}, so a plain config object is fine. The gap is that createCompiler normalizes first and applies plugins afterwards:

const createCompiler = (rawOptions, compilerIndex) => {
  let options = getNormalizedWebpackOptions(rawOptions);   // true -> {}
  applyWebpackOptionsBaseDefaults(options);
  ...
  for (const plugin of options.plugins) plugin.apply(compiler);   // plugin writes minimize: true
  const resolvedDefaultOptions = applyWebpackOptionsDefaults(options, compilerIndex);  // throws

Any plugin that assigns compiler.options.optimization.minimize from a boolean in apply() writes a value normalization no longer gets to see. That pattern was harmless in every 5.x before this one: 5.109.2 only ever reads the option for truthiness (WebpackOptionsApply.js:819) and fills it with D(optimization, "minimize", production).

If the current behavior is a bug, please provide the steps to reproduce.

// webpack.config.js
class SetMinimize {
  apply(compiler) {
    compiler.options.optimization.minimize = true;
  }
}

module.exports = {
  mode: 'production',
  plugins: [new SetMinimize()],
};

npx webpack throws on 5.110.0 and succeeds on 5.109.2. Verified against both: on 5.109.2 the build emits main.js 18 bytes [minimized], so the boolean was doing real work rather than being quietly ignored.

What is the expected behavior?

The build succeeds, with true treated as the documented shorthand for "minimize with defaults", the same way getNormalizedOptimizationMinimize treats it.

Worth noting that schemas/WebpackOptions.json in 5.110.0 still declares the boolean as valid:

"minimize": {
  "anyOf": [{ "type": "boolean" }, { "$ref": "#/definitions/OptimizationMinimizeOptions" }]
}

so a config carrying true validates and then crashes.

A one-line coercion in applyOptimizationDefaults restores the old behavior and keeps the new object form intact:

 	F(optimization, "minimize", () => (production ? {} : false));
+	// A plugin can assign the `true` shorthand to already-normalized options,
+	// which `getNormalizedOptimizationMinimize` never sees.
+	if (optimization.minimize === true) optimization.minimize = {};
 	const { minimize } = optimization;
 	if (minimize) {

I applied that against 5.110.0 locally and the repro above compiles, emitting the same main.js 18 bytes [minimized] as 5.109.2. Happy to open a PR with it plus a regression test if the approach looks right.

Other relevant information

  • webpack version: 5.110.0 (5.109.2 unaffected)
  • Node.js version: 20
  • Operating System: Linux
  • Additional tools: webpack-cli 7.2.2

Found via @nx/webpack, whose plugin sets the option in apply(). Given that compiler.options is a documented mutation point for plugins and the boolean is still schema-valid, other plugins are likely to be affected too.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: configOptions, defaults, validation (lib/config, schemas/)area: optimizationTree-shaking, splitChunks, concatenation, ids (lib/optimize, lib/ids)regressionWorked in a previous release; pair with the Affected version field

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      Sponsor
      SponsoredKunjungi sekarang
      Promo