vanilla-extract icon indicating copy to clipboard operation
vanilla-extract copied to clipboard

(Regression) Missing class name when using style to compose sprinkles and other styles

Open ericmatthys opened this issue 4 years ago • 5 comments

Describe the bug

Downgrading @vanilla-extract/webpack-plugin to 2.1.5 appears to resolve the issue.

In specific situations, it appears that all expected class names are not included. An example of the problem is seen with this error message, where the client is missing a class name. I have reproduced this in both a Next.js app and a Storybook app. After a fast refresh, like changing the color from green to red, it will start working again, but the initial build is always broken in both Next.js and Storybook.

Warning: Prop className did not match. Server: "Example__109b2pw2 sprinkles_width_100%__doo1ph0 Example__109b2pw1" Client: "sprinkles_width_100%__doo1ph0 Example__109b2pw1"

The example is not as reduced as I'd like yet, but there are a few requirements for the bug to happen afaik.

import { style } from "@vanilla-extract/css";
import { sprinkles } from "./sprinkles.css";

export const container = style([
  sprinkles({
    width: "100%"
  }),
  style([{ fontSize: "2em" }])
]);

export const label = style({
  selectors: {
    [`${container}:hover &`]: {
      backgroundColor: "green"
    }
  }
});
  1. style must be used with a sprinkles call. Basic styles cannot be included directly here, it can only be composing sprinkles and other style calls. The example is simplified, so I know including the nested style doesn't make much sense in this context.
  2. The return of that style is then used in another selector style. This is what makes or breaks the example. If that unique class name is not included in the DOM, then the label won't turn green on hover.
  3. It seems like there needs to be another import that uses sprinkles as well, hence the Divider.css.js in the example.
  4. The responsive properties in sprinkles seem to matter as well.

Link to reproduction

https://codesandbox.io/s/affectionate-turing-kwrpqd

When working, hovering over Hello World should show the green background behind World. When broken, there is no change on hover.

System Info

Output of npx envinfo --system --npmPackages @vanilla-extract/css,@vanilla-extract/webpack-plugin,@vanilla-extract/esbuild-plugin,@vanilla-extract/vite-plugin,@vanilla-extract/sprinkles,webpack,esbuild,vite --binaries --browsers:

My reproduction with Storybook outside of Code Sandbox:

  System:
    OS: macOS 12.1
    CPU: (10) x64 Apple M1 Max
    Memory: 831.85 MB / 64.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 14.17.3 - ~/.volta/tools/image/node/14.17.3/bin/node
    Yarn: 1.22.10 - ~/.volta/tools/image/yarn/1.22.10/bin/yarn
    npm: 6.14.13 - ~/.volta/tools/image/node/14.17.3/bin/npm
  Browsers:
    Chrome: 100.0.4896.88
    Firefox: 98.0.1
    Safari: 15.2
  npmPackages:
    @vanilla-extract/css: 1.6.8 => 1.6.8
    @vanilla-extract/sprinkles: 1.4.0 => 1.4.0
    @vanilla-extract/webpack-plugin: 2.1.7 => 2.1.7
    webpack: 5.67.0 => 5.67.0

ericmatthys avatar Apr 13 '22 20:04 ericmatthys

Experienced a possible similar issue with styles created using globalStyle not actually getting added to the page. Tricky to reproduce, because as soon as I edit the .css.ts file the issue goes away, but also seemed like downgrading resolved it. If can create a reliable repro I'll post it

zgreen avatar Jun 07 '22 14:06 zgreen

I'm still experiencing this on the latest versions of vanilla extract packages. I created a straightforward reproduction here: https://github.com/zgreen/vanilla-extract-bug

zgreen avatar Oct 07 '22 18:10 zgreen

Same for me

vovanezha avatar Nov 02 '22 08:11 vovanezha

Using the vite plugin (version 3.6.0) I can reproduce something similar.

It does this even if the linked style only consist of sprinkles calls and zero style calls. It never does it locally with a prod build, but always on the CI machine.

Exemple:

export const size = {
  small: sprinkles({ blockSize: "3", borderRadius: "4", inlineSize: "7" }),
  medium: sprinkles({ blockSize: "4", borderRadius: "5", inlineSize: "9" })
}

export const thumb = style([
  column,
  sprinkles({
    ...
  }),
  {
    selectors: {
      [`${size.small} > &`]: {
        blockSize: vars.size["2"],
        inlineSize: vars.size["2"]
      },
      [`${size.medium} > &`]: {
        blockSize: vars.size["3"],
        inlineSize: vars.size["3"]
      }
    }
  }
])

Here, the selectors referencing size almost never work because the parent won't have a stable className set for size.small or size.medium. Locally, it does retain the className that links to zero css properties.

AlexGalays avatar Nov 07 '22 23:11 AlexGalays

We just encountered the same Problem, rolling back to webpack plugin version 2.1.5 solved the issue for us too. Are there any hints how to triage this issue, I'm new to webpack plugin developement but would love to help with this.

morbidick avatar Mar 30 '23 13:03 morbidick