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
Can't clear emotion cache. #3133
Comments
This is the other example I mention where I create a new cache: import { getMarkupFromTree } from '@apollo/client/react/ssr';
import createEmotionCache from '@emotion/cache';
import { injectGlobal } from '@emotion/css';
import { CacheProvider as EmotionCacheProvider } from '@emotion/react';
import { extractCritical } from '@emotion/server';
import type { NextFunction, Request, Response } from 'express';
import type { FC } from 'react';
import { renderToString } from 'react-dom/server';
const App: FC<{ bgColor: string }> = ({ bgColor }) => {
injectGlobal(`body { background-color: ${bgColor}; }`);
return <>Dummy App</>;
};
/** For investigation of https://github.com/emotion-js/emotion/issues/3133 */
export async function renderDummy2(
request: Request,
response: Response,
next: NextFunction
): Promise<void> {
const currentUrl = new URL(request.url, `${request.protocol}://${request.hostname}`);
const bgColor = currentUrl.searchParams.get('background-color') ?? 'blue';
const emotionKey = 'my-emotion';
const emotionCache = createEmotionCache({ key: emotionKey });
const reactMarkup = (
<EmotionCacheProvider value={emotionCache}>
<App bgColor={bgColor} />
</EmotionCacheProvider>
);
const markup = await getMarkupFromTree({
tree: reactMarkup,
renderFunction: renderToString,
});
const { ids, css } = extractCritical(markup);
const emotionStyleTags = `<style data-emotion="${emotionKey} ${ids.join(' ')}">${css}</style>`;
const output = `<!DOCTYPE html>
<head>
${emotionStyleTags}
</head>
<html>
<body>
${markup}
</body>
</html>
`;
response.setHeader('Content-Type', 'text/html');
response.write(output);
response.status(200);
response.end();
} Some more context: we have to use |
If you want me to take a look at this please prepare this in a runnable form. I need to be able to jump into debugging this quickly - otherwise, I simply won't be able to afford the time spent on setting this situation up.
This sounds like you are on the right track. I don't know though why it doesn't work. |
Your response doesn't read very friendly. I am reporting a bug. If you want to help me, provide instructions on what you consider runnable. Do you have a server side rendering codepen? Emotion documentation is very broken when it comes to SSR. You shouldn't blame the users. |
That certainly wasn't my intention.
A CodeSandbox/StackBlitz or a repository that I could clone.
You can't blame a free laborer either 🤷♂️ I'm willing to help you out - even though I don't have to since I don't have any obligation to do so. I like helping people though but I just can't afford to spend more time on it than necessary. That's a perhaps harsh truth but this is just a side project that I maintain and I have a day job and a family to take care of on top of that. |
I do understand that there are other circumstances and we aren't all unemployed, rich people with nothing but time on our hands. I have a job and a family, too. And I was taken from them by dealing with an oncall issue with the visuals on our production site getting corrupted. After troubleshooting for a few hours, it boiled down to me filing this bug, and it was already 1am my time. So please understand that you're not the only one who's frustrated here. That being said here's a blitz for you to fork: https://stackblitz.com/edit/node-z8fb7h?file=emotionBug3133.tsx which shows the issue that I can't find a solution to. Code copied here for posterity, and so that other can find this by searching: import createEmotionCache from '@emotion/cache';
import { injectGlobal } from '@emotion/css';
import { CacheProvider as EmotionCacheProvider } from '@emotion/react';
import { extractCritical } from '@emotion/server';
import type { FC } from 'react';
import { renderToString } from 'react-dom/server';
const App: FC<{ bgColor: string }> = ({ bgColor }) => {
injectGlobal(`body { background-color: ${bgColor}; }`);
return <>Dummy App</>;
};
function renderStyle(color: string): string {
const emotionKey = 'my-emotion';
const emotionCache = createEmotionCache({ key: emotionKey });
const reactMarkup = (
<EmotionCacheProvider value={emotionCache}>
<App bgColor={color} />
</EmotionCacheProvider>
);
const markup = renderToString(reactMarkup);
const { ids: _ids, css } = extractCritical(markup);
return css;
}
/** For investigation of https://github.com/emotion-js/emotion/issues/3133
*
* Should print:
*
* results: [
'body{background-color:blue;}',
'body{background-color:green;}',
'body{background-color:blue;}'
]
*
* But prints:
*
* results: [
'body{background-color:blue;}',
'body{background-color:blue;}body{background-color:green;}',
'body{background-color:blue;}body{background-color:green;}'
]
*
*/
function main(): void {
const results = [renderStyle('blue'), renderStyle('green'), renderStyle('blue')];
console.info({ results });
}
try {
main();
} catch (error) {
console.error(error);
} Note that my comment about the documentation being bad, is that following it literally has no results. It doesn't work, as described in this bug: #2731. I'm already very happy that I'm able to use emotion SSR for a happy path. |
I'm not really frustrated. At this point, I'm kinda just used to getting reports of this nature and I'm fine with it. It's just that to be able to assist with your problems (related to your job), I need to get that runnable repro case. Without it, I just can't justify spending time on an issue like this. While my statement might sound harsh or something - please bear in mind that that's truly not my intention at all. I'm just static facts from my PoV. I'm also not a native speaker so my written language might sound more rough on the edges than it is supposed to. That being said... now I see the problem. You can't use It might also just be easier to use However, you mentioned this:
And that's something I don't understand - or rather I don't understand why you have to do it. So if the suggestions above don't help you then please tell me more about this requirement.
You probably should be able to do this on |
I see. I can't control the library's usage of For context: my team owns a website that uses a component library that styles components using functions from |
For others finding this thread, Here's what I'm doing to clear globally injected css from the cache: import { cache as emotionCache } from '@emotion/css';
for (const hash in emotionCache.inserted) {
const value = emotionCache.inserted[hash]!;
if (typeof value === 'boolean') continue;
// Skip any keyframe values because they look like they were injected globally
// even if they weren't.
if (value.includes('@keyframes')) continue;
// Skip values added through `css`. Those will always reference the hash.
if (value.includes(hash)) continue;
delete emotionCache.inserted[hash];
} but it does feel hacky and likely to break in future versions of emotion imho. Would love to know if there's a more robust way. Edit: I ended up not wiping all |
Current behavior:
injectGlobal
from@emotion/css
retains injections from another emotion server!To reproduce:
It's a server-side rendered app.
Render code:
Calling http://localhost will render text on blue background (because that's the default).
Calling http://localhost/?background-color=yellow will render a yellow background
Calling http://localhost again will keep rendering yellow background even though it should be blue!
Expected behavior:
It should render the background compatible with the the current invocation, and not use state cache state for global injection.
Note that I tried to make a new cache every render, i.e.
const emotionCache = createEmotionCache({ key: 'marketing-web-emotion' });
but that just doesn't work. No warnings, errors, nor content.If nothing else, it would be nice to be able to reset the cache, but that also doesn't seem possible. I tried inspecting cache's
inserted
andregistered
properties, but they don't contain globally injected styles.Environment information:
react
version: 18.2@emotion/react
version: 11.9.0The text was updated successfully, but these errors were encountered: