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

Having @emotion/styled in my deps breaks all styling #2414

Closed
olup opened this issue Nov 5, 2020 · 37 comments
Closed

Having @emotion/styled in my deps breaks all styling #2414

olup opened this issue Nov 5, 2020 · 37 comments

Comments

@olup
Copy link

olup commented Nov 5, 2020

Bug report

Describe the bug

If I have @emotion/styled in my dependencies - even if I don't import it, I chakra-ui components have no stylings. Precisely, every styled-system props is kept as-is and ends-up in the css - and is obviously invalid.

To reproduce

start a project with the latest chakra-ui (tested with rc 5, 6 and 8) and latest @emotion-styled (10.0.27). Tested with CRA 4 and latest 3.x

Expected behavior

I should be able to use @emotion/styled in my project alongside chakra-ui

Screenshots

see #2409

System information

  • OS: ubuntu
  • Browser (if applies):Chrome
  • Version of @chakra-ui/core: rc 5, 6 and 8
  • Version of Node.js: 12 something

Additional context

@ljosberinn
Copy link
Contributor

Chakra is internally using @emotion/styled so if you install it, you probably install a different version which leads to these conflicts.

@olup
Copy link
Author

olup commented Nov 5, 2020

Probably the doc should mention this ? In https://next.chakra-ui.com/docs/migration#1-update-your-dependencies It is said that emotion is no longer a peer dependency. However, it should probably be noted that it shouldn't be installed at all as it is now an internal dependency?

@ljosberinn
Copy link
Contributor

We're still discussing whether to have it as a peer dependency for v1. Generally though, there's no reason to use styled additional to chakra because you'd be mixing approaches which will lead to inconsistencies. If you need to use styled directly for whatever reason, you can leverage chakra directly:

import { chakra } from '@chakra-ui/core';

const RedBox = props => <chakra.button bgColor="red.100" {...props} />

@olup
Copy link
Author

olup commented Nov 5, 2020

Interesting. However, I might be interested in being able to style other components with styled DX, while still use chakra-ui for my basic UI needs, I would think.

@MarcLongJoyride
Copy link

We are seeing this issue at our company as well in RC8.

@JonMontgo
Copy link

Here's a code pen I made with an example of this bug https://codesandbox.io/s/homepage-forked-5l6hj

@ljosberinn
Copy link
Contributor

You can pass a component to chakra too :)

@Lulololu
Copy link

Lulololu commented Nov 5, 2020

Hola,

I also use emotion for complex styled layouts or animations, and enjoy Chakra-UI for basics components. Aria compliance is another reason for me to use Chakra-UI.

Does it mean that it's gonna be soon impossible to use emotion with Chakra-UI?

Could someone, please, explain to me how I could build /style complex tables, for example, using only Chakra-UI ?

Thank you,

@ljosberinn
Copy link
Contributor

@Lulololu It definitely won't be impossible, I just wouldn't recommend it considering you can just use chakra because that's basically the same (except chakra doesn't support the tagged template literal syntax). However, you'd have to sync the version with Chakra as far as I'm aware. We're currently looking into compatibility with v10.1 of emotion.

Regarding a table, this would work as a few primitives:

import { chakra } from '@chakra-ui/core';

const Table = props => <chakra.table {...props } />;
const Thead = props => <chakra.thead {...props } />;
const Tbody = props => <chakra.tbody {...props } />;
const Th = props => <chakra.th {...props } />;
const Td = props => <chakra.td {...props } />;
const Tr = props => <chakra.tr {...props } />;

e.g. <Table color="red.300" /> would use regular theme.colors.red.300 now.

On a sidenote, we're looking into supporting Table post v1 launch out of the box.

@olup
Copy link
Author

olup commented Nov 5, 2020

I feel this issue is going slightly off-topic. Chakra-ui is a very customizable ui-kit based on emotion and styled-system. It's not a styling library. If at any given time the use of Chakra is preventing user from using emotion or emotion-styled, this is an issue and should be fixed. A user should be able to use whatever css-in-js solution he wants to use, from Radium to Stitches or Styled-components, alongside chakra-ui. I'd rather have emotion as peer-dep with a hard version number if needed, or the compatible version clearly stated in the doc maybe ?

@ljosberinn on a side note, Table would be pretty neat !

@Lulololu
Copy link

Lulololu commented Nov 5, 2020

