Minimal Babel Setup

Lay down the bare minimum, yet solid, Babel foundation

Photo by Bart Zimny on Unsplash

Building on top of our last post — Minimal Webpack Setup , we will be introducing Babel to work with Webpack in order to transpile our Javascript codes — that are written in latest Javascript syntax— to codes written in older syntax that are supported by our target browsers.

We will take care of Babel first, and finish it off by intergrating it with Webpack.

F*ck it! Do it!! 🎆

Install some npm packages

npm i -D @babel/core @babel/preset-env babel-loader

(If you are using React, npm i -D @babel/preset-react too.)

And last one:

npm i @babel/polyfill

Note that ‘ @babel/polyfill’ will have installed the core-js(source of our polyfills) and regenerator-runtime packages too. The inclusion of all of that stuff will be handled for you ❤️ by Babel accordingly as we will see how to set that up next.

Create the .babelrc file

Edit (3/6/2019)

The following is the babel loader I’m currently using:

"presets": [
"useBuiltIns": "entry"
"@babel/preset-react" // removes this entry if not using React

As you will see, @babel/preset-env and @babel/polyfill are the two main components that make it really happen!

About @babel/preset-env :

@babel/preset-env is a smart preset that allows you to use the latest JavaScript without needing to micromanage which syntax transforms (and optionally, browser polyfills) are needed by your target environment(s). This both makes your life easier and JavaScript bundles smaller!

Basically, all you need to care about is the list of browsers you are going to support, then the @babel/preset-env will — with the help of the userBuiltIns key —automatically select all the required transform plugins and polyfills so that your final codes will run properly in your target browsers.

Let’s talk a bit about the effects of polyfills on codesize and ways to reining them in, then we will ram through the rest of this article!

Controlling codesize

Babel can bloat your codesize if you are not careful, especially when using @babel/polyfill , in which case, it’s recommended to utilize the useBuiltIns property with the @babel/preset-env as shown above, because that way, Babel will automatically include only those polyfills(including the regenerator-runtime file if necessary) that are really needed by your target browsers.

Here is a good summary of using @babel/preset-env along with different useBuiltIns values:

Unless nothing else ever works of you, avoid the following usage of @babel/polyfill :

  1. Put it in the entry of your webpack config: entry: ['@babel/polyfill', './index.js'] .
  2. Use @babel/runtime along with the @babel/plugin-transform-runtime , unless you are building a library, although they both do more or less than @babel/polyfill and might even solve some of your annoying Babel issues too. Here is a good summary about this.
  3. Most solutions/packages you see posted prior to Babel 7. Always refer to the official doc.

One downside to the useBuiltIns: "entry" setting is that it will add many potentially useless polyfills to satisfy all of your target browser, whether your code need them or not!

A better method would have delivered only the polyfills that are needed by your code and your user’s browser.

To that end, here are 3 methods I know of that we can try:

  1. Use useBuiltIns: "usage" . This is still experimental in Babel, but see the demo here.
  2. Use — “ It’s a service which accepts a request for a set of browser features and returns only the polyfills that are needed by the requesting browser.”
  3. Before mounting your app in client, check your API against window . If it exists, then it’s already a native API. If not, http fetch the corresponding polyfills. Only then mount your app. This method is more hands-on.

Alright, that’s all I have for you about this kinda stuff.

Now let’s finish this!

Next we will specify our target browsers in a file called .browserslistrc as recommended by Babel doc, so that Babel will know which polyfill and syntax to spit out.

Create the .browserslistrc file

We use browserlist to specify our target browsers:

# Browsers that we support>0.2%
not dead
not ie <= 11
not op_mini all

Here you can see all of the browsers you are supporting based on the list above.

Note, careful of using last 2 versions as argued here.

Import @babel/polyfill

Now we will simply do import '@babel/polyfill' at the very top(before everything else) of our entry file which is the index.js:

(Note: Skip this if you do useBuiltIns: "usage" )

// index.jsimport "@babel/polyfill"; import helloWorld from "./helloWorld";...

Integrate with Webpack

This is easy. All you need to do is add this block in the module.rules array in your you will do the same thing with the too.) :

module: {
rules: [
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"

test: /\.css$/,
use: ["style-loader", "css-loader"]

Essentially you are saying:

“Hey webpack compiler, skip the node_modules altogether, then when you come across a path that resolves to a ‘.js’ file inside of a require()/import statement use the babel-loader to transform it before you add it to the bundle.”

OK that’s it! Bye! 🎿

“Untitled” by Kheoh Yee Wei



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store