Building the Modern Web Stack: Babel

What is Babel?

Babel is a tool that lets you write your Javascript code using all the latest syntax and features, and still run it in older browsers. Babel is a transpiler that will translate your modern JS code into an older version of Javs…


This content originally appeared on DEV Community and was authored by Alex

What is Babel?

Babel is a tool that lets you write your Javascript code using all the latest syntax and features, and still run it in older browsers. Babel is a transpiler that will translate your modern JS code into an older version of Javscript that more browsers are able to understand.

Babel is often built into the tools that we use every day to built modern web applications (like create-react-app for example) so many developers don't have a full understanding of what the tool actually does. This tutorial is designed to set up a Babel configuration piece by piece and is part of a larger tutorial series in setting up your own custom development environment.

Prerequisites

You will need to have Node.js installed on your machine and available from your terminal. Installing Node will automatically install npm as well, which is what you will use to install Babel.

If you see version numbers when running the two commands below (your numbers will likely be different than this example) then you are ready to go:

node --version
> v15.5.0

npm --version
> 7.16.0

Initializing the Project

Let's start by initializing a new npm project. Run the following command to generate one:

npm init -y

The -y flag will automatically select default values for everything, which is appropriate in our example.

Next let's create a very basic Javascript file using some modern syntax. Create a file called script.js with the following code:

script.js

const x = 5;
let y;

const sampleFunction = () => "this is a return value";

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

const hasThree = [1, 2, 3].includes(3);
console.log(hasThree);

y ||= "a new value";
console.log(y);

In the above example const, let, the arrow function, includes array method and class are all features of ES6 that won't run properly in older browsers such as Internet Explorer 11 (which unfortunately some organizations still use extensively even in 2021).

You may also catch the brand new (as of 2021) logical OR assignment. This will not run in versions of Firefox before 79 and versions of Chrome before 85, and it won't run in IE11 at all.

So what can we do to run this code on older browsers without having to rewrite it ourselves?

Installing Babel

There are three basic packages we need to accomplish our goal, all of them are part of the Babel ecosystem, but each has a different function. Start by running the following command:

npm install @babel/core @babel/cli @babel/preset-env --save-dev

Let's take a look at what each one is doing:

  • @babel/core - This is the main engine that knows how to transform code based on a set of instructions it is given
  • @babel/cli - This is the actual program we are going to run to trigger the core engine and output a transformed Javascript file
  • @babel/preset-env - This is a preset that tells the core engine what kind of transformations to make. It looks at your environment (in our case it will be our package.json file) to determine what kind of changes need to be made depending on the browsers you wish to support.

We need to add a couple values to our package.json file:

  • browserslist - This tells Babel which browsers we are aiming to target. The older / less supported they are, the more work and more transformations Babel will have to make in order for your application to work in these browsers. The syntax is a simple array of strings. You can learn about here.
  • babel - This is where we defined all the presets that we will use, as well as any configuration options related to those presets. We will start with the simplest one, @babel/preset-env

So our package.json file should look like this:

package.json

{
  "devDependencies": {
    "@babel/cli": "^7.15.7",
    "@babel/core": "^7.15.5",
    "@babel/preset-env": "^7.15.6"
  },
  "browserslist": ["last 2 Chrome versions"],
  "babel": {
    "presets": [["@babel/preset-env"]]
  }
}

The devDependencies should already be there from your npm install. The other two properties described above you will need to add yourself.

Transforming Your Code

At its most basic configuration babel will transform your modern syntax into the much wider supported ES5.

Let's begin with a simple example. Run the following command in your project root directory containing your package.json file and your script.js file:

npx babel script.js --out-file script-transformed.js

Presuming you have followed all the instructions so far you should see a new file created called script-transformed.js that looks like this:

script-transformed.js

"use strict";

const x = 5;
let y;

const sampleFunction = () => "this is a return value";

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

const hasThree = [1, 2, 3].includes(3);
console.log(hasThree);
y ||= "a new value";
console.log(y);

Not much different right? Aside from adding strict mode nothing has actually changed.

The reason for this is because of how we have configured our environment in package.json, which is where @babel/plugin-env looks in order to decide what it should do.

package.json

...
"browserslist": [
  "last 2 Chrome versions"
],
...

Since we are only targeting the most recent 2 versions of Chrome, Babel knows that we have no problem including all the modern JS syntax that we want, it will work fine in those modern browsers.

But let's say that we are required to support Internet Explorer 11. We don't want to have to change the way we write our code just to accommodate that browser, but fortunately that's where Babel saves the day. Update your package.json to add IE11 to your browserslist array:

...
"browserslist": [
  "last 2 Chrome versions",
  "IE 11"
],
...

Now run this command again:

npx babel script.js --out-file script-transformed.js

Take a look at the output this time:

script-transformed.js

"use strict";

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

var x = 5;
var y;

var sampleFunction = function sampleFunction() {
  return "this is a return value";
};

var Person = function Person(name, age) {
  _classCallCheck(this, Person);

  this.name = name;
  this.age = age;
};

var hasThree = [1, 2, 3].includes(3);
console.log(hasThree);
y || (y = "a new value");
console.log(y);

This looks a lot different from our original file! Notice that almost all the ES6 terms we discussed above are gone, const is replaced with var, our arrow function is replaced with function syntax, and our class has been transformed into a basic Javascript object. We can now take this script-transformed.js file, serve it up to Internet Explorer 11 and it would run just fine... almost!

We still have one small problem: The includes method was not transformed. Why is that? To understand the reason, we first need to understand polyfills.

Polyfills

To understand why we need polyfills we have to understand the difference between what is new syntax and what is new functionality. The includes method is new functionality. It has its own logic behind it, and simply changing the syntax of how the code is written won't explain to older browsers how the logic of the includes method is supposed to function.

For new features that introduce new functionality we need something called a polyfill. Polyfills are simply just the source code for a method like includes that you bundle along with your application to essentially teach older browsers how it works.

You do not need to write polyfills yourself, polyfills for just about every feature of JS already exist and are easy to include. In future tutorials we will get into bundling and only including the specific ones that we need, but until then we can simply include a library called core-js and instantly give our app access to all modern JS features even on older browsers.

To test it out let's load the entirety of the core-js library into our app. Since we are still not yet using a bundler, we will simply load the already bundled and minified version from the web into our app. If you don't already have an index.html template, create this file in your project root directory:

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <script src="script-transformed.js"></script>
  </head>
  <body></body>
</html>

We'll begin by trying to load the file in IE11. If your machine doesn't have Internet Explorer 11, you can simply follow with the example here. This example is running on Windows 11 which has removed IE11 entirely. Fortunately Microsoft Edge comes with an IE 11 Mode for testing applications that require backward compatibility.

When we run Babel and try to load our script-transformed.js file in IE11 we get the following error on the console:

Array Includes Error

Now let's add the core-js library to a <script> tag inside the <head> in our index.html. You can find the most updated minified bundle URL here.

index.html

...
<head>
  <meta charset="UTF-8" />
  <script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/3.18.1/minified.js"></script>
  <script src="script-transformed.js" defer></script>
</head>
...

When we reload the page in IE11 we get:

Array Includes Works

It works! We're writing modern Javascript and running it in an old dinosaur browser! That's great!

Wrapping Up

You should now have a fairly solid grasp of the fundamentals of what Babel is, and how it works. Of course there's a lot more to discover. In future tutorials we'll go deeper into two more of the major presets that are supported by Babel for transpiling supersets of Javascript: JSX and Typescript.

Before we do that we'll first go over the fundamentals of each (similar to this introduction) before diving into how to configure them all together into a modern web stack. Stay tuned.


This content originally appeared on DEV Community and was authored by Alex


Print Share Comment Cite Upload Translate Updates
APA

Alex | Sciencx (2021-10-05T15:19:30+00:00) Building the Modern Web Stack: Babel. Retrieved from https://www.scien.cx/2021/10/05/building-the-modern-web-stack-babel/

MLA
" » Building the Modern Web Stack: Babel." Alex | Sciencx - Tuesday October 5, 2021, https://www.scien.cx/2021/10/05/building-the-modern-web-stack-babel/
HARVARD
Alex | Sciencx Tuesday October 5, 2021 » Building the Modern Web Stack: Babel., viewed ,<https://www.scien.cx/2021/10/05/building-the-modern-web-stack-babel/>
VANCOUVER
Alex | Sciencx - » Building the Modern Web Stack: Babel. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/10/05/building-the-modern-web-stack-babel/
CHICAGO
" » Building the Modern Web Stack: Babel." Alex | Sciencx - Accessed . https://www.scien.cx/2021/10/05/building-the-modern-web-stack-babel/
IEEE
" » Building the Modern Web Stack: Babel." Alex | Sciencx [Online]. Available: https://www.scien.cx/2021/10/05/building-the-modern-web-stack-babel/. [Accessed: ]
rf:citation
» Building the Modern Web Stack: Babel | Alex | Sciencx | https://www.scien.cx/2021/10/05/building-the-modern-web-stack-babel/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.