Web Development

A Quick Introduction Into ES6 Modules

July 20th, 2017 | By Niels Klom | 4 min read

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.

The support is still 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's most anticipated features.

Setting Up

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 module system and not the standard ES6 version.

When support is eventually widespread enough we will hopefully see a lot of 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 will need to spin up a web server 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 requires syntax that 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.

Backward Compatibility

A nice feature of the module's 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 the 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.

Jscrambler

The leader in client-side Web security. With Jscrambler, JavaScript applications become self-defensive and capable of detecting and blocking client-side attacks like Magecart.

View All Articles

Must read next

Web Development

8 Awesome ES6 Features

In this post we will go over eight useful and interesting ECMAScript 6 (ES2015) features.

April 20, 2016 | By Caio Ribeiro Pereira | 5 min read

Javascript

Creating Modules in JavaScript with ES7 and Babel

Last year, a new version of JavaScript was released with a lot of new goodies. Check them out!

April 13, 2016 | By Peter van der Zee | 6 min read

Section Divider

Subscribe to Our Newsletter