July 20, 2017

A Quick Introduction Into ES6 Modules

By Niels Klom | 4 min read

quick-introduction-to-es6-modules-1
ES6 Modules have theoretically been around for a while, but the world's most used browser, Chrome, has only recently added support for ES6 Modules. Even now the support is still very small, as it is only supported in the Canary build of the browser behind a flag. Even so going through the effort of setting all this up is worth it to use one of ES6 most anticipated feature.

Setting Up

First of all, you need to download Chrome Canary and then enable the experimental web platform features flag.
As of writing Canary is not available on Linux so you'll need to wait or get access to a Windows or Mac machine.
If you’re reading this sometime after publishing a more recent version of Chrome with default support may have already been released. Support without a flag is included as of Chrome 61. I've also made a quick example for us to use and placed it on Github. I wanted to do something else than the ever prevailing to-do list so I decided to code together a quick calorie counter.

The Benefits Of Using Modules

The primary reason to use modules is to organize your code. Most people already use modules of some sort in JavaScript. If you've used a module library then you know how using modules can help you write better structured and cleaner code. ES6 Modules are supported natively and they support asynchronous loading. The latter made it hard for the Node.js team to implement it as a replacement to CommonJS modules since this would break a lot of existing code, so, for now, Node.js is still using its own module system and not the standard ES6 version.

When support is eventually widespread enough we will hopefully see a lot people writing better code. More than anything at this point in the evolution of native modules remove the learning gap that came with modularized code in the past.

Getting Started

After you've cloned the code from Github you'll need to spin up a basic web server of some sort to run the code as modules aren't supported by the file protocol.

Quirks

As of writing 'bare' module specifiers aren't supported at all. A bare specifier is one that is just a filename without any slashes or dots in front or after it. See an example below:

How it should work:

import { counter } from 'counter.js';// even without the .js extension

Workaround:

import { counter } from './counter.js';

This is a minor issue but if you're getting errors this is one to check for. It is important to understand that only the top level module needs to be added to the HTML document, the rest is done using JavaScript.

                     < module 1 
                     /
index.html <- main.js 
                     \
                      < module 2

There isn't necessarily a hierarchy to using modules, however, it is a good practice to create one anyway. It is very possible to create spaghetti code with modules as well. Creating sub folders for every level of modules is a good method to prevent this from happening.

Require vs Import

The Node.js style require syntax is different from the actual ES6 syntax. Node.js borrowed its syntax from the Common.js syntax, and has since stayed with it. Common.js style modules were designed for synchronous loading, which goes against the current trend in JavaScript for asynchronous loading. If you are using the Require syntax right now using ES6 modules will feel a little unfamiliar, going from sync to async, but over time you will find that the difference isn’t incompatible.

The Script Tag

Adding a module to a page requires a slightly different tag than usual. See below:

<script type="module" src="main.js"></script>

You need to add the module type to your script tag to let the browser know you're adding code that uses modules and not just any old JavaScript file.

Backwards Compatibility

A nice feature of the modules spec is that they've also thought about what the browser should do when it doesn't support modules. For that, they have created the nomodule attribute for the script tag. See below:

<script nomodule src="main.precompiled.js"></script>

If the browser doesn't support modules it will automatically fallback to this script. However, if it does support modules it will ignore this tag.

Making A Module

In the counter.js file you will find a module. This is an ES5 constructor that has a method we use to update the total count.

export function counter (element , cals) {
    this.el = document.querySelectorAll(element)[0]; 
    console.log(this.el);
    this.amount = cals; 
    this.attr = this.el.getAttribute('data-total');
}; 

counter.prototype.update= function () {
    const newTotal = Number(this.amount) + Number(this.attr); 
    console.log(this.el);
    this.el.children[0].textContent = newTotal + ' Calories';  
    this.el.setAttribute('data-total', newTotal);
};

By adding the export statement before the constructor declaration we are exposing it as the primary 'export' for this module. In our main.js file we then import the counter from the counter.js file.

import { counter } from './counter.js'; 
const form = document.getElementById('add'); 
const cals = document.getElementById('cals'); 
const type = document.getElementById('type'); 
const table = document.getElementById('items'); 
form.onsubmit = function (event) {
    event.preventDefault();    
    let row = document.createElement('tr'); 
    let cellType = document.createElement('td'); 
    let cellCals = document.createElement('td');
    cellType.textContent = type.value; 
    cellCals.textContent = cals.value; 
    row.appendChild(cellType);
    row.appendChild(cellCals); 
    table.appendChild(row); 
    let counterObject = new counter('#counter', cals.value); 
        counterObject.update();
}

That's it. It's a lot like we added the code for counter in another script tag before we added this code, except we're calling it at the top of this document instead of piling up the script tags in our HTML file. Want to know more about modules? Check out this post by the Chrome Dev Team.

Tags: ES6
Niels Klom404 bio not found
View All Posts

Subscribe to our weekly newsletter

Learn more about new security threats and technologies.

I agree to receive these emails and accept the Privacy Policy.