How to write ES6 code that’s safe to run in the browser

Intro

Since being introduced in 2015, browsers have been gradually supporting more and more of the handy features of ES6. This is music to the ears of developers who want a move away from the constraints and quirks of ‘old JavaScript’.

But there are some features (notably module imports/exports) that aren’t quite fully compatible with all browsers and certainly won’t ever be implemented in Microsoft Edge or Internet Explorer.

Also, what if you want to start using new features of the next-generation of the ECMAScript standard ES7/8 and beyond?

I used to be of the opinion that you should write your code in plain old ES5 JavaScript so that you can support the maximum level of users. That is, until I got involved in a new Microsite project at work that was using totally new concepts to me at the time: transpilation and bundling.

What is transpilation and bundling?

So, transpilation is the process of converting code from one language to another. This could be something like converting TypeScript to JavaScript but in our case, it means converting ES6 code to another version, such as ES5.

If transpilation converts our code to another, more compatible, version of JavaScript, where does the bundling term come from?

Well, in order to transpile our code we’re going to need some tool to carry out the process and we might as well merge all our code files together at the same time by ‘bundling’ them together. Hence where the term bundling comes from.

This tutorial will take you through the process of transpiling and bundling your code using Babel (transpiler) and webpack (bundler) so you’ll be able to write your application code with all the features of ES6 and be sure that it’s safe to run in most browsers. It can also be a good project to add to your portfolio if you’re looking for JavaScript project ideas to show off your tooling skills.

For the tutorial, you’ll need to have NodeJS installed and be relatively familiar with running a few commands on the command line (although i’ll take you through each part, step-by-step).

Setting up the project

In order to get going, we’ll set up our project by creating the necessary files, install the project dependencies then add a little bit of boilerplate code.

First off, from the command line, create a new folder to hold your project and navigate to it e.g.

mkdir es6-build
cd es6-build

Next, create an index.html file and a folder called src with a file called index.js inside it. You can use your text editor or run the following commands if you like:

touch index.html
mkdir src
touch src/index.js

Your project structure should then look like this:

├── index.html
└── src
└── index.js

Open your index.html file in your text editor and put in a simple bit of HTML boilerplate, you can copy the below if it helps:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>ES6 JavaScript</title>
  </head>
  <body>
  </body>
</html>

Finally, just so you have a bit of JavaScript code to work with, add the following to your index.js file:

const hello = (msg) => console.log(`Hello ${msg}`);
hello('World');

All this is doing is creating an ES6 arrow function that includes a template literal which basically just prints out ‘Hello World’ to the console when the file is loaded. If the above looks totally unfamiliar to you, take a look at the explanation of ES6 arrow functions and how they differ from the function keyword in JavaScript below:

Installing dependencies

Our simple project will require webpack and Babel to build and transpile our code successfully so we will install these packages as dependencies.

To do this, create a package.json file in your project.

The easiest way to do this is to run npm init in your project directory and accept all of the default options.

Once you have your package.json file setup, you can install webpack and Babel with the following command

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

Let’s just run through quickly what each of these dependencies are:

  • @babel/core – the main Babel library which takes care of the transpilation process
  • @babel/preset-env – a configuration for Babel which makes sure our code will be transpiled to the right version
  • babel-loader – Is actually a kind of plugin for webpack to allow files to be passed to the Babel transpiler
  • webpack – The core webpack bundler code
  • webpack-cli – Allows webpack to run directly on the command line

We’ll now add a build script to your package.json file so we can call webpack from our project.

If you open up your package.json file in your text editor and edit the scripts property to add a new script of “build”: “webpack”. So your scripts section should look like this:

"scripts": {
  "build": "webpack",
  "test": "echo \"Error: no test specified\" && exit 1"
},

Now, from the command line if you type npm run build you’ll see some output from webpack and, once the build has completed, you will see a new folder dist in your project folder. This contains your processed code, ready to be used in your project.

You can now link to that JavaScript code in your HTML file. Open your index.html file and add the following script tag:

...
<head>
  <title>ES6 JavaScript</title>
  <script src="dist/main.js"></script>
</head>
…

If you then open the index.html file in your browser you will see the Hello World message in your console:

At this point we have got webpack running and bundling our code however it isn’t actually transpiling our ES6 code to ES5 yet. You can check this by inspecting the processed code either in your dist folder or inside your browser.

Can you see how the arrow function is still there? If this were running in an older browser, we might encounter an error at this point.

Adding transpilation to the webpack build

So far, what you have isn’t that impressive – webpack is simply taking our input JavaScript file in the src folder and running it through it’s build process and creating an output file in the dist folder.

So we will need to tell webpack to transpile the code by making a configuration file.

By providing webpack with a configuration, you can customise how it works including the version of the JavaScript produced in the output which is exactly what we want to create our browser-safe code.

Start off by creating a file in the root of your project and call it webpack.config.js

Inside it, add this boilerplate code which is the absolute basic configuration for webpack:

const path = require("path");
module.exports = {
  mode: 'development',
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "main.js"
  },
};

This is actually what webpack uses by default so we’re not adding anything new here.

You can see inside this configuration that you can change the default ‘input’ JavaScript file by updating the entry property but you can leave it as /src/index.js for this tutorial Also, you can update the output folder name and the bundled JavaScript filename in the output property if you wish.

In order to tell webpack to use Babel to transpile our code to be ES5 compatible, we need to create a rule. We’ll create one that matches any .js file and loads the file in to Babel for conversion. This is done by the babel-loader package we installed earlier on.

Our completed webpack config will look like this:

const path = require("path");
module.exports = {
  mode: 'development',
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "main.js"
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /(node_modules)/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env"]
          }
        }
      }
    ]
  }
};

You can see we have added a rule to check for any .js file (except those in the node_modules folder) and then load these files into Babel and process them with the @babel/preset-env package which will allow us to use the latest JavaScript without having to worry about compatibility.

Save the above configuration and run npm run build again.

When you inspect the bundled JavaScript file either in the dist folder or inside your browser you will see the ES6 arrow function has been converted to an older-style ES5 function declaration.

Great stuff! Our ES6 code is now being transpiled and bundled by webpack and Babel.

The following two tabs change content below.

jay

Latest posts by jay (see all)

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *