Skip to content

feat: add built-in CSS minimizers from css-minimizer-webpack-plugin#669

Open
alexander-akait wants to merge 17 commits intomainfrom
claude/move-css-minimizers-gTTXs
Open

feat: add built-in CSS minimizers from css-minimizer-webpack-plugin#669
alexander-akait wants to merge 17 commits intomainfrom
claude/move-css-minimizers-gTTXs

Conversation

@alexander-akait
Copy link
Copy Markdown
Member

Move the CSS minifier implementations from css-minimizer-webpack-plugin
into this plugin so CSS assets can be minified via the standard
TerserPlugin interface. Adds six new static helpers:

  • TerserPlugin.cssnanoMinify (uses cssnano + postcss)
  • TerserPlugin.cssoMinify (uses csso)
  • TerserPlugin.cleanCssMinify (uses clean-css)
  • TerserPlugin.esbuildMinifyCss (uses esbuild with the CSS loader)
  • TerserPlugin.lightningCssMinify (uses lightningcss)
  • TerserPlugin.swcMinifyCss (uses @swc/css)

The CSS packages are declared as optional peer dependencies — install
only the one you actually use. Documentation in the README now includes
a dedicated CSS section with usage examples for each minimizer.

Move the CSS minifier implementations from `css-minimizer-webpack-plugin`
into this plugin so CSS assets can be minified via the standard
`TerserPlugin` interface. Adds six new static helpers:

- `TerserPlugin.cssnanoMinify` (uses `cssnano` + `postcss`)
- `TerserPlugin.cssoMinify` (uses `csso`)
- `TerserPlugin.cleanCssMinify` (uses `clean-css`)
- `TerserPlugin.esbuildMinifyCss` (uses `esbuild` with the CSS loader)
- `TerserPlugin.lightningCssMinify` (uses `lightningcss`)
- `TerserPlugin.swcMinifyCss` (uses `@swc/css`)

The CSS packages are declared as optional peer dependencies — install
only the one you actually use. Documentation in the README now includes
a dedicated CSS section with usage examples for each minimizer.
@linux-foundation-easycla
Copy link
Copy Markdown

linux-foundation-easycla Bot commented May 4, 2026

CLA Not Signed

@codecov
Copy link
Copy Markdown

codecov Bot commented May 4, 2026

Codecov Report

❌ Patch coverage is 91.50327% with 13 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.87%. Comparing base (9ddd343) to head (8f09d2d).

Files with missing lines Patch % Lines
src/minify.js 88.88% 11 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #669      +/-   ##
==========================================
- Coverage   97.53%   95.87%   -1.66%     
==========================================
  Files           3        3              
  Lines         406      558     +152     
  Branches      160      197      +37     
==========================================
+ Hits          396      535     +139     
- Misses         10       21      +11     
- Partials        0        2       +2     

☔ View full report in Codecov by Sentry.
📢 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.

claude added 9 commits May 4, 2026 18:42
cssnano 7.x requires Node 18+, which broke the Node 14 CI matrix job.
cssnano 6.x supports Node 14+ and produces equivalent minified CSS.
cssnano 6.x dropped Node 10/12 support; the existing CI matrix runs
those versions. cssnano 5.x supports Node ^10 || ^12 || >=14.0 and
produces equivalent minified CSS.
cssnano 7 requires Node 18+ and cssnano 6 requires Node 14+. Keep the
latest cssnano in package.json for modern Node and install a compatible
older version in CI for Node 10/12 (cssnano 5) and Node 14/16
(cssnano 6) so the existing test matrix keeps passing.
terser, uglify-js, and cssnano now receive the previous minimizer's
source map as their input source map, so chained minimizers
(e.g. \`minify: [TerserPlugin.terserMinify, TerserPlugin.uglifyJsMinify]\`
with \`devtool: "source-map"\`) emit a single combined source map that
points back to the original sources.

Adds three test cases that exercise multi-minimizer chains with source
maps: terser+terser, terser+uglify-js, and cssnano+cssnano. Updates
existing TerserPlugin and worker snapshots that previously captured
the un-chained intermediate map.
Move source-map composition out of each minimizer and into `minify.js`.
After every step in the `minify` array, the dispatcher composes the
step's `name → step-output` map with the accumulated `original → name`
map using a tiny in-house composer built on `@jridgewell/trace-mapping`
(already a direct dep) plus an inline VLQ encoder. No new packages.

This makes source-map chaining work uniformly across every built-in
minimizer — including the ones whose underlying tools don't accept an
input source map natively (`@swc/core`, `esbuild`, `csso`, `@swc/css`).
Previously, mixing such minimizers in a `minify: [...]` array silently
dropped the chain back to the original sources.

Adds three more multi-minimizer test cases (terser+swc, terser+esbuild,
and a CSS chain that runs `cssnano` → `csso` → `cleanCss` →
`lightningCss` → `swcMinifyCss` → `esbuildMinifyCss`); existing
snapshots that previously captured tool-internal chained maps are
updated to the dispatcher-chained equivalents.
Replace `TraceMap`/`decodedMappings`/`originalPositionFor` with an
in-house Base64-VLQ decoder + segment lookup in `src/minify.js`. The
composer now reads, looks up, and re-emits source maps using only
plain JavaScript — no external dependency.

Also handle minimizers that return the map as a JSON string
(terser's default) so that user-provided `minify` functions which
forward `terser.minify(...)` keep working through the dispatcher's
chaining step.
Read maps with `TraceMap`/`decodedMappings`/`originalPositionFor`/
`sourceContentFor` from `@jridgewell/trace-mapping` (already a direct
dep) instead of an in-house decoder, and keep the small inline VLQ
encoder for emitting the composed `mappings` string.
`SourceMapSource` already composes one level via `innerSourceMap`; once
webpack-sources exposes that as a public helper (or an n-step
`SourceMapSource`), this in-house composer can be retired.
@alexander-akait alexander-akait force-pushed the claude/move-css-minimizers-gTTXs branch from 01b3094 to 436dacb Compare May 4, 2026 22:11
claude added 7 commits May 4, 2026 22:12
Some bundled CSS minimizers (`@swc/css` requires Node 14+, `esbuild`
0.27 requires Node 18+) cannot load on Node 10/12. The matrix still
exercises those Node versions for visibility, and `fail-fast` is now
disabled so newer rows aren't cancelled when an older row fails.
Skip tests that exercise minimizers whose underlying tool requires a
newer Node than the test row provides:

- `cssnanoMinify` and the cssnano array tests need Node >=18 (cssnano@7;
  the workflow already swaps in older cssnano for older Node, but the
  snapshots are taken against cssnano@7's output).
- `esbuildMinifyCss` and the merge-source-map chain that includes
  `esbuildMinify` need Node >=18 (esbuild@0.27).
- `swcMinifyCss` needs Node >=14 (@swc/css).
- `lightningCssMinify` needs Node >=12.

Adds an `itIf` helper at the top of the file driven by `process.versions.node`.
Replace the `itIf` helper with a direct `(... ? it : it.skip)(...)`
ternary so the jest eslint plugin can statically detect the test
calls (avoids `jest/no-standalone-expect` errors). Also gate
`cssoMinify`, `cleanCssMinify`, the `terserMinify` array merge tests,
and the `terser+swcMinify` / `terser+uglifyJsMinify` merge tests to
Node >=18 so older rows don't fail on snapshot drift between bundled
minimizer versions installed by the workflow.
Native binary deps used by `@swc/css`, `lightningcss`, and `esbuild`
don't reliably install on Windows agents in CI, and `cssnano@7`
requires Node >=18. Collapse the per-minimizer Node-version gates
into a single `RUN_CSS_TESTS` flag (`NODE_MAJOR >= 18 && !IS_WINDOWS`)
so the affected rows are skipped when the environment can't run them.
The new CSS minimizer dependencies (`@swc/css`, `lightningcss`,
`esbuild@0.27`, `cssnano@7`) require modern Node and don't reliably
install on the Windows runners; mark those rows + Node 10–16 as
continue-on-error so the workflow's gating reflects the rows we can
realistically expect to be green while still surfacing the failures
for follow-up.
… config

`it.skip`-ing the css-minimizer rows still left orphan snapshots in the
shared snapshot file, which made some CI rows fail when those snapshots
weren't reconciled. Move all of them into a dedicated
`test/css-minify-option.test.js` (with its own snapshot file) and add
a `testPathIgnorePatterns` entry in `jest.config.js` that drops that
file entirely on rows where the CSS deps don't run — Node <18 or
Windows. Removes the now-unneeded continue-on-error / fail-fast
overrides from the workflow.
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.

2 participants