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

"React is not defined" when using a custom _app.tsx and .babelrc using React 17 #18096

Closed
NBruhno opened this issue Oct 21, 2020 · 37 comments · Fixed by #19136
Closed

"React is not defined" when using a custom _app.tsx and .babelrc using React 17 #18096

NBruhno opened this issue Oct 21, 2020 · 37 comments · Fixed by #19136
Assignees
Milestone

Comments

@NBruhno
Copy link

NBruhno commented Oct 21, 2020

Bug report

After upgrading to React 17, I can no longer compile my project with a custom .babelrc file without importing React in every *.tsx file. Having a _app.tsx file seems to be required to reproduce the issue. The error returned is:

Error occurred prerendering page "/". Read more: https://err.sh/next.js/prerender-error
ReferenceError: React is not defined
    at MyApp.render (/home/bruhno/projects/react-not-defined/.next/server/pages/_app.js:297:70)
    at d (/home/bruhno/projects/react-not-defined/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:35:231)
    at bb (/home/bruhno/projects/react-not-defined/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:36:16)
    at a.b.render (/home/bruhno/projects/react-not-defined/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:42:43)
    at a.b.read (/home/bruhno/projects/react-not-defined/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:41:83)
    at exports.renderToString (/home/bruhno/projects/react-not-defined/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:52:138)
    at Object.renderPage (/home/bruhno/projects/react-not-defined/node_modules/next/dist/next-server/server/render.js:50:851)
    at Function.getInitialProps (/home/bruhno/projects/react-not-defined/.next/server/pages/_document.js:273:19)
    at loadGetInitialProps (/home/bruhno/projects/react-not-defined/node_modules/next/dist/next-server/lib/utils.js:5:101)
    at renderToHTML (/home/bruhno/projects/react-not-defined/node_modules/next/dist/next-server/server/render.js:50:1142)

I'm not sure if TypeScript is related to the issue, but I've simply copy pasted minimal configuration from my own project which is where I experienced the issue.

To Reproduce

I've created the following repo to reproduce the error: https://github.com/NBruhno/nextjs-react-not-defined

  1. run yarn
  2. run yarn dev or yarn build
  3. See error in the terminal and on the rendered page

Expected behavior

I could before React 17 run my repo without having to import React in my .tsx files unless explicitly referring to some functions, with my own custom .babelrc file.

System information

  • OS: Windows running WSL: Ubuntu-20.04
  • Version of Next.js: 9.5.5
  • Version of Node.js: v12.17.0
@NBruhno
Copy link
Author

NBruhno commented Oct 21, 2020

I can reproduce the issue without using TypeScript: https://github.com/NBruhno/nextjs-react-not-defined/tree/not-typescript

@vasco3
Copy link
Contributor

vasco3 commented Oct 21, 2020

I'm getting a similar error but i'm not using TS

@PabloSzx
Copy link
Contributor

PabloSzx commented Oct 27, 2020

A workaround is to modify your .babelrc adding "@babel/plugin-transform-react-jsx" plugin manually, you don't need to add it to your package.json, since Next.js itself has it as a dependency

{
  "presets": ["next/babel"],
  "plugins": [
    [
      "@babel/plugin-transform-react-jsx",
      {
        "runtime": "automatic"
      }
    ]
  ]
}

It doesn't seem to work all the time, and _document.tsx has problems too

@vasco3
Copy link
Contributor

vasco3 commented Oct 27, 2020

my error was caused because I was using <React.Fragment> in one of my js files. I replaced it with <> and it works

@lucax88x
Copy link

Just upgraded to next 10 and react 17, having the same issue with a custom _app.

I am the one of the guys using typescript, if it can helps somehow.

@lucax88x
Copy link

I think the problem is when you use a custom .babelrc with React 17.

If you just upgrade to next 10, keeping react 16 and custom babelrc, works smoothly.
As soon as you upgrade to React 17, keeping the custom babelrc, it breaks, but if you remove babelrc it works.

Maybe we need to add something to it?

@lucax88x
Copy link

This is even funnier, if you import React in the page, it works. :D

@NBruhno
Copy link
Author

NBruhno commented Oct 28, 2020

This is even funnier, if you import React in the page, it works. :D

Please calm down with the replies, we are getting notified every time someone posts (hoping for a solution). If you have anything to add which might help narrow down or resolve the issue, which is not already described in the issue initially or in the comments, please do add it.

@lucax88x
Copy link

