question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Multiple instances of emotion overwrite each other

See original GitHub issue

Current behavior: We’ve microservice architecture so each team can have their own emotion instance, in the same time they can even import other libraries that also use emotion. All apps getting loaded asynchronously. And when the next app is loaded, it creates own emotion instance that overwrites previous (at least it looks like so, but old <style /> tags still exist in DOM). image Yep, In dev mode we’re getting the warn, but in production build all sheets getting overwritten.

To reproduce: Main repo

  1. npm i to install pseudolibraries and deps
  2. npm run start to see the warn
  3. nrm run build to see how one library overwrites another after 2 seconds (public folder)

Library repo 1 Library repo 2

Expected behavior: Allow multiple instances of emotion

Environment information:

  • Main repo with emotion@10*
  • Libraries repos with emotion@11*

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:7
  • Comments:19 (7 by maintainers)

github_iconTop GitHub Comments

7reactions
Andaristcommented, Jan 12, 2021

In this situation, you really should use separate caches with unique keys - unfortunately <style/> elements are shared resources in the global document and we can’t easily distinguish which belong to each of those microfrontends.

The problematic part though is that you are using hard dependencies for @emotion/react in each one and thus you load multiple instances of Emotion 11 so their context identities won’t be shared. I guess that because you are in this microfrontend architecture this is a hard requirement for you so I would advise you to just export CacheProvider + createCache from each of your libraries~ and just wrap each React subtree in those CacheProviders.

So in the end you would handle things like this:

diff --git a/src/index.js b/src/index.js
index b55fafe..c350d6a 100644
--- a/src/index.js
+++ b/src/index.js
@@ -2,7 +2,8 @@ import React from "react"
 import ReactDOM from "react-dom"
 import styled from "@emotion/styled"
 import css from "@emotion/css"
-
+import { CacheProvider } from "@emotion/core"
+import createCache from "@emotion/cache"
 
 const getEmotion11Library1Chunk = async () => {
   return await import("emotion-11-library-1")
@@ -14,13 +15,23 @@ const getEmotion11Library2Chunk = async () => {
 
 setTimeout(() => {
   getEmotion11Library1Chunk().then((chunk) => {
-    ReactDOM.render(<chunk.Library1 />, document.getElementById(`placeholder1`))
+    ReactDOM.render(
+      <chunk.CacheProvider value={chunk.createCache({ key: "lib1" })}>
+        <chunk.Library1 />
+      </chunk.CacheProvider>,
+      document.getElementById(`placeholder1`)
+    )
   })
 }, 2000)
 
 setTimeout(() => {
   getEmotion11Library2Chunk().then((chunk) => {
-    ReactDOM.render(<chunk.Library2 />, document.getElementById(`placeholder2`))
+    ReactDOM.render(
+      <chunk.CacheProvider value={chunk.createCache({ key: "lib2" })}>
+        <chunk.Library2 />
+      </chunk.CacheProvider>,
+      document.getElementById(`placeholder2`)
+    )
   })
 }, 4000)
 
@@ -34,6 +45,9 @@ const Title = styled.h1`
 `
 
 ReactDOM.render(
-    <Title>Welcome!</Title>,
+  <CacheProvider value={createCache({ key: "app" })}>
+    {" "}
+    <Title>Welcome!</Title>
+  </CacheProvider>,
   document.getElementById(`app`)
 )

Note that this doesn’t fix your problem with Emotion 11 hijacking Emotion 10 styles - we’ve ensured that we don’t try to hijack Emotion 10 SSR styles but we have missed the case with dynamically created Emotion 10 styles (or assumed that it will just work thanks to the same thing we’ve done for SSRed styles).

You can workaround this by doing this:

const emotion10Styles = document.querySelectorAll(
  `style[data-emotion]:not([data-s])`
);
Array.prototype.forEach.call(emotion10Styles, (node) => {
  node.setAttribute("data-s", "");
});

before you fetch a bundle containing Emotion 11 code.

We can’t do much for the first thing but we probably should try to handle the second problem and I will give this a thought.

3reactions
nelsondudecommented, Mar 29, 2021

Is there any update on this? I’m currently just doing a dev build until this issue is fixed. If it isnt soon I might just switch to styled components. Currently using @emotion/styled for a bunch of components and i’d prefer not to convert these to use the css prop

Read more comments on GitHub >

github_iconTop Results From Across the Web

Material-ui overrides react emotion rules - Stack Overflow
The issue was resolved by changing the order of rendering the style rules. I created a wrapper that needs to wrap the entire...
Read more >
Best Practices - Emotion
There are two main approaches for sharing styles across an Emotion application. To illustrate the two methods, let's imagine we're developing an application ......
Read more >
Style library interoperability - Material UI - MUI
In MUI, all child elements have an increased specificity of 2: .parent .child {} . When writing overrides, you need to do the...
Read more >
Why We're Breaking Up with CSS-in-JS - DEV Community ‍ ‍
On the other hand, if you're using CSS-in-JS, you can write your styles directly ... Multiple instances of Emotion get loaded at once....
Read more >
How to ensure your Emotion ‍ CSS-in-JS styles are indeed ...
To make sure the Emotion styles are overwriting the CSS Module styles in ... 2. Now that we have our own Emotion instance...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found