Skip to content

[CLOV-1637] Phase 2: add postcss mangle to shortcut names#4633

Open
IrinaWei wants to merge 1 commit into
phase2-themeable-property-no-fallback-declfrom
phase3-postcss-mangle
Open

[CLOV-1637] Phase 2: add postcss mangle to shortcut names#4633
IrinaWei wants to merge 1 commit into
phase2-themeable-property-no-fallback-declfrom
phase3-postcss-mangle

Conversation

@IrinaWei
Copy link
Copy Markdown
Contributor

@IrinaWei IrinaWei commented May 25, 2026

Summary

Stacked on top of #4630. Applies the third (and final) of three planned compression strategies for base.css, taking the bundle from ~9.77 KB → ~7.92 KB on top of the savings already landed in #4630.

Combined with the previous PR, base.css shrinks from ~15.5 KB (after the token block in #4492) to ~7.92 KB — about a 48.9% total reduction.

📦42.19.1-dev-v26387757985.1
image

Strategy 3: Mangle CSS custom property names via a PostCSS plugin

Backpack's CSS custom properties carry full semantic names (--bpk-private-button-colour-bg-primary, --bpk-typography-style-headline, …). Those names are great for authoring and debugging, but in the shipped bundle every byte counts: the segments private, colour, dimension, and typography repeat across most variables and account for a meaningful chunk of base.css.

This PR introduces a build-time mangler that rewrites those segments to single-letter abbreviations in the bundled output, while keeping every source file (component SCSS, token-sync's standalone CSS) using the full readable names.

Pipeline

  1. token-sync emits a tokens-mangle-map.json manifest alongside its CSS output.
    New files: token-sync/src/mangle-token-name.ts, token-sync/src/manifest-emitter.ts.
    mangleVariableName applies a small abbreviation dictionary segment-by-segment to each CSS custom property name produced by the build:

    export const SEGMENT_ABBREVIATIONS = {
      private: 'p',
      colour: 'c',
      dimension: 'd',
      typography: 't',
    };

    The four entries are deliberately the highest-frequency repeated segments — Phase 1 of the dictionary. More abbreviations can be added incrementally; each addition is collision-checked at build time.

    buildNameMap walks the full set of names emitted by the build, deduplicates, and throws on collisions so a poorly chosen abbreviation can never silently merge two distinct tokens into the same CSS variable.

    emitTokensMangleMap walks the DTCG token trees (primitives + canonical light theme — symmetry across other themes is already asserted by the existing assertInputsAreBuildable check) and writes a sorted original → mangled map to token-sync/css/tokens-mangle-map.json alongside the standalone CSS files.

  2. A new PostCSS plugin (postcss-mangle-bpk-vars) consumes that manifest at webpack build time.
    New file: scripts/webpack/postcss-mangle-bpk-vars.js.
    For every CSS file webpack pipes through it:

    • LHS: custom property declarations whose name is in the manifest get their decl.prop rewritten (catches the :root { … } block coming from theme-backpack-*.css).
    • RHS: var(--bpk-…) references inside declaration values get rewritten via VAR_REF_PATTERN (catches all the component code that consumes the tokens).

    The manifest is loaded eagerly at plugin construction so a missing/broken manifest fails fast at webpack startup rather than mid-build, and is cached per-path so it's not re-read for every CSS file in a single run.

    An optional strict: true mode throws on var(--bpk-…) references that aren't in the manifest — useful in CI to catch typos and tokens that haven't been promoted into the design system. Off by default, so legacy component-local custom properties (e.g. --bpk-button-svg-display) keep flowing through unchanged.

  3. Wire-up in scripts/webpack/postCssPlugins.js.
    The new mangler runs after the dedupe plugin from [CLOV-1637] Phase 1: Drop legacy fallback declaration in bpk-themeable-property and delete duplicate dark style #4630 and before flexbugs-fixes / autoprefixer:

    module.exports = () => [
      dedupeDarkTheme(),
      mangleBpkVars({ manifestPath: TOKENS_MANGLE_MAP_PATH }),
      postCssFlexbugsFixes,
      autoprefixer({ flexbox: 'no-2009' }),
    ];

    Order matters: dedupe relies on the light theme file on disk (which still uses long readable names, since token-sync ships the unmangled form), so it must run before names get rewritten.

Where mangling does NOT happen

This is important enough to call out: only the webpack-bundled CSS is mangled. Token-sync's standalone theme-backpack-light.css / theme-backpack-dark.css files keep their full readable names (the build-css transform comment is updated to spell this out). Anyone consuming those files directly — or anyone who wants to opt out of the mangler entirely — is unaffected.

This means component authors continue writing var(--bpk-private-button-colour-bg-primary) in their SCSS. The mangling is invisible to them; the bundle is the only place the short form appears.

Scope

  • No source-code changes — every var(--bpk-…) call site continues to use the long readable name. Only the bundled output is mangled.
  • The mangle map is a generated file checked into the repo (token-sync/css/tokens-mangle-map.json) so the consumer-side webpack build can read it without running token-sync first. It's regenerated whenever npm run tokens:build-css runs.
  • The dictionary is intentionally tiny in this first cut. Adding more abbreviations is a one-line change followed by a build to confirm buildNameMap doesn't trip its collision check.

What this PR does not do

  • Does not change any consumer-facing API. Consumers importing theme-backpack-*.css directly still receive the full readable names.
  • Does not enable strict mode on the mangler. Turning that on is a separate decision once we're confident the manifest covers every legitimate var(--bpk-…) reference in the codebase.
  • Does not migrate component-local --bpk-* custom properties (e.g. --bpk-button-svg-display) into token-sync. They simply pass through the mangler untouched.

@IrinaWei IrinaWei deployed to Publishing May 25, 2026 06:56 — with GitHub Actions Active
@IrinaWei IrinaWei changed the title [bpk-mixins] add postcss mangle [CLOV-1637] Phase 2: add postcss mangle to shortcut names May 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant