NEW JSX TRANSFORM
Tags: react, javascript, reactnative, 100daysofcode
Published: 2021-01-25 18:27:25

##**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](https://reactjs.org/docs/introducing-jsx.html)

#**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 
```javascript
React.createElement()
```

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

```javascript
import React from 'react';

function App() {
  return <h1>Hello World</h1>;
}
```

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

```javascript
import React from 'react';

function App() {
  return React.createElement('h1', null, 'Hello world');
}
```


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

```javascript 
import React from 'react';

function App() {
  return <h1>Hello World</h1>;
}
```
The new Jsx transform would compile it to:

```javascript 
// 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' });
}
```
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](https://dev-to-uploads.s3.amazonaws.com/i/82ketq8lo4g8m3m8b3lp.png)

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
```
**For yarn run:**
```
yarn update @babel/core @babel/plugin-transform-react-jsx
```

If you are using `@babel/preset-react:`
```
npm update @babel/core @babel/preset-react
```

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:

```javascript
// 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"
    }]
  ]
}

```

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


* ESLint:
If you are using [eslint-plugin-react](https://www.npmjs.com/package/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.

```javascript
{
  // ...
  "rules": {
    // ...
    "react/jsx-uses-react": "off",
    "react/react-in-jsx-scope": "off"
  }
}
```

* Typesript:
Typesript supports the Jsx transform from version `v4.1`.

* Flow:
Flow supports the Jsx transform from version `v0.126.0`