@ljosberinn

Thanks a lot for your answer.

1 - I did not know it was possible to style "primitives", as you wrote.

So it would be exactly the same - except for the syntax : conditional props, nested selectors, and so on. Would ALL CSS props be available? Would it be mandatory to use Chakra-UI shortcuts?

--> Is there, please, some link on the Chakra-UI Documentation which would explain the process ? I've been searching but could not find it.

2 - I clearly understand the consistency priority. But, and perhaps I am wrong, emotion has its own advantages. For complex layouts and animation, I really enjoy it. But, because you said it would still be possible to keep using it, I'm relieved.

Regarding this issue subject, all my toast backgrounds just suddenly became transparents. If someone had any trick / solution.....

Merci à vous,

@olup
Copy link
Author

olup commented Nov 5, 2020

You can keep using emotion and emotion/styled and the beloved tagged template literal by installing the same version as the one packaged by chakra-ui (or if you feel like it, just uninstall emotion completely - the import should use the one from Chakra - while waiting for a proper fix to the situation)

De rien, pas de soucis

@ljosberinn
Copy link
Contributor

ljosberinn commented Nov 5, 2020

If at any given time the use of Chakra is preventing user from using emotion or emotion-styled, this is an issue and should be fixed. A user should be able to use whatever css-in-js solution he wants to use, from Radium to Stitches or Styled-components, alongside chakra-ui. I'd rather have emotion as peer-dep with a hard version number if needed, or the compatible version clearly stated in the doc maybe ?

I agree and we're looking into this :) we were considering adding it as peer dep already anyways.

Would ALL CSS props be available? Would it be mandatory to use Chakra-UI shortcuts?

All that are listed here should work seamlessly. I believe this documentation is in fact missing "a few" because, you know, CSS got a lot of stuff. While chakra should not have limitations here, some core chakra components will not have access to all props, this is a rare case though and we haven't heard of any issues where this leads to undesired behaviour. In any case you should be able to override everything with sx anyways.

--> Is there, please, some link on the Chakra-UI Documentation which would explain the process ? I've been searching but could not find it.

I was actually confident the docs showed an example here but as it turns out, they don't... technically that <Box as="button" usage is the same though, although clearly hidden away here. The implementation of Box is just chakra('div')! We will document chakra better.

@Lulololu
Copy link

Lulololu commented Nov 5, 2020

@olup

Alright. So @emotion/core and @emotion/styled have to be the exact same release, in package.json and chakra-ui module. Got it !

You're right, Chakra-UI AND emotion are great and we should be able to use both of them.

Hoping for a fix, then.

Merci à toi !!

@ljosberinn

Thank you for your help !

@vonwao
Copy link
Contributor

vonwao commented Nov 5, 2020

I'm having a different, but maybe related issue:

When I took out @emotion/core from my project, I get this error:
./node_modules/@chakra-ui/css-reset/dist/esm/css-reset.js
Module not found: Can't resolve '@emotion/core' in '/Users/OXV0UID/code/ui-csa/node_modules/@chakra-ui/css-reset/dist/esm'
(I'm not sure why, because I'm not actually calling any css reset)

Then, when I add @emotion/core back to my project, chakra does some really weird stuff, like the colors like 'blue.500' don't work... the Select and Input controls look super thin.

@ljosberinn
Copy link
Contributor

ljosberinn commented Nov 5, 2020

You probably add a different version, most likely latest, of @emotion/core. You can amend this if you remove your lockfile, remove node_modules, remove @emotion deps from package.json and let chakra decide which version it wants through reinstalling. You can still use it as usual then.

CSSReset is implicitly included in ChakraProvider.

@MarcLongJoyride
Copy link

@olup

Alright. So @emotion/core and @emotion/styled have to be the exact same release, in package.json and chakra-ui module. Got it !

You're right, Chakra-UI AND emotion are great and we should be able to use both of them.

Hoping for a fix, then.

Merci à toi !!

@ljosberinn

Thank you for your help !

No our team has tried 2 different versions (@emotion/core 10.0.35 and @emotion/styled 10.0.27) and that works just fine. It appears more to do with the version of emotion that is causing this issue... once you get to 10.1.

@vonwao
Copy link
Contributor

vonwao commented Nov 5, 2020

