Babel Polyfills, Transforms & Presets

Published Oct 11, 2017
Babel Polyfills, Transforms & Presets

Babel is really an amazing accomplishment by an open source community and an example of another kind of declarative, plugin-driven piece of software, like Webpack that pushes Javascript forward.

You may start from where we left off or clone the git repo and checkout this branch like so.

git clone git@github.com:lawwantsin/webpack-course.git  
cd webpack-course  
git checkout babel2  

Let’s get a bit more into how Babel works, by adding polyfills to our codebase to extend the browser’s current capabilities and run features that still being debated in the standards committee. Really cool way to evolve a language.

Now let’s add something that’s definitely going to be in the language. In our main.js.

var a = async () => {
  await console.log("Hello from the future!")
}

And in .babelrc we add the plugin.

{
  "plugins": [
    "transform-es2015-arrow-functions",
    "async-to-promises"
  ]
}

This should add code to build a promise in the ES5 syntax. When we run yarn add babel-plugin-async-to-promises in our terminal we see.

Babel Output

And we see, if we run this, the promise code is added and called.

Async/Await functions are working their way into many evergreen browsers, but at this point, it's still a part of the ES2017 spec. Either way, in IE 11, we'll need to include a polyfill to run even the transpiled code.

yarn add babel-polyfill

In webpack.dev.js add babel-polyfill to the front of main.js.

main: ["babel-polyfill", "./src/main.js"]

Run yarn start. You can main-bundle.js is quite a bit bigger now. Adding babel-polyfill to that array tacked the whole module to the front of our main.js code.

To reduce this and any polyfill, it's really best to use the exact fill you'll need. Change the main entry again and rerun the server.

    main: ["core-js/fn/promise", "./src/main.js"]

Polyfill Comparison

The difference is shown in this image. While polyfills will only be used if they're not already implemented natively in the user's browser.

Let's restore main to it's former self.

main: "./src/main.js"

Babel Presets

We can add features one at a time with plugins, or we can use presets to include all the features of a particular year or a particular way of working. There’s a preset for react development which compiles JSX for you. Presets make setup easier. And “env” is the current preset that works best in most situations.

So let’s wrap up our overview of Babel and setup a full ES2017 feature stack, so we can finally start coding our project the modern way. In your terminal.

yarn add babel-preset-env

In .babelrc, just this:

{
  "presets": [
    [
      "env",
      {
        "debug": true
      }
    ]
  ]
}

When we rerun the devServer, we see debugging information

Babel Output

If we change the target, we'll see a different output of polyfills and transforms based on what that browser needs. Babel uses The Compat-table to determine the current state of browser features. So if we add a target to our .babelrc:

{
  "presets": [
    [
      "env",
      {
        "targets": {
          "browsers": ["last 2 versions"]
        },
        "debug": true
      }
    ]
  ],
  "plugins": ["transform-runtime"]
}

Your main.js should look like this:

require("babel-runtime/regenerator")
require("./main.css")
require("./images/link.jpg")
require("./index.html")

var a = async args => {
  const { a, b } = args
  await console.log("Hello from the future!", a, b)
}

a({ a: 1, b: 2 })

Finally add the package and rerun:

yarn add babel-plugin-transform-runtime
yarn start

We see a list of the supported browsers and the plugins needed to target them. No surprise that IE 10 and Android 4.4.3 are causing the extra transforms and the total bundle size has increased. Interestingly, if you change the target to the lastest 1 version, it's IE 11 and Android 56 and the bundle size is the same.

Babel Output

Challenge

Feel free to add a mystery Javascript feature yourself or specific target browser as outlined here and practice looking at the output with yarn babel src/main.js, see if it’s what you’d expect.

In Sum

Transpilers a fascinating part of the javascript evolution and allows for lots of experimentation with the look and feel of a new syntax, before the makers of the engine commit to implementation.

This is the final code:

git checkout babel2-final
Discover and read more posts from Lawrence Whiteside
get started
Enjoy this post?

Leave a like and comment for Lawrence