Skip to content

refactor: validate options from webpack's validate hook - #701

Open
alexander-akait wants to merge 1 commit into
mainfrom
claude/webpack-minimizer-validation-qcf1vr
Open

refactor: validate options from webpack's validate hook#701
alexander-akait wants to merge 1 commit into
mainfrom
claude/webpack-minimizer-validation-qcf1vr

Conversation

@alexander-akait

@alexander-akait alexander-akait commented Aug 26, 2026

Copy link
Copy Markdown
Member

Summary

Moves option validation out of the constructor and onto compiler.validate, called from compiler.hooks.validate, so webpack owns when validation runs. validate: false now actually skips it — the constructor validated whatever the config said — and the schema is required lazily by the callback rather than at module load. Handing compiler.validate a pre-compiled check, so schema-utils and ajv are not loaded for valid options, is left to a follow-up PR.

Two fallbacks, both marked TODO to remove in the next major release:

  • webpack calls hooks.validate before it applies optimization.minimizer, so that hook reaches this plugin only where it sits in plugins. initialize is tapped alongside it, behind a latch, so the minimizer placement is validated too.
  • webpack before 5.106 has neither the hook nor compiler.validate, and validates with schema-utils directly.

Measured against a real webpack build, n=7 per arm, medians with ranges; retained heap read after forced GC:

before after
require() the plugin 6.1 ms 3.2 ms
default setup 404 ms [389-482] 419 ms [390-446]
default ajv modules / require.cache / retained heap 126 / 770 / 25.5 MB 126 / 770 / 25.5 MB
validate: false setup 429 ms [411-439] 298 ms [292-328]
validate: false ajv modules / require.cache / retained heap 126 / 770 / 25.4 MB 0 / 590 / 22.4 MB

Requiring the plugin is faster because options.json is no longer parsed at module load. With validation on nothing else moves: the default-setup difference is smaller than the run-to-run spread and the ranges overlap, so it is not a result, and ajv loads either way until the pre-compiled check lands. The win is validate: false, where the ranges are disjoint.

What kind of change does this PR introduce?

refactor

Did you add tests for your changes?

Yes — test/validate-options.test.js drives real compilers throughout, and adds a case for the optimization.minimizer placement. No unit tests: the pre-5.106 schema-utils fallback is therefore not covered by any test, since the matrix only runs webpack-version: latest.

Does this PR introduce a breaking change?

No. Invalid options are still rejected with the same message; the error is now thrown when the compiler is created rather than when the plugin is constructed, and validate: false now suppresses it.

If relevant, what needs to be documented once your changes are merged or what have you already documented?

n/a

Use of AI

Claude Code was used to rewire the validation and update the tests. The hook-ordering claim was verified empirically against webpack 5.109.2 rather than assumed: a probe plugin tapping both hooks reports validate, initialize for the plugins placement and initialize only for optimization.minimizer. The measurements above were taken by counting loaded modules and timing a real build across both arms; an earlier version of the harness attributed the constructor's cost to the wrong phase and was corrected before these numbers were taken. All changes were reviewed before committing.

@changeset-bot

changeset-bot Bot commented Aug 26, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 2adc2f6

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
minimizer-webpack-plugin Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@codecov

codecov Bot commented Aug 26, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.00000% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.39%. Comparing base (202428d) to head (2adc2f6).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
src/index.js 90.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #701      +/-   ##
==========================================
- Coverage   89.43%   89.39%   -0.05%     
==========================================
  Files           3        3              
  Lines         729      745      +16     
  Branches      251      259       +8     
==========================================
+ Hits          652      666      +14     
- Misses         66       68       +2     
  Partials       11       11              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@alexander-akait
alexander-akait force-pushed the claude/webpack-minimizer-validation-qcf1vr branch from 3abb90a to 32f71da Compare August 27, 2026 09:28
@alexander-akait alexander-akait changed the title perf: validate options from webpack's validate hook refactor: validate options from webpack's validate hook Aug 27, 2026
Move option validation out of the constructor and onto `compiler.validate`,
called from `compiler.hooks.validate`, so webpack owns when validation runs.
`validate: false` now actually skips it — the constructor validated whatever
the config said — and the schema is required lazily by the callback rather
than at module load.

webpack calls `hooks.validate` before it applies `optimization.minimizer`,
so that hook reaches the plugin only where it sits in `plugins`;
`initialize` is tapped alongside it, behind a latch, so the minimizer
placement is validated too. webpack before 5.106 has neither the hook nor
`compiler.validate` and falls back to `schema-utils` directly. Both are
marked TODO to remove in the next major release.

Measured against a real webpack build (n=7 per arm, medians): requiring the
plugin drops from 6.1ms to 3.2ms because `options.json` is no longer parsed
at module load. With validation on nothing else moves — ajv still loads
(126 modules) and retained heap is 25.5MB either way. With `validate: false`
setup goes 429ms -> 298ms on disjoint ranges, ajv modules 126 -> 0, modules
in require.cache 770 -> 590, and retained heap 25.4MB -> 22.4MB.
@alexander-akait
alexander-akait force-pushed the claude/webpack-minimizer-validation-qcf1vr branch from 32f71da to 2adc2f6 Compare August 27, 2026 10:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant