DEV Community

Cover image for NEW JSX TRANSFORM
melodyLeonard
melodyLeonard

Posted on

NEW JSX TRANSFORM

What is JSX?

JSX stands for JavaScript XML. A JavaScript wrapper around HTML tags. The JSX is more powerful than the traditional HTML.

It is built to allow React show more useful error and warning messages as well as other cool features that does'nt come with the traditional HTML.
You can read more about the cool feature of JSX in the React JSX Introduction

The New JSX Transform

JavaScript XML (JSX) which allows us to write HTML in react is not understood by the browser out of the box. Hence react developers rely on compilers like Babel or typescript to transform JSX code into regular JavaScript.
Even the preconfigured create react app toolkit include a JSX transform under the hood.

After the release of react 17, the Facebook team made an improvement to JSX transform. The team worked with babel to offer a new rewritten JSX transform for react users.

With the new transform, one can use JSX without importing react
Also the compiled output may also improve the bundle size which may depend on ones setup.

This update as promised by the team would not change the current JSX syntax and upgrading to the new JSX transform is not required. So users who are currently using the older transform do not have to upgrade if they choose not to as the old JSX transform will keep working as usual.

What’s Different in the New Transform?

Normally when we us JSX, the compiler transforms it into React function calls that the browser can understand. This means that The older JSX transform would turn JSX into

React.createElement()
Enter fullscreen mode Exit fullscreen mode

For example, lets say we have a simple function component that says Hello World

import React from 'react';

function App() {
  return <h1>Hello World</h1>;
}
Enter fullscreen mode Exit fullscreen mode

Under the hood, the old JSX transform would turn the JSX into regular JavaScript:

import React from 'react';

function App() {
  return React.createElement('h1', null, 'Hello world');
}
Enter fullscreen mode Exit fullscreen mode

However, this is not perfect:

  • Because JSX was compiled into React.createElement, React needed to be in scope if you used JSX. Hence, the reason react is being imported everywhere you use JSX

  • Also, there are some performance improvements and simplifications that that are not allowed by React.createElement()

Hence when react 17 was released to make react upgrade easier and backward compatible, it also introduced two new entry points to the react package that are intended to only be used by compilers like Babel and typescript. So instead of transforming Jsx to React.createElement(), the new JSX transform automatically imports special functions from those new entry points in the React package and calls them.

So for our hello World functional component

import React from 'react';

function App() {
  return <h1>Hello World</h1>;
}
Enter fullscreen mode Exit fullscreen mode

The new Jsx transform would compile it to:

// The import would be Inserted by the compiler (don't import it yourself)
import {jsx as _jsx} from 'react/jsx-runtime';

function App() {
  return _jsx('h1', { children: 'Hello world' });
}
Enter fullscreen mode Exit fullscreen mode

Now we can see that with the new JSX transform, we didn’t have to import react. This optimizes our code and gives us access to those performance improvement that JSX React.createElement() doesn’t allow.

Though this is true with JSX, we would still need to import React to use hooks or other exports that React provides

Want to Upgrade to the New JSX Transform?

If you wish to upgrade the new Jsx transform you would need these:

  1. A version of React that supports the new transform. For example React 17 RC and higher supports it. But the facebook team has also released React 16.14.0, React 15.7.0 and React 0.14.10 for people who are still on the older major versions

  2. A compatible compiler such as:

    • Create React App v4.0.0+
    • Next.js v9.5.3+
    • Gatsby v2.24.5+

some times with gatsby, one gets a gatsby error such as:

Alt Text

This can be fixed by running

npm update

New JSX Transform Supported Compilers Versions and Configurations

  • Babel v7.9.0 First, you’ll need to update to the latest Babel and plugin transform. If you are using @babel/plugin-transform-react-jsx:

For npm run:

npm update @babel/core @babel/plugin-transform-react-jsx
Enter fullscreen mode Exit fullscreen mode

For yarn run:

yarn update @babel/core @babel/plugin-transform-react-jsx
Enter fullscreen mode Exit fullscreen mode

If you are using @babel/preset-react:

npm update @babel/core @babel/preset-react
Enter fullscreen mode Exit fullscreen mode

Currently, the old transform {"runtime": "classic"} is the default option. To enable the new transform, you can pass {"runtime": "automatic"} as an option to @babel/plugin-transform-react-jsx or @babel/preset-react:

// If you are using @babel/preset-react
{
  "presets": [
    ["@babel/preset-react", {
      "runtime": "automatic"
    }]
  ]
}

// If you're using @babel/plugin-transform-react-jsx
{
  "plugins": [
    ["@babel/plugin-transform-react-jsx", {
      "runtime": "automatic"
    }]
  ]
}

Enter fullscreen mode Exit fullscreen mode

It is proposed that by Babel 8, "automatic" will be the default runtime for both plugins.

  • ESLint: If you are using eslint-plugin-react, the react/jsx-uses-react and react/react-in-jsx-scope rules are no longer necessary and can be turned off or removed.
{
  // ...
  "rules": {
    // ...
    "react/jsx-uses-react": "off",
    "react/react-in-jsx-scope": "off"
  }
}
Enter fullscreen mode Exit fullscreen mode
  • Typesript:
    Typesript supports the Jsx transform from version v4.1.

  • Flow:
    Flow supports the Jsx transform from version v0.126.0

Top comments (0)