Skip to content

[unplugin] Rehash single-stylesheet builds when StyleX CSS changes (#1889) - #1906

Open
0x5t4l1n wants to merge 1 commit into
facebook:mainfrom
0x5t4l1n:fix/unplugin-vite-css-codeSplit-false-rehash
Open

0x5t4l1n wants to merge 1 commit into
facebook:mainfrom
0x5t4l1n:fix/unplugin-vite-css-codeSplit-false-rehash

Conversation

@0x5t4l1n

Copy link
Copy Markdown

What changed / motivation ?

Fixes @stylexjs/unplugin's Vite adapter for single-stylesheet builds (build.cssCodeSplit: false): a StyleX-only edit (e.g. changing a padding value) changed the CSS content but left the content-hashed stylesheet filename unchanged, so browsers/CDNs kept serving the stale stylesheet against the new class names.

Root cause. Vite's vite:css-post plugin emits the extracted CSS assets in its own generateBundle hook, which runs after the enforce: 'pre' plugins. With cssCodeSplit: false the entire stylesheet is emitted there — and nowhere else. The adapter's generateBundle ran earlier (it lives on a pre-enforced plugin and had no hook-level ordering), so the bundle contained no CSS asset yet; the adapter then fell back to appending the StyleX CSS on disk in writeBundle, which appends but never rehashes the filename.

Fix. Run the adapter's generateBundle with order: 'post' so it executes after vite:css-post has emitted the single stylesheet. The existing replaceCssAssetWithHashedCopy path then applies the same rehashing already used by code-split builds. This matches the reporter's own diagnostic experiment in #1889 — the filenames produced with the fix (style-B2ydcg4O.css / style-DmGQdaq2.css) match exactly.

Linked PR/Issues

Fixes #1889

Additional Context

Reproduction against published @stylexjs/unplugin@0.19.1 + Vite 8.3.0 (4 builds: baseline, unchanged, stylex-only padding 16 → 32, plain-CSS margin 24 → 40):

Before (0.19.1, bug):

  • baseline assets/style-CW4HsblT.css sha 25f2e455…
  • stylex-only assets/style-CW4HsblT.css sha 3b00d50c… ← same filename, different bytes

After (this fix):

  • baseline assets/style-B2ydcg4O.css sha 25f2e455…
  • stylex-only assets/style-DmGQdaq2.css sha 3b00d50c… ← filename changes with the bytes
  • plain-css assets/style-i818Skdl.css sha 56e1ff21…
  • HTML <link> and .vite/manifest.json both reference the new hashed file; the CSS contains padding-top: 32px

Tests. Added a Vite single-stylesheet builds (cssCodeSplit: false) describe block to packages/@stylexjs/unplugin/__tests__/unplugin.test.js: one test pins the order: 'post' hook contract, one drives the rehash path against a single emitted stylesheet. Full unplugin suite: 22/22 pass; eslint + prettier clean.

Pre-flight checklist

Vite's vite:css-post plugin emits the extracted CSS assets in its own
generateBundle hook, which runs after the enforce:'pre' plugins. With
build.cssCodeSplit: false the whole stylesheet is emitted there (and
nowhere else), so the adapter's generateBundle ran before any CSS asset
existed in the bundle. It then fell back to appending on disk in
writeBundle without rehashing the filename, so a StyleX-only edit
changed the CSS bytes while the content-hashed filename stayed the
same and browsers/CDNs kept serving stale stylesheet against the new
class names.

Run the adapter's generateBundle in post order so it executes after
vite:css-post has emitted the single stylesheet, making the existing
replaceCssAssetWithHashedCopy path work for single-stylesheet builds.

Fixes facebook#1889
Copilot AI lite review requested due to automatic review settings September 24, 2026 13:29
@meta-cla

meta-cla Bot commented Sep 24, 2026

Copy link
Copy Markdown

Hi @0x5t4l1n!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks!

@vercel

vercel Bot commented Sep 24, 2026

Copy link
Copy Markdown

@0x5t4l1n is attempting to deploy a commit to the Meta Open Source Team on Vercel.

A member of the Team first needs to authorize it.

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

The regression test does not exercise Vite’s hook scheduler or verify updated hashed asset references.

Review effort: Lite
Findings: None

What changed in this PR

Fixes stale CSS filenames in Vite single-stylesheet builds by running StyleX CSS processing after Vite emits the stylesheet.

Changes:

  • Runs generateBundle with post-order execution.
  • Adds tests for stylesheet rehashing and hook ordering.
File Reviewed changes
packages/​@stylexjs/​unplugin/​src/​vite.js Applies post-ordered CSS asset replacement and rehashing.
packages/​@stylexjs/​unplugin/​__tests__/​unplugin.test.js Adds coverage for hook ordering and single-stylesheet rehashing.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Sep 24, 2026
@meta-cla

meta-cla Bot commented Sep 24, 2026

Copy link
Copy Markdown

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Vite CSS filename does not change after a StyleX-only edit with cssCodeSplit: false

2 participants