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

TypeError: Cannot read property 'key' of undefined on server side render #1185

Closed
jooj123 opened this issue Jan 21, 2019 · 10 comments
Closed

Comments

@jooj123
Copy link
Contributor

jooj123 commented Jan 21, 2019

  • emotion version: @emotion/core: 10.0.6
  • react version: 16.4.2

Relevant code:

const Carousel = () => {
  return <div css={{
    backgroundColor: 'hotpink',
    '&:hover': {
      color: 'lightgreen'
    }
  }}>Hello</div>;
};

What you did:

Seems to be failing for server side render (see error in What happened)
Works on client render.

I tried to migrate from emotion 9 to 10.
I have moved over the component code to use @emotion/core
and used the import:

/** @jsx jsx */
import { css, jsx } from '@emotion/core';

I have also removed all the server side render code associated with emotion 9 (eg: renderStylesToString)

Maybe im missing something?

What happened:

Got this error on server side render (client render is ok):

TypeError: Cannot read property 'key' of undefined
    at insertStyles (webpack-internal:///./node_modules/@emotion/utils/dist/utils.esm.js:17:25)
    at render (webpack-internal:///./node_modules/@emotion/core/dist/core.esm.js:122:82)
    at eval (webpack-internal:///./node_modules/@emotion/core/dist/core.esm.js:163:10)
    at Object.eval [as children] (webpack-internal:///./node_modules/@emotion/core/dist/core.esm.js:83:18)
    at ReactDOMServerRenderer.render (webpack-internal:///../fe-build/node_modules/react-dom/cjs/react-dom-server.node.development.js:3290:55)
    at ReactDOMServerRenderer.read (webpack-internal:///../fe-build/node_modules/react-dom/cjs/react-dom-server.node.development.js:3057:29)
    at renderToString (webpack-internal:///../fe-build/node_modules/react-dom/cjs/react-dom-server.node.development.js:3524:27)
    at Object.eval [as serverRender] (webpack-internal:///../fe-build/lib/fe-server/demo/server.js:37:89)
    at render (/Users/martin.jujou/Documents/projects/fe-build/lib/server.js:76:62)
    at Layer.handle [as handle_request] (/Users/martin.jujou/Documents/projects/fe-build/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/martin.jujou/Documents/projects/fe-build/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/Users/martin.jujou/Documents/projects/fe-build/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/Users/martin.jujou/Documents/projects/fe-build/node_modules/express/lib/router/layer.js:95:5)
    at /Users/martin.jujou/Documents/projects/fe-build/node_modules/express/lib/router/index.js:281:22
    at param (/Users/martin.jujou/Documents/projects/fe-build/node_modules/express/lib/router/index.js:354:14)
    at param (/Users/martin.jujou/Documents/projects/fe-build/node_modules/express/lib/router/index.js:365:14)

Reproduction:

Not sure if this is associated with our internal webpack tooling
Hard to reproduce on a code sandbox link with our internal tooling

Problem description:

See above.

Suggested solution:

? Not sure

@tkh44
Copy link
Member

tkh44 commented Jan 22, 2019

My first guess is that you still have some old emotion imports and are calling the older css function somewhere. That error stack points here: https://github.com/emotion-js/emotion/blob/master/packages/utils/src/index.js#L28

It might be worth it to set a conditional breakpoint there in your app to break when !cache. Maybe you could look at the stack trace and track down the errant call.

Looking at this more there may be some difference in the entry point of the App on the server and client. Maybe the renderToString call is not calling the "true" top level component or a component above the one being rendered is calling emotion. Maybe an old Global styles call?

@badrey
Copy link

badrey commented Jan 22, 2019

The same issue for our project. We did not upgrade from 9 to 10. We use 10 version right away. Fails on SSR with error:

TypeError: Cannot read property 'key' of undefined
at Object.insertStyles (/Users/user/misc/code/mobile/web/node_modules/@emotion/utils/dist/utils.cjs.dev.js:18:25)
at render (/Users/user/misc/code/mobile/web/node_modules/@emotion/core/dist/core.cjs.dev.js:111:21)
at /Users/user/misc/code/mobile/web/node_modules/@emotion/core/dist/core.cjs.dev.js:152:10
at Object.children (/Users/user/misc/code/mobile/web/node_modules/@emotion/core/dist/core.cjs.dev.js:72:18)
at ReactDOMServerRenderer.render (/Users/user/misc/code/mobile/web/node_modules/react-wildcat-handoff/node_modules/react-dom/cjs/react-dom-server.node.development.js:2446:55)
at ReactDOMServerRenderer.read (/Users/user/misc/code/mobile/web/node_modules/react-wildcat-handoff/node_modules/react-dom/cjs/react-dom-server.node.development.js:2307:19)
at Object.renderToString (/Users/user/misc/code/mobile/web/node_modules/react-wildcat-handoff/node_modules/react-dom/cjs/react-dom-server.node.development.js:2679:25)
at serverRenderPromiseResult (/Users/user/misc/code/mobile/web/node_modules/react-wildcat-handoff/src/utils/serverRender.js:103:72)
at
at process._tickCallback (internal/process/next_tick.js:188:7)

After debugging we found a hack in Emotion sources in core.cjs.dev.js file if we change line 22 from
var EmotionCacheContext = React.createContext(isBrowser ? createCache() : null);
to
var EmotionCacheContext = React.createContext(createCache());
It works.
But it is not for production. Could you please advice what is the best resolution here?

@jooj123
Copy link
Contributor Author

jooj123 commented Jan 22, 2019

After some time debugging - I have noticed this is due to an old dependancy of babel-plugin-emotion lying around so my SSR issue is fixed

I also noticed I needed to install @emotion/babel-utils because after I updated babel-plugin-emotion it said it was missing - which doesn't seem to be documented here:
https://github.com/emotion-js/emotion/tree/master/packages/babel-plugin-emotion

Should I update the docs?

I think also the original error message can be improved - maybe it can somehow detect you have old deps based on the code path

@Andarist
Copy link
Member

Are you sure @emotion/babel-utils are needed? Seems like some old package which shouldnt be used right now.

@BohdanHulchack
Copy link

Same error in my project.
Just using import:

/** @jsx jsx */
import {jsx} from '@emotion/core';

and add simple style object:

{
        height: 250,
        marginLeft: "auto",
        marginRight: "auto",
        width: 300,
    }

Looks like in SSR run EmotionCacheContext is null.
In browser run createCache() returns undefined.
And this case is not handled.

@jooj123
Copy link
Contributor Author

jooj123 commented Jan 25, 2019

I removed @emotion/babel-utils and also removed babel-plugin-emotion then upgraded our internal tooling to babel 7 (we were stuck on babel 6 for a while .. long story) then added @emotion/babel-preset-css-prop preset (because we dont want to use pragma anyway) and everything works smoothly now 🎉

Not sure if this will help anyone else or even if its related to the error message I was getting originally (maybe it was all some sort of co-incidence)

I still think that there should be better error messages to indicate something is erroneous or missing

@aaaa0441
Copy link

I encountered a similar error. Some of my transitive dependencies are respectively depending on Emotion 9 & 10. Took me days before I figured out that the error was actually caused by a rogue webpack plugin breaking correct module resolution. Thus making calls to wrong version of the emotion core or util dependency.

@jooj123 jooj123 closed this as completed Jul 30, 2019
@winstondispatch
Copy link

I also ran into this error while running mocha tests, so I needed to make emotion think I was running on a browser by adding global.HTMLElement = window.HTMLElement; to my jsdom setup.

@Andarist
Copy link
Member

@winstondispatch could you prepare a repro case for your problem and raise a new issue with it?

@jmrossy
Copy link

jmrossy commented May 31, 2020

Same problem for me when running tests via Jasmine + JSDOM but the suggestion from @winstondispatch above solved it!

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

8 participants