Repository navigation
feat(css): join adjacent rules and fold four more value spellings - #21648
Conversation
🦋 Changeset detectedLatest commit: 09aa8a2 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 |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
Note
|
| Layer / File(s) | Summary |
|---|---|
CSS metadata generation lib/css/data.js, tooling/generate-css-data.js, test/CssValueSyntax.unittest.js |
Adds grammar-derived shorthand, gradient, alpha, ratio, and mergeable at-rule metadata with validation helpers and tests. |
Minification and output processing lib/css/syntax.js, lib/util/SourceProcessor.js, lib/css/cssMinify.js, types.d.ts |
Adds CSS value transforms, safe data-URI decoding, gradient folding, buffered rule merging, cascade-aware declaration handling, and replacement-text printer operations. |
Environment capability wiring declarations/WebpackOptions.d.ts, schemas/WebpackOptions.json, lib/config/*, test/Defaults.unittest.js, test/configCases/ecmaVersion/*, test/configCases/css/minimize-environment/* |
Adds cssGradientDoublePosition to public options, browser target detection, defaults, minimizer configuration, and snapshots. |
Behavior validation and release metadata test/CssSyntax.unittest.js, test/SyntaxBrowserEquivalence.unittest.js, test/configCases/css/*, .changeset/* |
Adds unit, equivalence, nesting, URL, shorthand, gradient, selector, and rule-merging coverage. Updates changesets. |
🚥 Pre-merge checks | ✅ 3 | ❌ 1
❌ Failed checks (1 inconclusive)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Title check | ❓ Inconclusive | The title uses valid Conventional Commit syntax and describes the CSS rule joining and value-folding changes, but the branch prefix is not provided. | Provide the branch name or confirm that its prefix is feat so the required type-prefix match can be verified. |
✅ Passed checks (3 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| 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. |
Comment @coderabbitai help to get the list of available commands.
|
This PR is packaged and the instant preview is available (3197f80). Install it locally:
npm i -D webpack@https://pkg.pr.new/webpack@3197f80
yarn add -D webpack@https://pkg.pr.new/webpack@3197f80
pnpm add -D webpack@https://pkg.pr.new/webpack@3197f80 |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #21648 +/- ##
==========================================
+ Coverage 94.40% 94.44% +0.03%
==========================================
Files 628 628
Lines 80618 81097 +479
Branches 23812 23998 +186
==========================================
+ Hits 76108 76592 +484
+ Misses 4510 4505 -5
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Generated code sizeComparing
140 asset(s) changed size, biggest 20 by raw change
1 runtime(s) changed which runtime modules they carry
Built |
Merging this PR will improve performance by 43.98%
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ⚡ | Memory | benchmark "devtool-eval", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' |
949.8 KB | 470.4 KB | ×2 |
| ⚡ | Memory | benchmark "future-defaults", scenario '{"name":"mode-production","mode":"production"}' |
10.2 MB | 8.4 MB | +21.79% |
| ⚡ | Memory | benchmark "css-modules", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' |
917.6 KB | 756 KB | +21.37% |
Tip
Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.
Comparing feat/css-minify-value-and-url-transforms (09aa8a2) with main (5c5d009)
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (6)
test/CssSyntax.unittest.js (2)
2393-2403: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueGive this block a distinct title.
Line 2401 uses the title template
"keeps both rules where %s". Line 2318 already uses the same template in the samedescribe. Two cases can then report identical names. Rename the second block to name the nesting condition.♻️ Proposed rename
- ])("keeps both rules where %s", (_name, css) => { + ])("keeps both nested rules where %s", (_name, css) => {
2167-2169: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueTwo new inline comments exceed the comment-length limit. The guideline allows one line, and two short lines at most. Both comments span three lines.
test/CssSyntax.unittest.js#L2167-L2169: shorten the<bg-image>slot explanation to two short lines.test/SyntaxBrowserEquivalence.unittest.js#L1024-L1026: shorten the adjacent-repeat explanation to two short lines.As per coding guidelines: "Keep comments as short as possible, generally one line and no more than two short lines; comments must add non-obvious information and must not narrate or restate code."
Source: Coding guidelines
test/configCases/css/minimize-nesting/webpack.config.js (1)
25-25: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse the specific
CompilerJSDoc type.
EXPECTED_ANYdisables type checking at theMinimizerPlugin.applyboundary. Replace it withimport("../../../../").Compiler, if that type is compatible with the installed plugin declaration.Proposed change
- }).apply(/** `@type` {EXPECTED_ANY} */ (compiler)); + }).apply(/** `@type` {import("../../../../").Compiler} */ (compiler));As per coding guidelines, use
EXPECTED_ANYonly when a precise type is genuinely unavailable.Source: Coding guidelines
lib/css/syntax.js (3)
6643-6653: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueUse the
CC_character-code constants.This loop compares against the numeric literals
0x28and0x29. The file names character codes elsewhere, for exampleCC_SEMICOLONat Line 7964 andCC_QUOTATION_MARKat Line 5739. Use the same named constants for(and)if they exist in this module.
7646-7653: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winChain the two gradient transforms instead of returning after the first.
_dropDefaultGradientDirectionreturns as soon as it changes anything, so_foldGradientStopsnever runs on the same value. Forlinear-gradient(to bottom,red,blue 100%)the default direction is dropped and the redundant100%is kept, because the printer visits the node once.Feed the first result into the second.
♻️ Proposed change
- const gradient = _dropDefaultGradientDirection(fn, inner); - if (gradient !== null) return `${name}(${gradient})`; - const stops = _foldGradientStops( - fn, - inner, - _doublePositionAllowed(writer) - ); - if (stops !== null) return `${name}(${stops})`; + const gradient = _dropDefaultGradientDirection(fn, inner); + const args = gradient === null ? inner : gradient; + const stops = _foldGradientStops( + fn, + args, + _doublePositionAllowed(writer) + ); + if (stops !== null) return `${name}(${stops})`; + if (gradient !== null) return `${name}(${gradient})`;
7934-7952: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low valueSkip the allocation when the rule cannot contain a duplicate.
supersededandseenare allocated for every minified rule, including the many rules that hold zero or one item. The printer runs once per rule, so this is a hot path.Guard both allocations on
items.length >= 2.♻️ Proposed change
/** `@type` {Set<number> | null} */ let superseded = null; - if (minify) { + if (minify && items.length >= 2) { superseded = new Set();As per coding guidelines: "Evaluate time and memory costs of changes, especially on hot paths."
Source: Coding guidelines
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: c712655c-bff0-4d71-97b3-38d41f76d8b1
⛔ Files ignored due to path filters (18)
test/__snapshots__/Cli.basictest.js.snapis excluded by!**/*.snaptest/__snapshots__/target-browserslist.unittest.js.snapis excluded by!**/*.snaptest/configCases/css/minimize-colors/__snapshots__/ConfigCacheTest.snapis excluded by!**/*.snaptest/configCases/css/minimize-colors/__snapshots__/ConfigTest.snapis excluded by!**/*.snaptest/configCases/css/minimize-declined/__snapshots__/ConfigCacheTest.snapis excluded by!**/*.snaptest/configCases/css/minimize-declined/__snapshots__/ConfigTest.snapis excluded by!**/*.snaptest/configCases/css/minimize-environment/__snapshots__/ConfigCacheTest.snapis excluded by!**/*.snaptest/configCases/css/minimize-environment/__snapshots__/ConfigTest.snapis excluded by!**/*.snaptest/configCases/css/minimize-nesting/__snapshots__/ConfigCacheTest.snapis excluded by!**/*.snaptest/configCases/css/minimize-nesting/__snapshots__/ConfigTest.snapis excluded by!**/*.snaptest/configCases/css/minimize-selectors/__snapshots__/ConfigCacheTest.snapis excluded by!**/*.snaptest/configCases/css/minimize-selectors/__snapshots__/ConfigTest.snapis excluded by!**/*.snaptest/configCases/css/minimize-shorthands/__snapshots__/ConfigCacheTest.snapis excluded by!**/*.snaptest/configCases/css/minimize-shorthands/__snapshots__/ConfigTest.snapis excluded by!**/*.snaptest/configCases/css/minimize-urls/__snapshots__/ConfigCacheTest.snapis excluded by!**/*.snaptest/configCases/css/minimize-urls/__snapshots__/ConfigTest.snapis excluded by!**/*.snaptest/configCases/css/minimize-values/__snapshots__/ConfigCacheTest.snapis excluded by!**/*.snaptest/configCases/css/minimize-values/__snapshots__/ConfigTest.snapis excluded by!**/*.snap
📒 Files selected for processing (38)
.changeset/070-css-html-minify-transforms.md.changeset/075-css-join-adjacent-rules.mddeclarations/WebpackOptions.d.tslib/config/browserslistTargetHandler.jslib/config/defaults.jslib/config/target.jslib/css/cssMinify.jslib/css/data.jslib/css/syntax.jslib/util/SourceProcessor.jsschemas/WebpackOptions.check.jsschemas/WebpackOptions.jsontest/CssSyntax.unittest.jstest/CssValueSyntax.unittest.jstest/Defaults.unittest.jstest/SyntaxBrowserEquivalence.unittest.jstest/configCases/css/minimize-declined/style.csstest/configCases/css/minimize-environment/style.csstest/configCases/css/minimize-environment/webpack.config.jstest/configCases/css/minimize-nesting/index.jstest/configCases/css/minimize-nesting/style.csstest/configCases/css/minimize-nesting/test.config.jstest/configCases/css/minimize-nesting/webpack.config.jstest/configCases/css/minimize-selectors/style.csstest/configCases/css/minimize-shorthands/style.csstest/configCases/css/minimize-urls/style.csstest/configCases/css/minimize-values/style.csstest/configCases/ecmaVersion/browserslist-config-env-extends/webpack.config.jstest/configCases/ecmaVersion/browserslist-config-env/webpack.config.jstest/configCases/ecmaVersion/browserslist-config-extends/webpack.config.jstest/configCases/ecmaVersion/browserslist-config/webpack.config.jstest/configCases/ecmaVersion/browserslist-env/webpack.config.jstest/configCases/ecmaVersion/browserslist-extends/webpack.config.jstest/configCases/ecmaVersion/browserslist-query-with-config-file/webpack.config.jstest/configCases/ecmaVersion/browserslist-query/webpack.config.jstest/configCases/ecmaVersion/browserslist/webpack.config.jstooling/generate-css-data.jstypes.d.ts
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
webpack/schema-utils(auto-detected)webpack/tapable(auto-detected)
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
lib/css/syntax.js (2)
6612-6613: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueUse full identifier names.
Rename
fnandoutto names such asfunctionNameandreducedFunction.As per coding guidelines, “Spell function, variable, parameter, and property names out in full.”
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lib/css/syntax.js` around lines 6612 - 6613, In _reduceTransformFunctionDeep, rename the abbreviated parameter fn and local variable out to full descriptive identifiers such as functionName and reducedFunction, updating all references while preserving the existing behavior.Source: Coding guidelines
6575-6577: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueShorten these source comments.
lib/css/syntax.js#L6575-L6577: Reduce the comment to one or two short lines.lib/css/syntax.js#L6588-L6590: Reduce the comment to one or two short lines.lib/css/syntax.js#L6605-L6607: Reduce the comment to one or two short lines.lib/css/syntax.js#L6660-L6662: Reduce the comment to one or two short lines.As per coding guidelines, comments must generally use one line and no more than two short lines.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lib/css/syntax.js` around lines 6575 - 6577, Shorten the source comments at lib/css/syntax.js lines 6575-6577, 6588-6590, 6605-6607, and 6660-6662 to one or two concise lines while preserving their essential clarification.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@lib/css/syntax.js`:
- Around line 6593-6597: Update the layer transformation in the relevant
background/mask size parser so it removes the trailing auto only when the first
token is a valid size value; preserve cover, contain, and CSS-wide keywords such
as initial as invalid two-token declarations. Add regression cases covering
these inputs and verify invalid declarations are not reduced to valid one-token
values.
---
Nitpick comments:
In `@lib/css/syntax.js`:
- Around line 6612-6613: In _reduceTransformFunctionDeep, rename the abbreviated
parameter fn and local variable out to full descriptive identifiers such as
functionName and reducedFunction, updating all references while preserving the
existing behavior.
- Around line 6575-6577: Shorten the source comments at lib/css/syntax.js lines
6575-6577, 6588-6590, 6605-6607, and 6660-6662 to one or two concise lines while
preserving their essential clarification.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 4f06609a-3f94-4f1a-bdcd-f2165ba0a0a8
⛔ Files ignored due to path filters (2)
test/configCases/css/minimize-values/__snapshots__/ConfigCacheTest.snapis excluded by!**/*.snaptest/configCases/css/minimize-values/__snapshots__/ConfigTest.snapis excluded by!**/*.snap
📒 Files selected for processing (4)
.changeset/070-css-html-minify-transforms.mdlib/css/syntax.jstest/CssSyntax.unittest.jstest/configCases/css/minimize-values/style.css
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
webpack/schema-utils(auto-detected)webpack/tapable(auto-detected)
🚧 Files skipped from review as they are similar to previous changes (1)
- .changeset/070-css-html-minify-transforms.md
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
lib/css/syntax.js (1)
8058-8062: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winPreserve kept comments at the full custom-property value boundaries.
fromandtoexclude comment-only gaps before the first token and after the last token. A kept/*!…*/comment in either gap remains queued and can be emitted after the enclosing rule instead of inside--x.Pass the complete declaration-value span to
_customPropertyValue. Add regression cases for--x:/*!keep*/fooand--x:foo/*!keep*/.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lib/css/syntax.js` around lines 8058 - 8062, Update the custom-property handling around _customPropertyValue to pass the complete declaration-value span, including comment-only gaps before the first child and after the last child, rather than boundaries derived solely from children. Preserve the non-minified slicing behavior as appropriate, and add regression coverage for --x:/*!keep*/foo and --x:foo/*!keep*/ so kept comments remain inside the custom-property value.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@lib/css/syntax.js`:
- Around line 8058-8062: Update the custom-property handling around
_customPropertyValue to pass the complete declaration-value span, including
comment-only gaps before the first child and after the last child, rather than
boundaries derived solely from children. Preserve the non-minified slicing
behavior as appropriate, and add regression coverage for --x:/*!keep*/foo and
--x:foo/*!keep*/ so kept comments remain inside the custom-property value.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: ad9eb090-5137-4668-878c-fb1d47c11e6e
⛔ Files ignored due to path filters (4)
test/configCases/css/minimize-selectors/__snapshots__/ConfigCacheTest.snapis excluded by!**/*.snaptest/configCases/css/minimize-selectors/__snapshots__/ConfigTest.snapis excluded by!**/*.snaptest/configCases/css/minimize-values/__snapshots__/ConfigCacheTest.snapis excluded by!**/*.snaptest/configCases/css/minimize-values/__snapshots__/ConfigTest.snapis excluded by!**/*.snap
📒 Files selected for processing (10)
.changeset/070-css-html-minify-transforms.mdlib/css/data.jslib/css/syntax.jslib/util/SourceProcessor.jstest/CssSyntax.unittest.jstest/CssValueSyntax.unittest.jstest/configCases/css/minimize-selectors/style.csstest/configCases/css/minimize-values/style.csstooling/generate-css-data.jstypes.d.ts
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
webpack/schema-utils(auto-detected)webpack/tapable(auto-detected)
🚧 Files skipped from review as they are similar to previous changes (5)
- lib/util/SourceProcessor.js
- types.d.ts
- .changeset/070-css-html-minify-transforms.md
- lib/css/data.js
- test/configCases/css/minimize-selectors/style.css
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
tooling/generate-css-data.js (1)
792-794: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueShorten this comment.
Use no more than two short lines for this comment.
Proposed change
- // A grammar naming its slots by type rather than by property: the slot - // is the longhand whose own value is exactly that type, followed - // through the `<'other'>` some of them are stated as. + // Match a type slot to the unique longhand whose complete value has that type. + // Follow a `<'other'>` reference before matching.As per coding guidelines, "
{lib,hot,tooling,test}/**/*.{js,mjs}: Keep comments as short as possible, generally one line and no more than two short lines; comments must add non-obvious information and must not narrate or restate code."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tooling/generate-css-data.js` around lines 792 - 794, Shorten the comment near the grammar slot handling to no more than two brief lines, retaining only the non-obvious explanation that the slot is the longhand whose value matches the grammar type.Source: Coding guidelines
test/SyntaxBrowserEquivalence.unittest.js (1)
432-435: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winShorten the changed comments.
Reduce these comments to no more than two short lines each. Keep only the cascade behavior that is not clear from the code.
As per coding guidelines, “Keep comments as short as possible, generally one line and no more than two short lines; comments must add non-obvious information and must not narrate or restate code.”
Also applies to: 443-447
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@test/SyntaxBrowserEquivalence.unittest.js` around lines 432 - 435, Shorten the comments around the selector cascade behavior near the existing probe explanation, including the related comment at the other referenced section, to no more than two short lines each. Retain only the non-obvious rule that later declarations win and !important declarations take precedence; remove narrative about joining blocks, text folding, or restating the code.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@test/SyntaxBrowserEquivalence.unittest.js`:
- Around line 439-441: Update the adjacent-rule equivalence check in walk() to
compare previous.chain and chain by their condition entries’ kind and condition
values rather than array identity. Preserve the existing previous and label
checks so equivalent adjacent conditional blocks are merged while distinct
chains remain separate.
---
Nitpick comments:
In `@test/SyntaxBrowserEquivalence.unittest.js`:
- Around line 432-435: Shorten the comments around the selector cascade behavior
near the existing probe explanation, including the related comment at the other
referenced section, to no more than two short lines each. Retain only the
non-obvious rule that later declarations win and !important declarations take
precedence; remove narrative about joining blocks, text folding, or restating
the code.
In `@tooling/generate-css-data.js`:
- Around line 792-794: Shorten the comment near the grammar slot handling to no
more than two brief lines, retaining only the non-obvious explanation that the
slot is the longhand whose value matches the grammar type.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 9b7d3494-f421-4bd8-b0f7-71446e2d34ae
⛔ Files ignored due to path filters (5)
lib/css/data.jsis excluded by!lib/css/data.jstest/configCases/css/minimize-selectors/__snapshots__/ConfigCacheTest.snapis excluded by!**/*.snap,!test/**/__snapshots__/**test/configCases/css/minimize-selectors/__snapshots__/ConfigTest.snapis excluded by!**/*.snap,!test/**/__snapshots__/**test/configCases/css/minimize-shorthands/__snapshots__/ConfigCacheTest.snapis excluded by!**/*.snap,!test/**/__snapshots__/**test/configCases/css/minimize-shorthands/__snapshots__/ConfigTest.snapis excluded by!**/*.snap,!test/**/__snapshots__/**
📒 Files selected for processing (8)
.changeset/075-css-join-adjacent-rules.mdlib/css/syntax.jstest/CssSyntax.unittest.jstest/CssValueSyntax.unittest.jstest/SyntaxBrowserEquivalence.unittest.jstest/configCases/css/minimize-selectors/style.csstest/configCases/css/minimize-shorthands/style.csstooling/generate-css-data.js
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
webpack/schema-utils(auto-detected)webpack/tapable(auto-detected)
🚧 Files skipped from review as they are similar to previous changes (3)
- test/configCases/css/minimize-selectors/style.css
- .changeset/075-css-join-adjacent-rules.md
- lib/css/syntax.js
1711e88 to
6a8cafe
Compare
Join adjacent qualified rules that share a selector, the blocks of two adjacent at-rules of one condition, and a border side's three longhands into its shorthand, each declining wherever the cascade could read the result differently. Fold a one-axis skew and rotation, an alpha percentage, a ratio's implied denominator, a gradient's defaulted stop positions and a data URI's needless escapes, and reduce a transform until it stops getting shorter.
6a8cafe to
09aa8a2
Compare
Summary
Continues the native CSS minifier's coverage of what the other minifiers ship, keeping webpack's rule that a rewrite must be equivalent to the engine. Measured over 18 real stylesheets (Bootstrap, Tailwind, Bulma, Foundation, UIkit, …): 4,519,478 → 4,505,803 raw / 540,124 → 539,417 gzip.
Structural: adjacent rules that print the same block join into one selector list, and adjacent at-rule blocks of one condition into one block — at every nesting depth, the rules the two blocks leave meeting at the seam joining the same way. Only where every selector is a shape each engine parses, since one it cannot invalidates the whole list. Rules a third stands between are still declined, that being a cascade reorder.
Values: a filter argument that is a zero carrying its unit; a data URI's payload written as the bytes its escapes name (outside that payload an escape is structure, so nothing else is touched); a shorthand slot holding its own initial where every value the slot takes is one the generated spellings report, not only where it takes keywords alone;
flex's shrink factor over a basis no factor can be read as; and a gradient's last color-stop position where CSS Images 3 §3.4.3's own fix-up already puts it. Two adjacent stops of one color become the one stop naming both, behind a newoutput.environment.cssGradientDoublePosition, which the browserslist target reports like the other CSS abilities.It also fixes a pre-existing bug the new nesting fixture caught: a declaration a nested rule parts from its repeat was dropped, losing a rule the engine builds.
What kind of change does this PR introduce?
feat
Did you add tests for your changes?
Yes — a new
test/configCases/css/minimize-nestingcase, plus fixtures inminimize-values,minimize-shorthands,minimize-urls,minimize-declinedandminimize-environment, and ~90 cases intest/CssSyntax.unittest.js. Every transform is also checked against headless Chromium bytest/SyntaxBrowserEquivalence.unittest.js, which must build the same rules in the same cascade order computing the same style from both spellings.Does this PR introduce a breaking change?
No.
output.environment.cssGradientDoublePositionis new and defaults to available, as the other CSS entries do.If relevant, what needs to be documented once your changes are merged or what have you already documented?
output.environment.cssGradientDoublePositionon theoutput.environmentpage, alongsidecssColorHexAlpha/cssInsetShorthand/cssMediaQueryRange.Use of AI
AI (Claude Code) was used to write the transforms, the generator's derivations and the tests, and to measure each change. No transform was kept on the model's word: every one had to pass the headless-Chromium equivalence suite, and every size claim in this description is a measured number over the 18-stylesheet corpus, reported whether or not it flattered the change — the gradient double-position fold is worth 16 raw bytes on it, and the seam join zero.
Generated by Claude Code
Summary by CodeRabbit
New Features
Bug Fixes