Module Pattern in JavaScript (Part 2)

Modules in ES6

In my last post, I covered the Module Pattern in JavaScript pre ES6 specifications. There is a lot to learn and I recommend you read up on that first before jumping into the ES6 module. You can read the post here. I’ll recap below the main reasons why you should implement using modules in your code.

Maintainability

Writing your code into modules means that it should have fewer dependencies and writing an update to a module is only going to affect that module.

Namespace

Read the previous post about namespaces and closure, but in a short way, you can introduce global variables and unknowingly alter variable state and values if you happen to use the same name elsewhere. Use of modules can prevent this.

Reusability

Keeping your code dry (don’t repeat yourself) is not always easy. We’ve all done it. Copy-pasta code can be troublesome, for the reason that you will at some point need to update something and then need to find every place you copied out a snippet of code. Trust me, you’re going to miss something and introduce a bug.

Vanilla Modules in ES6

Starting with the ES6 specifications we are able to write our modules in a way that is easier in my opinion for a variety of ways. If you come from an object-oriented background in programming they make much more sense and feel a bit cleaner in its usage than for example the anonymous function pattern, for execution of a function without polluting the global namespace. Modules in ES6 are essentially all of the good that comes from previous implementations of module patterns and cleans up the syntax with some o’sweet syntactic sugar. Note too that this is not available functionality in all browsers, for example, IE11, and if you are still using IE 11 I am sorry.

So now you’re probably asking how do we do this using ES6? Let me demonstrate and then explain. Let’s start with how we load a module in HTML, as this is slightly different than how we load javascript script elements that are not modules.

<script src="scripts/app.js" type="module"></script>

Notice that we are loading our javascript like so <script src="scripts/app.js" type="module"></script>. We need to clarify that the script we are loading is of a type module. If not using the type property on our script tag there will be errors loading your JavaScript.

Now that we know how to load a module, let’s take a look at the actual module code itself. This is where things get interesting and makes me happy to be able to write code this way. app.js is actually our entrance into our JavaScript files. The first thing you should notice is the import statement.

import { sum, MessageClass } from './module.js';
let arr = [1,2,3,4];
console.log( sum(...arr) ); // 10
 
let messenger = new MessageClass('this is your message');
 
console.log(messenger.getMessage());

We can see that we are using an import statement, and if you have used CommonJs/requireJs or AMD this might begin to feel familiar. In essence, we are importing sum and MessageClass from our module.js file. So let’s take a look at the module.js file to see how this is done using the export keyword.

export const PI = 3.1415926;
 
export function sum(...args) {
  log('sum', args);
  return args.reduce((num, tot) => tot + num);
}
 
// private function
function log(...msg) {
  console.log( ...msg);
}
 
export class MessageClass{
    constructor(message){
        this.message = message;
    }
 
    getMessage(){
        return this.message;
    }
 
    setMessage(newMessage){
        this.message = newMessage;
    }
}

Notice that the export keyword is being used in the sum function and PI const variable. This is great if you have a few variables that you wish to use, and also can be used in a sense for encapsulation in the example of the log function, but I also really enjoy the ability to create a class as in the MessageClass and use that. Coming from a .NET background is a bit more comfortable for me.

I hope that you have found this helpful and understand ES6 is just sugar on the pre ES6 implementations of JavaScript, that you can read about in my previous post on the module pattern here