babel-plugin-styled-components: Invalid checksum

I am using the babel plugin 1.1.5 with styled components 2.1.0. I have placed a ssr: true in both the client and the server babel configs.

However, I always see this mismatch in checksum:

(client) P gradient-container___default-s1b1hs7t-
(server) P gradient-container-s1b1hs7t-0 ieOpth"

This tells me that the plugin is enabled for both the client and server, but the client consistently has this __default string as part of the class name. Where is this coming from?

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 31 (13 by maintainers)

Most upvoted comments

Okay, two things:

  1. We need to mention that we can’t fix this and it’s an issue with how certain Babel plugins (like react-hot-loader) change exports around.
  2. Let’s add a long message with code examples to the website under FAQ and link to it from the warning. (“Why am I getting checksum mismatches when server-side rendering?” or smth) This could also include more common cases like using window.x (e.g. window.innerWidth) in your styling etc. (maybe we should write an eslint plugin? lol)

Text for the warning:

[babel-plugin-styled-components] You’ve turned on the ssr option, but another Babel plugin has changed the exports. (e.g. react-hot-loader does this) This will break client-side rehydration. Please assign your component to a variable and export default the variable, see [link-to-website]

Code examples:

// Before
export default styled.button`
  color: blue;
`;

// After
const Button = styled.button`
  color: blue;
`
export default Button;

@philpl Yes, enforcing order of when babel plugins execute is not really possible. http://thejameskyle.com/babel-plugin-ordering.html

Hm, can you try disabling the displayName option? It seems that something is leaking into the name there. Maybe the transpilation is not identical, and it’s using default from export default or sth?

Also, currently the plugin doesn’t support withComponent and extend. This will be added with the changes in v3

Ah, it seems then that we’re not falling back to attaching a componentId based on the filename only. Something to look into, I suppose

On the other hand, generally it’s not a good idea to directly export unnamed components. Exporting arrow functions without a name for example will lead to nameless components

But anyway, I’ll have a quick look and see if there’s any obvious problems in the plugin

@mxstbr @piteer1 @neoziro I’ve taken a look at the failing test and the problems seem to be:

  • No name (variable name) is given to the StyledComponent. This is generally bad practice as we’re enforcing that every presentational component has a name.
  • The order of the plugins might be relevant (See below for an explanation)

So to the order of the plugins, what is happening is:

  1. We detect the StyledComponent and detect the filename. At this point it doesn’t have a variable name, so we leave it blank. Only the filename is used
  2. The hot loader plugin creates a variable called _default for the component

Depending on the order we either have a variable name (_default) or not. So the solution is to keep the order of the babel plugin consistent.

@mxstbr We can add the variable name to be _default for StyledComponents that are being export default-ed. The problem is that other plugins might choose to change this pattern completely. So if another plugin chooses the variable name defaultExport or something similar, this won’t fix anything and we’ll be back to square one.

I think we can add _default for now, and output a warning that says something along the lines of:

The ssr option is turned on, but you’re default-exporting a StyledComponent inside [FILENAME]. This can cause its name to be unstable when other plugins that are wrapping it are used. Please apply the best practice of creating a variable for your component.

Sounds good?

@mxstbr Sorry for late answer, but I wanted to know what exactly causes this behavior. It is React Hot Loader plugin that does this transformation with var _default. I was able to create a failing test at last: https://github.com/styled-components/babel-plugin-styled-components/pull/86

Because it only happens when this plugin is attached, I’m not sure if it should be considered as a bug in this plugin.