Sorry, maybe I was unintentionally malicious. apologies.

I just wanted to say that if you import React, it actually works, so this can help understand the problem or any guy occurring in the issue.

@lukeshumard
Copy link
Contributor

I am also running into this issue when trying to upgrade to React 17, but I'm not using a custom .babelrc. As a hotfix, I tried to explicitly import React in my _app.js file, but this does not resolve the issue when running next build. Typescript in my project is limited to API routes, so that doesn't seem to be the culprit either.

While related to a custom .babelrc, I think this seems more broad. If I had to guess as to why this happens, I would assume it is related to React 17 support from other dependencies. I'll try and put together a reproducible demo for this later in the week to diagnose.

@Timer Timer added this to the iteration 11 milestone Oct 28, 2020
@kyle-mccarthy
Copy link

my error was caused because I was using <React.Fragment> in one of my js files. I replaced it with <> and it works

I am actually having the opposite of this. I was using <> but replacing that with Fragment (ex <Fragment>...</Fragment>) seems to fix the issue.

Additionally, adding import React from 'react' to files using <> also fixes the problem. My project has over 200 tsx files though so it isn't exactly an option.

Also this doesn't seem to be directly related to next@10. I only see them problem when upgrading react and react-dom to 17.

babel.config.js

module.exports = {
  presets: ['next/babel', '@emotion/babel-preset-css-prop'],
  plugins: [
    '@emotion',
    'babel-plugin-transform-typescript-metadata',
    ['@babel/plugin-proposal-decorators', { legacy: true }],
    ['@babel/plugin-proposal-class-properties', { loose: true }],
    '@babel/plugin-proposal-optional-chaining',
    '@babel/plugin-proposal-numeric-separator',
  ],
};

@BernardA
Copy link

I just updated using npm install next@latest react@latest react-dom@latest and I am getting the same error.

Note that I do not have any custom babel config nor am I using Typescript.

I can also confirm that if I import React from 'react'; it seem to work, at least to the extent that the error is thrown in another component that does not have that import ( this is an app that came from another framework and there are still several components with that import)

@BernardA
Copy link

I went to the trouble of adding back the import React from 'react'; on all components needed for the homepage ( including _app.js and _document.js ) and it works

@F3WS
Copy link

F3WS commented Oct 30, 2020

I've just ran in to this issue, the console pointed to an old 'Class' component I had kicking around, importing React as mentioned above or converting to a functional component solved the problem.

jtomchak added a commit to cloudinary-devs/media-jams that referenced this issue Oct 30, 2020
@Timer Timer modified the milestones: iteration 11, iteration 12 Oct 30, 2020
@mdirolf
Copy link

mdirolf commented Oct 30, 2020

Might be related to @emotion/babel-preset-css-prop in babel config - @NBruhno's repro has it, as does @kyle-mccarthy's post, as does my app which is also running into this.

@NBruhno
Copy link
Author

NBruhno commented Nov 1, 2020

After updating to the latest version of emotionjs (10.1.0), yarn dev runs fine, but the production build fails for each page during static page generation:

[next] Unhandled error during request: ReferenceError: _jsxs is not defined
[next]     at _app_MyApp.render (/home/bruhno/projects/homepage/.next/serverless/pages/index.js:8213:5)
[next]     at d (/home/bruhno/projects/homepage/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:35:231)
[next]     at bb (/home/bruhno/projects/homepage/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:36:16)
[next]     at a.b.render (/home/bruhno/projects/homepage/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:42:43)
[next]     at a.b.read (/home/bruhno/projects/homepage/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:41:83)
[next]     at exports.renderToString (/home/bruhno/projects/homepage/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:52:138)
[next]     at Object.renderPage (/home/bruhno/projects/homepage/node_modules/next/dist/next-server/server/render.js:50:851)
[next]     at Function.getInitialProps (/home/bruhno/projects/homepage/.next/serverless/pages/index.js:3704:19)
[next]     at loadGetInitialProps (/home/bruhno/projects/homepage/node_modules/next/dist/next-server/lib/utils.js:5:101)
[next]     at renderToHTML (/home/bruhno/projects/homepage/node_modules/next/dist/next-server/server/render.js:50:1142)

After updating emotionjs, I added the following to my .babelrc to make it use their new implementation for the JSX runtime:

  "presets": [
    "next/babel",
    [
      "@emotion/babel-preset-css-prop",
      {
        "runtime": "automatic"
      }
    ]
  ]

I thought that maybe the error is from the css optimization during the production build, but turning that off gives the same error.

Repo here: https://github.com/NBruhno/nextjs-react-not-defined/tree/emotion-update

@ccambournac
Copy link

Waiting for the bug to be fixed, you may use Webpack's ProvidePlugin for React package inside a custom next.config.js file, like so:

new webpack.ProvidePlugin({
	React: 'react'
})

@karlhorky
Copy link
Contributor

karlhorky commented Nov 1, 2020

@NBruhno I think the new _jsxs is not defined error could be a bug in the new Emotion Babel preset version.

Reported here: emotion-js/emotion#2064

@karlhorky
Copy link
Contributor

karlhorky commented Nov 1, 2020

As Andarist figured out, it seems like if you reorder the next/babel preset to the end, the build no longer fails with _jsxs is not defined:

babel.config.js

module.exports = {
  presets: [
    ['@emotion/babel-preset-css-prop', { runtime: 'automatic' }],
    'next/babel',
  ],
};

‼️ Important Edit: However, this causes the Emotion CSS props to fail :(

Screen Shot 2020-11-01 at 16 41 04

cc @NBruhno

karlhorky added a commit to karlhorky/next-js-example-sep-2020 that referenced this issue Nov 1, 2020
@NBruhno
Copy link
Author

NBruhno commented Nov 1, 2020

As Andarist figured out, it seems like if you reorder the next/babel preset to the end, it starts working again:

Unfortunately @karlhorky, if I change up the order of the presets so "next/babel" is not first, a good portion of my other code breaks as well. So there is something weird going on here. I can share the error here but I'm not sure it provides any valid information as it seems like it becomes unable to parse some files compared to what it was previously able to:

[next] Failed to compile.
[next]
[next] ./src/containers/api/middleware/authenticate.ts:62:13
[next] Syntax error: Unexpected token, expected "}"
[next]
[next]   60 |   try {
[next]   61 |           const decodedToken = <Token>JWT.verify(getToken(), config.auth.publicKey, {
[next] > 62 |                   algorithms: ['RS256'],
[next]      |                             ^
[next]   63 |                   audience: ['https://bruhno.com', 'https://bruhno.dev'],
[next]   64 |                   issuer: 'https://bruhno.dev',
[next]   65 |                   typ: type,
[next]
[next]
[next] > Build error occurred
[next] Error: > Build failed because of webpack errors
[next]     at build (/home/bruhno/projects/homepage/node_modules/next/dist/build/index.js:15:918)

Mind you, this is from my personal project and not the minimal repro, since that doesn't appear to fail.
https://github.com/NBruhno/nextjs-react-not-defined/tree/emotion-update

Edit* Actually, having it with "next/babel" first in my minimal repro appears to work. But switching up the order here will break it so the styles are not applied and instead the css prop is resolved to:

<h1 css="You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop).">...</h1>

So it does look like a battle of who gets to transform the JSX.

@karlhorky
Copy link
Contributor

@Timer One further clue that Andarist found in the other issue is that this error is also happening with other presets:

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

@karlhorky
Copy link
Contributor

Ok, one last possible way to do it.

Not the most beautiful configuration, but 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'],
};

@NBruhno does this work for you?

@NBruhno
Copy link
Author

NBruhno commented Nov 1, 2020

Ok, one last possible way to do it.

Not the most beautiful configuration, but 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'],
};

@NBruhno does this work for you?

@karlhorky I don't see any new issues or failures building it or running it when using '@emotion/core' as the importSource for the preset. So this does solve the issue as far as I can tell. But there does seem to be some kind of clash with the two babel presets. I am unsure if this issue is valid for this bug at this point.

@Vadorequest
Copy link
Contributor

Vadorequest commented Nov 2, 2020

If you need a reproduction case, look at UnlyEd/next-right-now#197

My config worked fine, until I tried upgrading to the latest 10.1.0 (see UnlyEd/next-right-now@225b3c8)

I'll let the branch as-it and wait for a proper solution.

The workaround did work. (see UnlyEd/next-right-now@40b18aa)

@Andarist
Copy link
Contributor

Andarist commented Nov 3, 2020

@Timer I've done a fair share of debugging this issue and so far it looks like a bug in Babel's config loading logic. It doesn't quite deduplicate plugins in this configuration and according to Babel's docs only the last one defined should be preserved: https://babeljs.io/docs/en/options#pluginpreset-merging

I've dug up the PR that has implemented the logic for this flattening but it doesn't contain a test case similar to the situation we are dealing with here. I'm also poking Babel team about this to see if this is intended or a bug (I'm strongly inclined to believe that it's the latter).

@Andarist
Copy link
Contributor

Andarist commented Nov 5, 2020

I've written down a lengthy explanation of the problems and the proposed solution here: #18847

@Migggz
Copy link

Migggz commented Nov 8, 2020

It appears without using Typescript.
I was using React.Component in _app HoC without importing React.
it works now fine after importing React

@karlhorky
Copy link
Contributor

karlhorky commented Nov 18, 2020

I'm trying to create the canonical example for Emotion 11 with React 17 and Next.js 10 in #18620

So @Andarist and @Timer, am I understanding correctly when I read the Emotion docs (introduced in emotion-js/emotion#2074) that the following configuration is the current recommendation for using the automatic JSX runtime with Next.js and Emotion?

.babelrc

{
  "presets": [
    [
      "next/babel",
      {
        "preset-react": {
          "runtime": "automatic",
          "importSource": "@emotion/react"
        }
      }
    ]
  ],
  "plugins": ["@emotion/babel-plugin"]
}

Also, I'm assuming that I only need @emotion/babel-plugin with this configuration, not the full @emotion/babel-preset-css-prop:

package.json

{
  "name": "with-emotion",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  },
  "keywords": [],
  "author": "Thomas Greco",
  "license": "MIT",
  "devDependencies": {
-    "@emotion/babel-preset-css-prop": "11.0.0"
+    "@emotion/babel-plugin": "11.0.0"
  },
  "dependencies": {
    "@emotion/react": "11.1.1",
    "@emotion/styled": "11.0.0",
    "next": "latest",
    "react": "^17.0.1",
    "react-dom": "^17.0.1"
  }
}

@Andarist
Copy link
Contributor

Sounds about right - @emotion/babel-preset-css-prop should only be used when you want to use the classic runtime.

@supperioguy

This comment has been minimized.

@mateegojra
Copy link

my error was caused because I was using <React.Fragment> in one of my js files. I replaced it with <> and it works

this worked for me... I'm using next JS

mcgoooo added a commit to mcgoooo/mine-sweeper that referenced this issue Jan 28, 2021
mcgoooo added a commit to mcgoooo/mine-sweeper that referenced this issue Jan 28, 2021
@mrnossiom
Copy link

A workaround is to modify your .babelrc adding "@babel/plugin-transform-react-jsx" plugin manually, you don't need to add it to your package.json, since Next.js itself has it as a dependency

{
  "presets": ["next/babel"],
  "plugins": [
    [
      "@babel/plugin-transform-react-jsx",
      {
        "runtime": "automatic"
      }
    ]
  ]
}

It doesn't seem to work all the time, and _document.tsx has problems too

Thanks, this helped me so much...

@MrJadaml
Copy link

Just reordering next/babel to be last fixed the issue for me.

{
  'presets': [
    // WAS ORIGINALLY HERE
    '@babel/preset-react',
    '@babel/preset-typescript',
    'next/babel',  // NOW HERE 
  ]
}

Next v11.1.0
React v17.0.2

@timneutkens
Copy link
Member

@MrJadaml that babelrc config should probably be removed. next/babel handles both React and TypeScript.

@Powersource
Copy link

I was getting this after updating to React 17

> Build error occurred
ReferenceError: React is not defined
at Module.RNiq (/vercel/path1/.next/server/pages/index.js:1072:18)
at __webpack_require__ (/vercel/path1/.next/server/pages/index.js:23:31)
at Object.15 (/vercel/path1/.next/server/pages/index.js:180:18)
at __webpack_require__ (/vercel/path1/.next/server/pages/index.js:23:31)
at /vercel/path1/.next/server/pages/index.js:91:18
at Object.<anonymous> (/vercel/path1/.next/server/pages/index.js:94:10)
at Module._compile (internal/modules/cjs/loader.js:1072:14)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1101:10)
at Module.load (internal/modules/cjs/loader.js:937:32)
at Function.Module._load (internal/modules/cjs/loader.js:778:12) {
type: 'ReferenceError'
}

I fixed it with this commit where I fixed some assumptions that React was a global (I still didn't have to import it to just use jsx) cobudget/cobudget@1c3bfb9

@balazsorban44
Copy link
Member

This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@vercel vercel locked as resolved and limited conversation to collaborators Jan 27, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet