Clarifying Which Babel to Use for Compiling React Today

Babel is a toolchain to transpile new JavaScript syntax (e.g. ES6) down to older versions that is supported by browser or node.js execution environments. The latest major version at the moment is Babel 7. To transpile JavaScript React, we normally use bable.

The problem is that babel is evolving so fast that it can be confusing to know what to use. Especially when you are supporting older React application as well as creating new ones. Is stage-x still a thing? What happens to preset-es2017? Why my babel has @babel prefix? What should I use?

If you are starting a new React project, my recommendation is to use the latest set. I have been guilty of using create react app or get other developers to configure the environment and was pretty confused about it. It took me a while to figure out what had been deprecated and what would be the best to use in my own React project. After burning my fingers a few times, I have a little bit better knowledge about this toolchain.

Before going any further, I have to note that this is for compiling React with the latest webpack 4 and babel 7 to date. In this space, things move very quickly and everything becomes legacy in a few months time.

Now, it’s time to demystify some of the things that confused me as well as give you some tips to use babel.

(1) stage-x and esYear modules are deprecated.

We do not need to use stage-x or esYear modules. They are replaced by @babel/preset-env module.

(2) @babel prefixed modules are the latest ones.

If you are using something like babel-preset-env or babel-preset-stage-2, they are super old and not compatible with webpack 4. You will see them in legacy React apps with older webpack versions where developers are too scared to upgrade. You can spot them when you look at presets in babelrc files. They are short like [“preset-env”, “stage-2”]. The latest ones has prefix as [“@babel/preset-env”].

(3) preset-env rules

Instead of yearly presets like es2017 or stage-x presets, use @babel/preset-env. It includes all the deprecated presets.

(4) Don’t worry about the target for preset-env if you don’t have specific requirements

With preset-env, you can specify the target as in the documentation here. Note that the default is the browserlist. So, if you want to target browsers, you do not need to specify the target.

Basically, this one is the same

"presets": [
  [
    "@babel/preset-env",
    {
      "targets": "> 0.25%, not dead"
    }
]

As this one

"presets": ["@babel/preset-env"]

(5) Update babel often

If you are re-using package.json from a few month ago, it is probably outdated. You can upgrade babel with npx babel-upgrade

(6) @babel/plugin-proposal-class-properties are needed for using arrow function in React class

Using arrow functions in React class is definitely preferable. Lexically scoped class functions are easier to use and make code more concise. Unfortunately, this is not supported out of the box preset-env. You need to install the plugins.

(7) Read the error message

When compilation fails, babel gives you pretty good error message. Before jumping to google, make sure to read them. The answer is right in front of your eye.

(8) Create .babelrc file instead of putting in package.json file

It is recommended by babel. The separation makes it maintainable because package.json file can get pretty big.

Setup Example

Here is the example of babel set up. This is the minimum requirement to write modern React application.

.babelrc

{ 
  "presets": [
    "@babel/preset-react",
    "@babel/preset-env"
  ],
  "plugins": [
    "@babel/plugin-proposal-class-properties"
  ]
}

Versions

"webpack": "^4.19.1",
"@babel/core": "^7.1.0",
"@babel/plugin-proposal-class-properties": "^7.4.4",
"@babel/preset-env": "^7.1.0",
"@babel/preset-react": "^7.0.0",

Now we can finally stop worrying about compiling React and start building cool stuff … until the whole thing becomes obsolete in a few month time… urrg…

Front-End
TypeScript: type aliases to check type equality

This post is to analyse how the type equality check by using type aliases proposed by Matt Pocock in his twitter post. These type aliases allow us to elegantly express type equality checks in unit tests. All we need to do is to pass the output and expected types in …

Front-End
Fixing it.only type error in Jest

If you are getting a type error with it.only in Jest, it could be due to incorrect TypeScript typings or incompatible versions of Jest and TypeScript. To resolve this issue, you can try the following steps: Make sure you have the latest versions of Jest and its TypeScript typings installed …

Front-End
yup conditional validation example

Here’s an example of a Yup validation logic where the first input field is optional but, if filled, it must contain only alphabetic characters, and the second input field is required: import * as Yup from “yup”; const validationSchema = Yup.object().shape({ firstField: Yup.string().matches(/^[A-Za-z]*$/, { message: “First field must contain only …