refactor: validate options from webpack's validate hook - #701
Open
alexander-akait wants to merge 1 commit into
Open
refactor: validate options from webpack's validate hook#701alexander-akait wants to merge 1 commit into
alexander-akait wants to merge 1 commit into
Conversation
🦋 Changeset detectedLatest commit: 2adc2f6 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
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 Report❌ Patch coverage is
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. 🚀 New features to boost your workflow:
|
alexander-akait
force-pushed
the
claude/webpack-minimizer-validation-qcf1vr
branch
from
August 27, 2026 09:28
3abb90a to
32f71da
Compare
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
force-pushed
the
claude/webpack-minimizer-validation-qcf1vr
branch
from
August 27, 2026 10:05
32f71da to
2adc2f6
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Moves option validation out of the constructor and onto
compiler.validate, called fromcompiler.hooks.validate, so webpack owns when validation runs.validate: falsenow actually skips it — the constructor validated whatever the config said — and the schema is required lazily by the callback rather than at module load. Handingcompiler.validatea pre-compiled check, soschema-utilsand ajv are not loaded for valid options, is left to a follow-up PR.Two fallbacks, both marked
TODOto remove in the next major release:hooks.validatebefore it appliesoptimization.minimizer, so that hook reaches this plugin only where it sits inplugins.initializeis tapped alongside it, behind a latch, so the minimizer placement is validated too.compiler.validate, and validates withschema-utilsdirectly.Measured against a real webpack build, n=7 per arm, medians with ranges; retained heap read after forced GC:
require()the plugin[389-482][390-446]validate: falsesetup[411-439][292-328]validate: falseajv modules / require.cache / retained heapRequiring the plugin is faster because
options.jsonis 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 isvalidate: 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.jsdrives real compilers throughout, and adds a case for theoptimization.minimizerplacement. No unit tests: the pre-5.106schema-utilsfallback is therefore not covered by any test, since the matrix only runswebpack-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: falsenow 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, initializefor thepluginsplacement andinitializeonly foroptimization.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.