You probably add a different version, most likely latest, of @emotion/core. You can amend this if you remove your lockfile, remove node_modules, remove @emotion deps from package.json and let chakra decide which version it wants through reinstalling. You can still use it as usual then.

CSSReset is implicitly included in ChakraProvider.

That totally fixed it. Thanks!

This really needs to be more explicit. At least in the "upgrading instructions" it should say to delete BOTH node_modules and the "lockfile"

(I tried deleting node_modules but forgot about the lockfile. Why is the node ecosystem so weird and why can't things break in more predictable ways instead of random errors like this!?)

@AndrewPrifer
Copy link

AndrewPrifer commented Nov 5, 2020

Same here, I'm building a web component, so being coupled to outside dependencies would be a deal breaker. It is a little puzzling to me though, how exactly does an externally added @emotion/core break chakra? Shouldn't yarn and your module bundler resolve both versions without collision?

@ljosberinn do you have an idea how I could use chakra in complete isolation in a web component? Also, this is going to be part of a development tool which is excluded from production, so there are no size restrictions to consider.

@hedleygois
Copy link

Removing every @emotion trace from my package.json (and removing node_modules together with yarn.lock) fixed the issue but you end up importing a transitive dependency to use @emotion which is a bad smell. Also, trying to use chakra from chakra/core like this didn't work (for example)

const ColoredProgress = chakra(Progress)<{ readonly color: string }>`
  div {
    background-color: ${(props) => props.color};
  }
`

I'm still trying to figure out how to use css (from @emotion/core) like

<div css={someCoolEmotionCss}>
...
</div>

@ljosberinn
Copy link
Contributor

ljosberinn commented Nov 6, 2020

@vonwao re This really needs to be more explicit. At least in the "upgrading instructions" it should say to delete BOTH node_modules and the "lockfile" - afraid this is simply how npm works. The lockfile is a log of the last install. Based on that, node_modules is built, so removing node_modules and reinstalling just leads to installing the same stuff as you had before.

Why is the node ecosystem so weird and why can't things break in more predictable ways instead of random errors like this!?

Fwiw, outside of react this would most likely crash and burn a lot harder than it does here. The issue in the end is that emotion has a ThemeProvider, which ChakraProvider renders. Chakra renders its version, emotion 10.0.27 iirc. Then you use styled from 10.1, which uses the ThemeProvider from 10.1. Which is undefined, as it isn't used.

@AndrewPrifer Afraid I have no idea about creating webcomponents based on React components except that "its possible".

Re how exactly does an externally added @emotion/core break chakra: emotion doesn't strictly follow semver, so since chakra requires a specific version (not because of incompatibilities but simply becasue it was the latest at the time), any new release of emotion could break chakra to some degree. That's just what not following semver leads to.
And eventually, as of recently, this happened - when you install @emotion/core, its automatically latest because of how npm works unless you specify a version, which leads to incompatibility (for now - we're looking into it).

@hedleygois css should be available under _css instead as its used internally; you should be using sx instead most likely.

As mentioned, the tagged template literal synatx is not supported by chakra (see here).

@AndrewPrifer
Copy link

AndrewPrifer commented Nov 6, 2020

@ljosberinn thank you for the explanation!

And eventually, as of recently, this happened - when you install @emotion/core, its automatically latest because of how npm works unless you specify a version, which leads to incompatibility (for now - we're looking into it).

If I look at @chakra/system's package.json, I see that @emotion/core is pinned at 10.0.35. I was always under the impression that in this case if you install a different version of the same package as a direct dependency, then there will be two emotion instances in the bundle and chakra can keep using its own. So is this not the case here? I'm just trying to understand what exactly is happening so I can work something out. :)

Afraid I have no idea about creating webcomponents based on React components except that "its possible".

Luckily I already worked out how to use React, emotion and chakra in a webcomponent, my sole issue now is to somehow work around the situation that when my consumer installs their own emotion, even without importing it, things break, and was asking if you had an idea for how I could put a bandaid on this.

For context, this is what I'm working on: https://github.com/AndrewPrifer/react-three-editable

@ljosberinn
Copy link
Contributor

If I look at @chakra/system's package.json, I see that @emotion/core is pinned at 10.0.35. I was always under the impression that in this case if you install a different version of the same package as a direct dependency, then there will be two emotion instances in the bundle and chakra can keep using its own. So is this not the case here? I'm just trying to understand what exactly is happening so I can work something out. :)

I'm afraid I wouldn't know in detail. I've definitely seen this in the past at work e.g., where we had conflicting versions of redux and another dependency, which dragged in its own redux version because they were not synced. You can imagine it being a pain debug to see a "no redux store found" error when you can literally see your Provider higher up in the tree.

@AndrewPrifer
Copy link

Yeah I get you, often happens with React too, but the error is always that multiple versions are simultaneously imported which create their own state. I didn't think it was possible for direct dependencies to override transitive dependencies in the way it seems to be happening with chakra and emotion.

@vonwao
Copy link
Contributor

vonwao commented Nov 6, 2020

@ljosberinn

Fwiw, outside of react this would most likely crash and burn a lot harder than it does here. The issue in the end is that emotion has a ThemeProvider, which ChakraProvider renders. Chakra renders its version, emotion 10.0.27 iirc. Then you use styled from 10.1, which uses the ThemeProvider from 10.1. Which is undefined, as it isn't used.

Ok, I get that, but there should be ways for the code to do some simple check, whether it's checking if a certain module is present or not, and then display a message like "you may be running with an incompatible version of @emotion, try deleting node_modules and [lockfile]".

Or I imagine that node itself could build-in some mechanisms that would allow it to "guess" when there's this kind of issue and make this same recommendation.

And yes, I know that every node developer worth his salt knows this (dumb mistake on mine for not realizing/remembering I had to delete lockfile)... but still there are many amateurs and I think as a community should strive to make things explicit and less frustrating (and in my experience even pros experience brain more often than they like to admit LOL)

Anyway, thanks again for explaining this!

@ljosberinn
Copy link
Contributor

Generally I agree, I'm just unsure how brittle an implementation of that would look like. Projects can be set up in numerous ways, and to be able to check reliably, we'd have to traverse up folders until we find a package.json to parse - which might not even be the relevant one, see monorepos - which is at best sketchy for a module to do imo. I haven't seen any other library doing so and notifying users either, happy to see an example here though.

@vonwao
Copy link
Contributor

vonwao commented Nov 6, 2020

@ljosberinn yep, good question, I'll think about it and maybe do some research if it's possible.
BTW, I just submitted this PR to the migration doc:
#2422
with this message:

Emotion has a ThemeProvider, which ChakraProvider renders. If your version in
node_modules are out of sync with the new Chakra version, you may get a strange
error. Therefore it's a good idea to delete node_modules as well as the
package-lock.json or yarn.lock when upgrading or if you get an error
related to @emotion

Hopefully someone who has the permssions will merge it :)

