Skip to content

feat: an empty minify list, and deleting an original alone - #743

Merged
alexander-akait merged 7 commits into
mainfrom
feat/generator-delete-and-empty-minify
Sep 19, 2026
Merged

alexander-akait merged 7 commits into
mainfrom
feat/generator-delete-and-empty-minify

Conversation

@alexander-akait

@alexander-akait alexander-akait commented Sep 18, 2026

Copy link
Copy Markdown
Member

Summary

The work that missed #742 — it was merged at 214b37e, and these five commits landed on the branch after that.

Deleting an original now takes that file and nothing else. webpack deletes whatever an asset's related names along with it, so deleteOriginalAssets took the source map, and the file a second generator wrote beside the same original, with it — which is how a gzip instance destroys a brotli one's output (webpack/compression-webpack-plugin#245, webpack/compression-webpack-plugin#389). It also takes a function now, asked per asset.

minify: [] is nothing to minify, for an instance whose whole job is its generate. A list with none in it needs no guard anywhere the minimizers are run — each pass simply does nothing — while a second kind of value would, which is why false stays out. Such an instance salts no chunk hash either: it rewrites nothing, so the bundle keeps the name it would have had without it.

Two more from the same work. A file written under the original's own name has replaced it, so relatedName is not recorded there — doing so wrote the source back over what was just generated. And filename takes a function, which is what webpack's own getPath accepts and what compression-webpack-plugin has always documented; minify's public type now says what the schema has taken since 5.10 — a list or a descriptor, not one function.

What kind of change does this PR introduce?

feat.

Did you add tests for your changes?

Yes, nine in test/generate-option.test.js: the source map and a sibling generator's file surviving a delete, a function deciding which to delete, a file written under the original's name kept and pointing nowhere, a filename function, an empty minify minifying nothing and renaming nothing, and the validation case for minify: []. 719 green.

Does this PR introduce a breaking change?

No. One behaviour narrows: deleteOriginalAssets: true no longer deletes files named in the deleted asset's related info. That was the bug above.

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

Documented here: minify's empty list, the generator's deleteOriginalAssets function form and what deletion takes, the filename function, in-place generation, and a new "Compressing with minifying, and without" section under compress.

Use of AI

Claude Code was used for the implementation, tests and this description. The related cascade was found by running both compression-webpack-plugin implementations over the same fixtures: gzip plus brotli with deleteOriginalAssets: true emits no .br files at all today.


Generated by Claude Code

Summary by CodeRabbit

  • New Features
    • minify: [] can skip minification while still running asset generation.
    • Generator filenames can be determined dynamically.
    • Original-asset deletion can be selected per asset.
    • Added minimizer descriptors with custom options and filters.
    • Added generator controls for thresholds, minimum ratios, and related asset naming.
  • Documentation
    • Expanded guidance and examples for generation, compression, minification, and asset deletion.
  • Type Improvements
    • Updated public types and validation for the expanded configuration options.

The asset it read goes alone, so a source map or another generator's file beside it stays, and a function decides per asset which of them to delete.
For an instance whose whole job is its generate. A list with none in it needs no guard where a second kind of value would, which is why false stays out.
An instance whose whole job is its generate rewrote no bytes, so the bundle kept its own name; and a file written under the original's name has replaced it, so recording related there wrote the source back over it.
…yped as written

The public type said one function where the schema has taken a list or a descriptor since 5.10, and a filename function is what webpack's own getPath takes.
The two shapes a compression instance is written in, now that an empty list of minimizers says the second one.
@changeset-bot

changeset-bot Bot commented Sep 18, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 66300f9

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

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

Click here to learn what changesets are, and how to add one.

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

@codecov

codecov Bot commented Sep 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.75%. Comparing base (816e5b8) to head (66300f9).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #743      +/-   ##
==========================================
+ Coverage   97.73%   97.75%   +0.01%     
==========================================
  Files           4        4              
  Lines        1545     1557      +12     
  Branches      574      582       +8     
==========================================
+ Hits         1510     1522      +12     
  Misses         35       35              

☔ 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.

@coderabbitai

coderabbitai Bot commented Sep 18, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 88b2f7db-a486-4aa6-a979-1cc5ea1d3f81

📥 Commits

Reviewing files that changed from the base of the PR and between 70c42d9 and 66300f9.

📒 Files selected for processing (2)
  • src/index.js
  • test/generate-option.test.js

Included review availability: Your plan provides up to 4 included reviews per hour; 3 remain after this review.


Walkthrough

The plugin now accepts minify: [] to disable minification while keeping asset generation active. Generator filename and deleteOriginalAssets options accept functions. Deletion preserves related assets and avoids deleting assets overwritten by another generator. New minimizer descriptor types are documented and exported. Schema, TypeScript declarations, README content, changeset text, and tests now cover these behaviors.

Priority: ⬇️ Low

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely identifies the two primary changes: support for an empty minify list and deletion of the original asset alone.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 5…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Warning

Some tools did not complete. Review the errors below.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

src/index.js

ESLint failed to execute (timeout).

test/generate-option.test.js

ESLint skipped: the matched ESLint configuration already failed (timeout).


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to GitHub limitations.

⚠️ Outside diff range comments (1)

🟠 Major · Do not salt embedded-source hashes when no minimizers run. · index.js:2436-2439

src/index.js:2436-2439
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not salt embedded-source hashes when no minimizers run.

With minify: [], renderEmbeddedSource returns the original source because no minimizer matches. The registered embeddedSourceHash tap still adds "TerserPlugin" and data to the module hash. Webpack can therefore change content hashes and derived filenames even though this plugin does no minification, contrary to the documented no-hash-change behavior.

Apply the same zero-minimizer guard to embeddedSourceHash, or do not register the embedded-source hooks when this.minimizers().length === 0.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 4f028e98-306d-4bd5-80f4-1b1a39b6aa6d

📥 Commits

Reviewing files that changed from the base of the PR and between 816e5b8 and bddb808.

⛔ Files ignored due to path filters (1)
  • test/__snapshots__/validate-options.test.js.snap is excluded by !**/*.snap
📒 Files selected for processing (7)
  • .changeset/generator-compression-options.md
  • README.md
  • src/index.js
  • src/options.json
  • test/generate-option.test.js
  • test/validate-options.test.js
  • types/index.d.ts

Included review availability: Your plan provides up to 4 included reviews per hour; 3 remain after this review.

The tap varies a module's hash on the minimizers, so an instance with none of them renamed files it never rewrote — the same defect the chunk hash had.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to GitHub limitations.

⚠️ Outside diff range comments (1)

🟠 Major · Delete only the captured original asset. · index.js:1785

src/index.js:1785
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Delete only the captured original asset.

generateAssets runs all generators concurrently. A same-name generator can replace name before a differently named generator reaches this branch. The current getAsset(name) check then overwrites and deletes that replacement.

Compare the current source with the captured source before updating and deleting:

const current = compilation.getAsset(name);

if (
  generatedName !== name &&
  current &&
  current.source === source
) {

Add a regression test with one same-name generator and one differently named generator. Assert that the same-name replacement remains.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 5612b384-5047-4e34-b03f-e43a6a3b224b

📥 Commits

Reviewing files that changed from the base of the PR and between bddb808 and 70c42d9.

📒 Files selected for processing (2)
  • src/index.js
  • test/embedded-source.test.js

Included review availability: Your plan provides up to 4 included reviews per hour; 3 remain after this review.

The generators of a pass run together, so another may have written over the original first — deleting then destroys that file instead.
@alexander-akait
alexander-akait merged commit c69dae3 into main Sep 19, 2026
31 checks passed
@alexander-akait
alexander-akait deleted the feat/generator-delete-and-empty-minify branch September 19, 2026 12:52
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