Emotion: Babel CSS Prop Preset: _jsxs is not defined

Created on 1 Nov 2020  路  14Comments  路  Source: emotion-js/emotion

Current behavior:

Using @emotion/[email protected] with the { runtime: 'automatic' } option, the Next.js build fails with the following error:

[   =] info  - Generating static pages (0/3)
Error occurred prerendering page "/about-us". Read more: https://err.sh/next.js/prerender-error
ReferenceError: _jsxs is not defined
    at MyApp (next-js-example-sep-2020/.next/server/pages/_app.js:174:3)
    at d (next-js-example-sep-2020/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:33:498)
    at bb (next-js-example-sep-2020/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:36:16)
    at a.b.render (next-js-example-sep-2020/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:42:43)
    at a.b.read (next-js-example-sep-2020/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:41:83)
    at exports.renderToString (next-js-example-sep-2020/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:52:138)
    at Object.renderPage (next-js-example-sep-2020/node_modules/next/dist/next-server/server/render.js:50:851)
    at Function.getInitialProps (next-js-example-sep-2020/.next/server/pages/_document.js:273:19)
    at loadGetInitialProps (next-js-example-sep-2020/node_modules/next/dist/next-server/lib/utils.js:5:101)
    at renderToHTML (next-js-example-sep-2020/node_modules/next/dist/next-server/server/render.js:50:1142)

To reproduce:

  1. Clone this repo and run yarn: https://github.com/upleveled/next-js-example-sep-2020
  2. Run yarn build

Information for posterity: the bug can be seen at revision f0488edf42a9daebb78a56d10675d0e1a9560831

Expected behavior:

No error.

Environment information:

  • react version: 17.0.1
  • @emotion/core version: 10.1.0
  • @emotion/babel-preset-css-prop version: 10.1.0

Ref: https://github.com/emotion-js/emotion/issues/2041

Also reported at the vercel/next.js repo: https://github.com/vercel/next.js/issues/18096#issuecomment-720061067

bug

Most helpful comment

I've been debugging this further and all signs point to a bug in Babel's config loading logic. Trying to get to the bottom of this but might take a while.

All 14 comments

Thanks for the repro case! I'm looking into this.

I don't know yet why this happens - some components are correctly handled and some are not (so my bet is that it's a bug somewhere, and it's not likely that it's in Emotion).

If you reorder your Babel presets things start to work (so Emotion preset comes before next/babel).

Investigating further...

One thing I did notice is that the component in question (in pages/_app.tsx) has a shorthand fragment in it (<>), and this is also something they mention in https://github.com/vercel/next.js/issues/18096 ...

Edit: However, both changing the fragment to use Fragment (imported from 'react') and also changing it to a <div> don't help here...

If you reorder your Babel presets things start to work (so Emotion preset comes before next/babel).

Ah, cool! This is a good insight! So I guess possibly the two presets are conflicting.

Will cross-post to the Next.js issue.

This also happens with:

module.exports = {
  presets: [
    "next/babel",
    [
      "@babel/preset-react",
      { runtime: "automatic" },
    ],
  ],
};

Therefore I'm closing this issue as it doesn't seem to be related to Emotion at all. This doesn't mean that I won't investigate this further though.

Right yeah, it looks like an issue with the next/babel preset. Thanks for investigating!

It seems like re-ordering doesn't actually work - although there are no errors, it ends up messing with the Emotion props in the production build:

Screen Shot 2020-11-01 at 16 41 04

Ah, right. Im on mobile right now and will investigate later but i believe that u can fix this by passing importSource option through next鈥檚 preset (smth like ['next/babel', { 'preset-react': { importSource: '@emotion/core' } }] should do the trick). To regain some Emotion-specific things like source maps etc u can just add Emotion's plugin (not the preset!) to your config.

This most likely happens because JSX-related plugins are duplicated and fight with each other in the config in that repro case.

Confirmed, this does work. No build errors and no CSS prop [object Object] weirdness:

babel.config.js:

module.exports = {
  presets: [
    ['next/babel', { 'preset-react': { importSource: '@emotion/core' } }],
  ],
  plugins: ['emotion'],
};

Kind of unusual configuration though.

Depending on whether https://github.com/vercel/next.js/issues/18096 gets a nicer solution, and if this is the only way to do it, maybe I'll end up changing https://github.com/vercel/next.js/pull/18620 to use this instead...

I plan to figure out a better solution - for now, treat this as a temporary one.

G

I've been debugging this further and all signs point to a bug in Babel's config loading logic. Trying to get to the bottom of this but might take a while.

If you want you can check this PR with a lengthy explanation of the situation: https://github.com/vercel/next.js/pull/18847

I don't know yet why this happens - some components are correctly handled and some are not (so my bet is that it's a bug somewhere, and it's not likely that it's in Emotion).

If you reorder your Babel presets things start to work (so Emotion preset comes before next/babel).

Investigating further...

I was getting this error in my Next project and reordering the @babel/preset-react and next/babel presets worked for me. I don't use Emotion on it, thanks though @Andarist 鉂わ笍

You most likely shouldn't use @babel/preset-react & next/babel at the same time - the latter already contains the former one.

Was this page helpful?
0 / 5 - 0 ratings