Skip to content

fix: invalidate the pack when the generator changes - #722

Merged
alexander-akait merged 2 commits into
mainfrom
fix/generate-cache-version
Sep 5, 2026
Merged

fix: invalidate the pack when the generator changes#722
alexander-akait merged 2 commits into
mainfrom
fix/generate-cache-version

Conversation

@alexander-akait

Copy link
Copy Markdown
Member

Summary

generate rewrites a module's own build result, and the filesystem cache restores that result without rebuilding the module — so changing generate or generatorOptions changed nothing. Reproduced: a second run configured for avif emitted image.webp with the first run's bytes and never called the new generator. Silent, and only deleting the cache directory recovered.

Nothing per-module keys on a plugin, so the generator's identity goes into cache.version. Identity is the implementation's source rather than getMinimizerVersion, since a generator already travels to a worker as source and a custom one reports no version. This reaches the cache only from a configured plugin — plugins or optimization.minimizer — because webpack builds the cache strategy while it applies those; the README says so.

Based on #721 rather than main: the README paragraph this extends is added there. Please merge that one first.

What kind of change does this PR introduce?

fix

Did you add tests for your changes?

Yes — test/generate-filesystem-cache.test.js, four cases across two compiler runs sharing a cache directory. The rename surviving a restore (with the module asserted cached, not built) and changed bytes re-encoding both pass without the fix; a changed generator and changed generatorOptions both fail without it.

Does this PR introduce a breaking change?

No. A pack written before this is invalidated once, since the version it was written under no longer matches.

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

Documented here, in the generate section: that the pack is invalidated by a changed generator, and that the plugin has to be in the config for it to be — a plugin applied by hand after webpack() returns is too late.

Use of AI

Claude Code found and fixed this. It went looking after the tests in #721 closed the watch-mode gap, first ruling out the canonical defect by running three builds under infrastructureLogging.debug and confirming zero Pack got invalid because of write to: lines with the probe shown to be capturing output. The bug then surfaced on the next hypothesis. Its first probe missed it — two generators built by the same factory had identical source and differed only by closure, which is also what settled on source as the identity — and the fix was confirmed by A/B on one probe with nothing else changed. Reading webpack's own ordering is what established the plugins requirement, after the first version of the test applied the plugin post-construction and failed.


🤖 Generated with Claude Code

https://claude.ai/code/session_016TQeNpahUSDUjD2Crugy5H


Generated by Claude Code

@changeset-bot

changeset-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 8aa3bfa

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 Patch

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

`generate` rewrites a module's own build result, and the filesystem cache
restores that result without rebuilding the module -- so changing `generate`
or `generatorOptions` changed nothing. The pack kept answering with the
previous generator's bytes and its name, and only deleting the cache
directory recovered. Reproduced: a second run configured for `avif` emitted
`image.webp` with the first run's bytes and never called the new generator.

Nothing per-module keys on a plugin, so the generator's identity goes into
`cache.version` instead. Identity is the implementation's source rather than
`getMinimizerVersion`, since a generator already travels to a worker as
source and a custom one reports no version. This reaches the cache only from
a configured plugin -- `plugins` or `optimization.minimizer` -- because
webpack builds the cache strategy while it applies those; the README says so.

Three cases cover it, in a new file: the rename surviving a restore (with the
module asserted `cached`, not `built`), changed bytes re-encoding, and a
changed generator or changed options re-running. The first two pass without
the fix; the last two fail.
@alexander-akait
alexander-akait force-pushed the fix/generate-cache-version branch from 650bb5e to dd939bd Compare September 4, 2026 15:01
@alexander-akait
alexander-akait changed the base branch from test/generate-option-coverage to main September 4, 2026 15:01
`generate` takes an array, and the identity the pack's version carries reads
one — but nothing drove that branch, so it sat at 0 hits while the single
generator path had 4. Same two-run shape as the other cases: an array of one
generator, then an array naming a different one, which has to re-encode.
@codecov

codecov Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.88%. Comparing base (cc1f712) to head (8aa3bfa).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #722      +/-   ##
==========================================
+ Coverage   94.73%   94.88%   +0.14%     
==========================================
  Files           4        4              
  Lines        1102     1114      +12     
  Branches      386      391       +5     
==========================================
+ Hits         1044     1057      +13     
+ Misses         51       50       -1     
  Partials        7        7              

☔ 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 merged commit 5342acc into main Sep 5, 2026
55 of 56 checks passed
@alexander-akait
alexander-akait deleted the fix/generate-cache-version branch September 5, 2026 11:41
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