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

babel-preset: Support plugin-transform-react-jsx's automatic runtime #1969

Closed
FLGMwt opened this issue Aug 12, 2020 · 1 comment
Closed

babel-preset: Support plugin-transform-react-jsx's automatic runtime #1969

FLGMwt opened this issue Aug 12, 2020 · 1 comment

Comments

@FLGMwt
Copy link
Contributor

FLGMwt commented Aug 12, 2020

The problem

@babel/plugin-transform-react-jsx powers the transformation of JSX to standard JavaScript method invocations: <div /> => React.createElement('div').

@emotion/babel-preset-css-prop is a babel preset that wraps the JSX transform configuration to change the default JSX pragma (React.createElement) to a custom pragma (___EmotionJSX) defined in @emotion/core.

React 17 introduces an element creation paradigm which is an alternative to React.createElement. It is described in the Create Element Changes RFC and is implemented for React itself in this PR. The new element creation paradigm can be used with a new option in the @babel/plugin-transform-react-jsx.

The current @emotion/babel-preset-css-props configuration and @emotion/core's jsx transform are built for the React.createElement paradigm, now referred to as the "classic JSX runtime". This configuration and transform implementation are incompatible with the new "automatic JSX runtime" option.

I would like to use the automatic JSX runtime option with the emotion CSS prop.

Proposed solution

I've done some digging and I think I have a handle on what's required:

@emotion/babel-preset-css-props should check for options.runtime === 'automatic

Currently, babel-preset-css-props forwards all jsx plugin options but also configures pragma and pragmaFrag https://github.com/emotion-js/emotion/blob/master/packages/babel-preset-css-prop/src/index.js#L26. These options are incompatible with the automatic runtime. We shouldn't send them when runtime is automatic. Instead, we should set the importSource option to @emotion/core.

We also don't need pragmatic because its role is now handled by the jsx transform in automatic mode.

@emotion/core should implement and expose jsx-runtime

The automatic runtime expects the transform modules at {importSource}/jsx-runtime / {importSource}/jsx-dev-runtime, where importSource is defaulted to React. We probably want to add these entrypoints to @emotion/core alongside the existing jsx function. preconstruct supports this.

These jsx-runtime modules should mirror the existing jsx behavior of providing the emotion wrapper and theme context, but implement the jsx-runtime interface instead. The React implementation is probably the best reference here: facebook/react#18299.

Alternative solutions

We could wait for more guidance from the react team on implementing jsx-runtime.

I do think this will need to happen eventually to support future functionality the new create element paradigm was initiated to enable.

Additional context

I only just started looking into this as a result of the React 17 release and I don't have a great handle on all the parts involved. Please correct me if I messed something up 😬

@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
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

2 participants