Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mismatch between Server and Client Classes when Composing Styles with Vite #1133

Open
2 tasks done
jahredhope opened this issue Jul 9, 2023 · 2 comments
Open
2 tasks done
Labels
vite Issue related to vite

Comments

@jahredhope
Copy link
Contributor

Describe the bug

Vanilla Extract adds an additional Identifier to classes to ensure it's safe for use in selectors. This gets stripped when unused.

In some cases this is only stripped from client code and remains in server code, resulting in a mismatch between server and client, also known as a hydration error.

When composed styles are used in selectors, they are assigned an additional class if required so they can be uniquely identified. When selectors are processed internally, the composed classes are removed, only leaving behind the unique identifier classes. This allows you to treat them as if they were a single class within vanilla-extract selectors. - v1.4.0

Details

When creating a style composed of other styles, (either by passing an array to style or calling a Sprinkles function in a css file) Vanilla Extract will create an additional identifier class.
If the class is unused, the class will appear in the server render, but will be stripped for the client render, resulting in a mismatch between renders known as a hydration error.

This only occurs when:

  • emitCssInSsr is not true
  • A style is defined as a composition of other styles. (Or, a Sprinkles function called in a css.ts file)
  • The resulting value must be exported, and NOT used in another selector

Though Sprinkles has been mentioned here, the demonstration below reveals this occurs without Sprinkles. It's just that your more likely to be in this scenario if you are using atomic styles.

Attempted Workarounds / Solutions

As mentioned setting emitCssInSsr to true did solve my issue, and may be a more preferable configuration anyway.

  • Perhaps it would make sense to default emitCssInSsr to true?

If not, I suspect the result of this code path:

https://github.com/vanilla-extract-css/vanilla-extract/blob/master/packages/vite-plugin/src/index.ts#L163 calling @vanilla-extract/integration's processVanillaFile is the key differentiator.


This may be related to #654 which has a similar error, but has quite a different scenario.

Reproduction

https://github.com/jahredhope/ve-sprinkles-in-styles-bug

System Info

System:
    OS: macOS 13.4
    CPU: (10) arm64 Apple M1 Pro
    Memory: 3.93 GB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 18.16.1 - ~/.volta/tools/image/node/18.16.1/bin/node
    Yarn: 1.22.19 - ~/.volta/tools/image/yarn/1.22.19/bin/yarn
    npm: 9.5.1 - ~/.volta/tools/image/node/18.16.1/bin/npm
    pnpm: 7.33.3 - ~/.volta/tools/image/pnpm/7.33.3/bin/pnpm
  Browsers:
    Chrome: 114.0.5735.198
    Safari: 16.5
  npmPackages:
    @vanilla-extract/css: ^1.12.0 => 1.12.0 
    @vanilla-extract/sprinkles: ^1.6.1 => 1.6.1 
    @vanilla-extract/vite-plugin: ^3.8.2 => 3.8.2 
    vite: ^4.3.9 => 4.3.9

Used Package Manager

pnpm

Logs

No response

Validations

@jahredhope
Copy link
Contributor Author

jahredhope commented Jul 10, 2023

Update:

  • This is not isolated to emitCssInSsr=false and can be recreate with emitCssInSsr=true, though it's more difficult.
  • This can happen in both directions: Either the additional style being stripped from the client and not the server, or being stripped from the server and not the client.

I can, very inconsistently, recreate the behaviour in both directions when I queue a request the server render immediately after starting the server.
When I wait for the dev server to start up it doesn't occur.

This leads me to believe:

  • When the server and client are trying to create the styles there is a race condition as to whether the styles will be stripped before they are used.

I've not added the above update into the simplified solution. I believe this is due to the small size of the project makes it hard to trigger the race condition before it's ready.

Example: Additional Style on Server
example-add-style-server

Example: Additional Style on Client
example-add-style-client

@graup graup added vite Issue related to vite and removed pending triage labels Jul 17, 2023
@jahredhope
Copy link
Contributor Author

Confirmed this is fixed/no-longer a problem with the new experimental macros work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
vite Issue related to vite
Projects
None yet
Development

No branches or pull requests

2 participants