Anjolaoluwa Adebayo-Oyetoro Maker. Writes sometimes. Playful most times. Loves beautiful UIs.

What’s coming in Babel 8

4 min read 1239

TC39 (Technical Committee 39 — the institution which standardizes the JavaScript language under the “ECMAScript” specification) published ES2015 version of JavaScript popularly known as ES6. The adoption of ES6 grew among developers but browsers did not support every feature of ES2015, then came the need for tools that allowed for the usage of the newest features of the JavaScript programming language.

Babel, originally named 6to5, did exactly that — it made it possible to turn ES6 code into a backwards-compatible version of JavaScript that can be run by older JavaScript engines. The process of compiling code written in one language to another form of the same language is known as Transpiling(transforming + compiling), in this case, taking JavaScript code written in ES6+ and converting it to ES5.

What is Babel?

According to the platforms official documentation:

Babel is a toolchain that is mainly used to convert ECMAScript 2015+ code into a backwards compatible version of JavaScript in current and older browsers or environments

Babel is a JavaScript transpiler, it provides access to the new features made available in the JavaScript language in older environments. it makes available presets and plugins to make code transformations, syntax conversion, and polyfilling features that are missing in your target environment possible.

In this article, we will be taking a look at some of the features and improvements on the previous versions, coming to version 8 of the Babel tool.

New JSX transform

The React team in this RFC has made available new ways to create JSX elements and simplifies how React.createElement() works.

Babel 8 would include a new JSX transform, which will make the creation and instantiation of JSX elements improve considerably in React and React-like libraries.

This new transform would support React.jsx instead of React.createElement. It also automatically imports "react" when needed, so you don’t have to manually import "react".

This transform also takes on the following behaviors:

  • Passing children as props rather than as an explicit argument
  • Passing key as an explicit argument separately rather than through props
  • In development mode
    • Pass a flag determining if it was static or not
    • Pass __source and __self separately from other props
React.createElement(type, props, children)

becomes

React.jsx(type, props, key)

As an example, this input:

function Foo() {
  return <div />;
}

would be transpiled into:

import { jsx as _jsx } from "react/jsx-runtime";
function Foo() {
  return _jsx("div", ...);
}

You can enable this new transform by passing { "runtime": "automatic" } (as opposed to "classic") to @babel/preset-react (or @babel/plugin-transform-react-jsx):

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

Starting from Babel 8, "automatic" will be the default runtime.

You can also try out the new functions available in React for instantiating JSX elements by installing the experimental release as it’s not been made available for stable releases yet:

npm install [email protected] [email protected]

Full support for TypeScript 3.8

This release would also include full support for TypeScript 3.8, which introduced explicit type-only imports and exports (i.e. export type { foo }), in version 8 of Babel you will be able to explicitly mark imports and exports as type-only:

import type { SomeThing } from "./some-module.js";

export type { SomeThing };

This would allow Babel to safely decide which imports or exports are used for types and which are for values.

Maintain class fields when using Flow/TypeScript

This feature would make Babel ignore uninitialized class fields which happens if the flow plugin runs before the class properties plugin or when the class properties plugin isn’t used.

Babel currently transforms code declared like this:

class Foo { x: string }

to become:

class Foo {}

this feature would see that same code become this in version 8:

class Foo { x }

Users who wish to maintain the old behavior can either use flow comments (as officially recommended):

class Bar extends Foo {
  x: ?number;
  /*:: y: number; */
}

or use the ignoreUninitialized option added to the class properties plugin (#9141).

Drop support for core-js 2

Babel will be dropping support for the version 2 of core-js a polyfill of the JavaScript standard library, which supports the latest ECMAScript standard and library proposals.

Babel would be dropping support for it as it introduces de-optimizations on the V8 browser engine(the most popular JavaScript engine and the engine that powers Chrome) this issue affects regexes, iterators, some array methods, typed arrays, promises, and it sometimes causes ~100x performance degradation.

Babel 8 will use core-js version 3.

Transform JSX spread properties using useSpread

This feature changes the current behavior for the transform-react-jsx plugin, where it handles props spread {...Props} by either using Babel’s extend helper or calls to Object.assign. With this feature, you can now convert such instances to an inline object with a spread operator.

According to the documentation, You can enable it using the useSpread option with either @babel/preset-react or @babel/plugin-transform-react-jsx:

{
 presets: [
  ["@babel/react", { useSpread: true }]
  ]
}

If your code needs to run in an environment which doesn’t support object spread, you can either use @babel/preset-env (recommended) or @babel/plugin-proposal-object-rest-spread.

If you want to transpile Object.assign down to Babel’s _extends helper (which is the current default behavior) you also need to enable @babel/plugin-transform-object-assign.



Disabled submodule exports

Babel 8 will disallow importing internal files of different packages, it will be adding exports: false to every package stating explicitly that every package does not offer submodule exports.

Trying something like import "@babel/core/src/config" will fail because this file belongs to internal implementation details.

Declare fields in Flow

The Flow team added support for the declare modifier for class fields because the class fields proposal specifies uninitialized class fields are initialized to undefined. Which is quite different from what Babel does with Flow, it simply ignores them.

Babel 8 includes support for the declare keyword in class fields:

class Foo {
  x: ?string; // A "real" field
  declare y: number; // A type-only field
}

Getting started

Let’s take a look at how we can get started with using Babel in our project.

This tutorial assumes the reader has the following:

Install the Babel CLI tool, this tool allows us to compile our JavaScript files from the command line.

We can install Babel CLI locally by running:

#Using NPM
npm install --save-dev @babel/core @babel/cli

#Using Yarn
yarn add -D @babel/core @babel/cli

after running this command, you should see the packages added as devDependencies in your package.json file.

To compile a file, run the command

npx babel filename.js

Alternatively, you can also run these commands if you would like to output the compiled code to a file:

npx babel filename.js -o compiled-filename.js

You can also use the online repl to compile your code.

Conclusion

In a bid to ease the migration pain for developers which there was while migrating from Babel 5 to Babel 6 and then from Babel 6 to Babel 7. Babel 8 will only contain a few breaking changes and provide an easy migration strategy for each of them.

Babel 8, which is currently less than 50% done and without a set due date is expected to debut with breaking changes in 8.0.0, then a minor version will be released the same day which will contain all the bug fixes and new features that would otherwise be released in 8.0.0.


More great articles from LogRocket:


Babel is an important tool and almost every JavaScript tool depends on it, you can read the release plan and check out other features expected to be released.

What do you think? Which new features stand out to you? Let me know in the comments section.

Get set up with LogRocket's modern error tracking in minutes:

  1. Visit https://logrocket.com/signup/ to get an app ID
  2. Install LogRocket via npm or script tag. LogRocket.init() must be called client-side, not server-side
  3. $ npm i --save logrocket 

    // Code:

    import LogRocket from 'logrocket';
    LogRocket.init('app/id');
    Add to your HTML:

    <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script>
    <script>window.LogRocket && window.LogRocket.init('app/id');</script>
  4. (Optional) Install plugins for deeper integrations with your stack:
    • Redux middleware
    • NgRx middleware
    • Vuex plugin
Get started now
Anjolaoluwa Adebayo-Oyetoro Maker. Writes sometimes. Playful most times. Loves beautiful UIs.

Leave a Reply