@ljosberinn
Copy link
Contributor

@segunadebayo
Copy link
Member

Thanks for the PR @vonwao. I've updated the notes in the docs as well.

For anyone else facing this issue kindly read through

@AndrewPrifer
Copy link

@segunadebayo could you please link to the notes?

@seloner
Copy link

seloner commented Nov 12, 2020

You can pass a component to chakra too :)

Can you post an example how to do that ?

@ljosberinn
Copy link
Contributor

We have new docs for that here.

@VinSpee
Copy link

VinSpee commented Nov 12, 2020

if anyone is dealing with the issue of dependencies relying on different versions of @emotion/core, If you're using yarn, add

  "resolutions": {
    "@emotion/core": "10.0.35"
  },

to your package.json and it should sort the problem out.

@devtombiz
Copy link

Hi all, I am still having this issue or a similar issue.

I have created a react component library using Chakra. But whenever trying to import this library in a next.js project (That is also using Chakra) I lose all styles from the component library and get a warning message saying that there are two instances of emotion. I went through all the deps I could to make sure emotion is at the same version everywhere but that didn't help:

Screen Shot 2022-08-26 at 8 40 56 AM

Any idea why ?

@setcooki
Copy link

@devtombiz i am facing the same issue - did you find a solution for this?

@devtombiz
Copy link

@devtombiz i am facing the same issue - did you find a solution for this?

Unfortunately, I couldn't find a suitable solution. So I took my library and made it part of the main code. This was an in-house library so I had all the code available.

@mwelwankuta
Copy link

We are seeing this issue at our company as well in RC8.

Also experincing this issue, when built and ran locally, it's fine. when running in development in runs fine. but when deployed the styles just disapear.

I am using React with Vite. anyone have a solution for this issue almost 4 years later ?

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

No branches or pull requests