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 17 + new JSX transform + JSX pragma/pragmaFrag #2041

Closed
Metroninja opened this issue Oct 11, 2020 · 26 comments
Closed

React 17 + new JSX transform + JSX pragma/pragmaFrag #2041

Metroninja opened this issue Oct 11, 2020 · 26 comments

Comments

@Metroninja
Copy link

Metroninja commented Oct 11, 2020

Current behavior:

I'm currently using a barebones nextJS deployment with React 17.0.0-rc.3 and have added emotion to the project. I wanted to test out the new JSX transform but I'm running into issues, whenever I set

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

in a component, I run into compilation issues in said file.
SyntaxError: pragma and pragmaFrag cannot be set when runtime is automatic.

my .babelrc file but is set below, and the issue is obviously with the value of runtime being set to automatic. that said, that's how babel 8 will be set moving forward, and also is what allows the removal of requiring React in every file.

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

I'm not sure if here, react, or the babel issues repo was the best to post in but settled here given it's an issue with emotion's setting of the pragma. I suspect a lot of this issue will be popping up soon once react 17 ships, so I thought i'd raise an issue so people aren't lost on day 1 after ripping out all of the 'import React from "react"` across their app and realizing they just made a huge mistake.

Environment information:

  • react version: 17.0.0-rc.3
  • emotion version: 10.0.35
@Andarist
Copy link
Member

U have configured globally the automatic runtime and it cannot be mixed with @jsx pragma. When React 17 gets published we are going to prepare a special entries compatible with it and u will be able to configure automatic runtime with Emotion or override per file with @jsxImportSource

@n8sabes
Copy link

n8sabes commented Oct 14, 2020

I modified my emotion style components to import the css prop manually. A bit of a pain, but got the project working again.

// Typescript
const MyComponent = styled.div`
    ${(props: any) => props.css}
`;

// Javascript
const MyComponent = styled.div`
    ${props => props.css}
`;

I had to do the following when inheriting from another component:

// Typescript
const MyComponent = styled((props: any) => <MyBaseComponent {...props} />)`
    ${(props: any) => props.css}
`;

// Javascript
const MyComponent = styled(props => <MyBaseComponent {...props} />)`
    ${props => props.css}
`;

@Andarist What is the the recommenced workaround in the interim? I did not have much luck with toolchain / build mods, and certainly don't want to eject the create-react-app baseline.

@Andarist
Copy link
Member

@n8sabes just to confirm - you are using a prerelease of CRA 4 and React 17, right? I'm afraid that I don't have a good recommendation for this situation yet. You could create a module like this: #1970 (comment) and use @jsxImportSource pragma to point to it, but it ain't a super pleasant experience. We may be forced to recommend that new pragma in combination with CRA once we implement new factories for React 17. It's a shame as it's significantly longer than the current one:

/** @jsx jsx */

vs

/** @jsxImportSource @emotion/react */

@n8sabes
Copy link

n8sabes commented Oct 14, 2020

Thanks @Andarist.

"react": "17.0.0-rc.2"
"react-scripts": "^4.0.0-next.98"

I checked out @jsxImportSource #1970. For now, I have my project working with the manual css prop injection so I can wait for the preferred solution. I mainly wanted to share a workaround with others, and also ask if you had anything better. So, it seems we have two workarounds, neither of which are super clean but work.

@dsngo
Copy link

dsngo commented Oct 18, 2020

facebook/react#20045
I am not sure if this totally relates to the emotion babel css presets prop. However I feel it appropriate to report here.

@robertosaenz
Copy link

Hi guys, I am new on react. I have the same issue when i adding @jsx jsx . How can i solve this.

`./src/components/UserIcon.tsx
SyntaxError: C:\Net Core Projects\QandA\frontend\src\components\UserIcon.tsx: pragma and pragmaFrag cannot be set when runtime is automatic.

