ES6 Toolings

This is a brief introduction to Babel and Webpack, but before we talk about them, let’s look at the concept of module in JavaScript.

Module

Instead of writing all your codes inside of one file, we can split them into multiple modules. A example is when you are using WeakMap to make private members, you can put the class defination and the private members defination in a module and only export the class as an public interface.

There’re no modules before ES6, but Node.js has its own module format called CommonJS, after ES6, JavaScript natively supports module format which can be used in browsers.

Let’s take a look at them:

CommonJS Module

Used in Node.js.

module refers to the current module.

To export multiple object:

1
2
module.exports.Circle = Circle;
module.exports.Square = Square;

When only exporting a single object, a better approach is rewriting module.exports:

1
module.exports = Circle;

Reset exports to Circle, so when we import the module, we will get the Circle class directly.

To import from another module:

1
const Cirlce = require("./circle"); // the module's position, return module.exports

ES6 Module

Used in browser.

put export before a declaration to export:

1
export const name = "sichen";

To import:

1
import { name } from "./other";

However, after doing that, you will get a SyntaxError: Unexpected token {, there’s a proper way to fix this issue using webpack, which we will talk below.

But if not in production, we can set the script tag in your HTML file to:

1
<script type="module" src="index.js"></script>

Then the browser will treats index.js as a module, so it will understand the {.

However, that’s still not enough, because you will get a different error saying GET hostname/other net::ERR_ABORTED, because we load the module using "./other", so browser will send an HTTP GET request to the /other endpoint.

If not in production, a simple work around is to append .js when import, so it will send an HTTP request to ./circle.js which will work for temporarily:

1
import { Circle } from "./circle.js";

Babel

Babel is a transpiler (translator + compiler).

To install Babel in your project , run npm i babel-cli babel-core babel-preset-env --save-dev. --save-dev means we will install these dependencies as development dependecies, so they are not going to be deployed to the production environment.

Let’s explore these 3 node packages:

  • babel-cli is Babel’s command line interface, a tool we run from the command line like npm, you can run it using babel.
  • babel-core contains all the logics for transpling code.
  • babel-preset-env is a combination of all new features from ES6’s plugins, it understands all the new features starting from ES6.

Open package.json and add a new srcipt under scripts section.

1
2
3
{
"babel": "babel --preset env index.js -o build/index.js"
}

For all of the scripts defined under the scripts section, we can run them using npm run <name>, such as npm run babel which runs babel --preset env index.js -o build/index.js

Webpack

The real workflow when building an application doesn’t include working with Babel by ourselves. The real workflow is:

  1. Run npm i -g webpack-cli in the project folder where -g indicates to install webpack-cli globally in the computer.
  2. Run webpack-cli init.
  3. It will ask you a lot of questions, based on them it will create a webpack configuration file. One of these questions is “Will you be using ES2015? (Y/n)”, if you answer yes, webpack will install Babel for us automatically.
  4. Run npm init --yes to initial a node project.
  5. Add a new command under the scripts section

    1
    2
    3
    {
    "build": "webpack"
    }
  6. Now, every thing is ready, let’s bundle our application, run npm run build, after that you can see a JavaScript file under dist folder with ugly code.

  7. Now we have only a single JavaScript file to serve for the clients, change the script tag in your HTML file:

    1
    <script src="dist/main.bundle.js"></script>
  8. One last step, with the current setup, everytime we make a change to our source files, we have to run npm run build again, that’s time consuming, we can make webpack to generate the bundle file automatically when we change our codes:

    1
    2
    3
    {
    "build": "webpack -w"
    }

    -w is short for --watch, so now webpack will watch our files and every time we make changes, it will generate a bundle automatically.