1 | import React from 'react';
| ^
2 | /** @jsx jsx */
3 | import { css, jsx } from '@emotion/core';
4 | import userlogo from '../user.svg';`

@Andarist
Copy link
Member

Im working on fixing this - from both ends. We have a working PR with the support for new automatic runtimes and im working on a Babel PR to allow old pragmas to overwrite the configured runtime.

@karlhorky
Copy link

@Metroninja I guess this issue title can be edited to be "React 17" instead of "React 17 RC", now that v17 is out...

@karlhorky
Copy link

@Andarist do you have links for those PRs for those interested in following along?

@Metroninja Metroninja changed the title React 17 RC + new JSX transform + JSX pragma/pragmaFrag React 17 + new JSX transform + JSX pragma/pragmaFrag Oct 28, 2020
@Andarist
Copy link
Member

The one in Emotion is here: #1970
The discussion in Babel is here: babel/babel#12208

@karlhorky
Copy link

karlhorky commented Oct 29, 2020

Edit: The new version of @emotion/core and @emotion/babel-preset-css-prop (>=10.1.0) will allow opting into the new JSX runtimes by using such configuration:

.babelrc

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

Reference: #2063


For anyone who can use the Babel CSS preset instead of pragmas, this option seems to work:

  1. Install @emotion/babel-preset-css-prop
  2. Add a babel.config.js file with at least module.exports = { presets: ['@emotion/babel-preset-css-prop'] };
  3. Remove all of the /** @jsx jsx */ pragma comments (or similar)
  4. Remove any /** @jsxFrag React.Fragment */ comments (or similar)

At least it works with Next.js 10 + React 17...

More details here:

vercel/next.js#18461 (comment)

@ghost
Copy link

ghost commented Oct 30, 2020

Nice! For anyone who can use the Babel CSS preset instead of pragmas, this option seems to work:

  1. Install @emotion/babel-preset-css-prop
  2. Add a babel.config.js file with at least module.exports = { presets: ['@emotion/babel-preset-css-prop'] };
  3. Remove all of the /** @jsx jsx */ pragma comments (or similar)
  4. Remove any /** @jsxFrag React.Fragment */ comments (or similar)

At least it works with Next.js 10 + React 17...

More details here:

vercel/next.js#18461 (comment)

What about Typescript sir?

@karlhorky
Copy link

@arganaphangquestian This is working with TypeScript as well for me (note the files with .tsx extensions): https://github.com/upleveled/next-js-example-sep-2020/tree/main/pages

Are you or @PabloSzx having issues?

@andriyandriyan
Copy link

Nice! For anyone who can use the Babel CSS preset instead of pragmas, this option seems to work:

  1. Install @emotion/babel-preset-css-prop
  2. Add a babel.config.js file with at least module.exports = { presets: ['@emotion/babel-preset-css-prop'] };
  3. Remove all of the /** @jsx jsx */ pragma comments (or similar)
  4. Remove any /** @jsxFrag React.Fragment */ comments (or similar)

At least it works with Next.js 10 + React 17...

More details here:

vercel/next.js#18461 (comment)

I've tried with CRA 4 + Typescript but it doesn't work

@karlhorky
Copy link

Yes, it will not work with create-react-app, because of the limitation of not being able to change the Babel config. Read more here: https://emotion.sh/docs/css-prop#jsx-pragma

It does not have to do with TypeScript.

For these environments, a fix is required for the pragma (which is being worked on in the two pull requests above, apparently).

@fobbyal
Copy link

fobbyal commented Oct 30, 2020

I've gotten the following to work with CRA4. This tells babel to transpile the file using the old way

/** @jsxRuntime classic */
/** @jsx jsx */
import { jsx } from '@emotion/core'

@Andarist
Copy link
Member

Andarist commented Oct 30, 2020

Yes, this works - but I feel that this is far from ideal and I hope that we can still change the logic for this in Babel, but we'll see.

The better news is that with #1970 you should be able to just use this in this CRA4:

/** @jsxImportSource @emotion/core */

@karlhorky
Copy link

karlhorky commented Oct 31, 2020

That sounds great @Andarist :) Cool that #1970 is merged now!

I guess the plan will be to publish 10.x versions of @emotion/core and @emotion/babel-preset-css-prop with these changes?

Edit: Oh sorry, just saw the PR from the bot now with the versions 10.1.0: #2062

@Andarist
Copy link
Member

Yes, we only need to prepare a docs update that is being worked on here: #2063

@Andarist
Copy link
Member

Andarist commented Nov 1, 2020

I'm going to release @emotion/[email protected] with the support for the new runtimes in a moment so I'm going to close this issue now. If you encounter any problems with this please open new issues.

@Andarist Andarist closed this as completed Nov 1, 2020
@karlhorky
Copy link

Thanks @Andarist !

@karlhorky
Copy link

Seems like the new versions error out with _jsxs is not defined when running next build. Filed a new bug:

#2064

@przytrzask
Copy link

Hey, Thanks for solving this
Now it /** @jsxImportSource @emotion/core */ basically works for me in emotion 10.1.1
However I've got following ts errror on CRA4.0 with typescript
'React' refers to a UMD global, but the current file is a module. Consider adding an import instead.
Does anybody have any clue how to solve this?

@Andarist
Copy link
Member

Andarist commented Nov 3, 2020

Please take a look at the comments in this CRA issue, starting from this comment.

Migration everything at once is a little bit problematic, given different release schedules of various tools etc 😢

shgtkshruch added a commit to shgtkshruch/shgtkshruch.com that referenced this issue Nov 9, 2020
issue: emotion-js/emotion#2041 (comment)
```
9:50:10 PM: ./components/common/GitHub-Corner.tsx
9:50:10 PM: SyntaxError: /opt/build/repo/components/common/GitHub-Corner.tsx: pragma and pragmaFrag cannot be set when runtime is automatic.
9:50:10 PM: > 1 | /** @jsx jsx */
9:50:10 PM:     | ^
9:50:10 PM:   2 | import styled from '@emotion/styled'
9:50:10 PM:   3 | import { jsx, css } from '@emotion/core'
9:50:10 PM:   4 | import { mq } from '../variables'
9:50:10 PM: > Build error occurred
9:50:10 PM: Error: > Build failed because of webpack errors
9:50:10 PM:     at build (/opt/build/repo/node_modules/next/dist/build/index.js:15:918)
9:50:10 PM: error Command failed with exit code 1.
```
kodiakhq bot pushed a commit to vercel/next.js that referenced this issue Nov 19, 2020
kamermans pushed a commit to kamermans/next.js that referenced this issue Dec 14, 2020
@akshayr20
Copy link

Hey, Thanks for solving this
Now it /** @jsxImportSource @emotion/core */ basically works for me in emotion 10.1.1
However I've got following ts errror on CRA4.0 with typescript
'React' refers to a UMD global, but the current file is a module. Consider adding an import instead.
Does anybody have any clue how to solve this?

import React from 'react';
was no longer required, but with the typescript setting you are using I guess you still have to add above line in your code, else ts starts complaining

@tianhuil
Copy link

tianhuil commented Apr 5, 2022

It looks like emotion is working as an experimental feature. You have to next.config.js to

const nextConfig = {
  reactStrictMode: true,
  experimental: {
    emotion: true,
  },
}

module.exports = nextConfig

and adding jsxImportSource to tsconfig.json to

{
  "compilerOptions": {
    "jsxImportSource": "@emotion/react"
  },
}

I can confirm this works with [email protected]. See this merged PR

the-bears-field added a commit to the-bears-field/React that referenced this issue Oct 21, 2022
Emotion.jsxを新規作成
先頭に2行分コメントを記述し、古い方式で処理するよう設定
@emotion/reactのjsx、cssと、@emotion/styledのインポート処理を実施
Emotionコンポーネント生成
コンポーネント内でコンテナとタイトルのCSSを定義
コンテナはCSS in JSでの記述、
タイトルはインラインスタイルで記述
ボタンはStyled Componentsで記述し、コンポーネント外で変数を定義
App.jsxにEmotion.jsxのインポート処理を追加
Appコンポーネントの返り値にEmotionコンポーネントを追加

参考URL
https://www.udemy.com/course/react_stepup/learn/lecture/24823352
emotion-js/emotion#2041 (comment)
https://www.atnr.net/emotion-react-css-prop-error/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests