By Ran Bar-Zik | 2/20/2018 | General |Beginners

Modules in ECMAScript 6

Modules in ECMAScript 6

As the amount of JavaScript frameworks rises, so too does the need for modules—independent units of code that we can import into our own code. There are tons of uses for them in JavaScript and you’re probably familiar with things like MooTools, jQuery, and even common.js and require.js.

 

Until recently, the easiest way to execute modules was by way of an anonymous function that ran itself, also know in fancier terms as an Immediately-Invoked Function Expression or IIFE for short. Because JavaScript could also use some unnecessary acronyms.

 

But I digress. So what’s this whole anonymous function that runs itself thing anyway? Well, it goes something like this:

//Module Starts

(function(window){

   var sum = function(x, y){
       return x + y;
   }

   var sub = function(x, y){
       return x - y;
   }

   var math = {
       findSum: function(a, b){
           return sum(a,b);
       },

       findSub: function(a, b){
           return sub(a, b);
       }
   }

   window.math = math;

})(window);

//Module Ends

console.log(math.findSum(1, 2)); //3
console.log(math.findSub(1, 2)); //-1

If this looks familiar then you won’t be surprised to learn that jQuery also uses this type of module. If it doesn’t look familiar, have another look at the code. What might look strange to you here is this:

(function(window){

})(window);

So what do we need this for anyway? It’s designed to isolate the module from the general scope and prevent its functions and variables from mixing with the rest of the code.

 

There are JavaScript libraries and environments that have taken this farther and allow you to put modules in a separate file where the call to the module is made from JavaScript itself. For example, something like this:

//math.js fille


var sum = function(x, y){
   return x + y;
}

var sub = function(x, y){
   return x - y;
}

var math = {
   findSum: function(a, b){
       return sum(a,b);
   },

   findSub: function(a, b){
       return sub(a, b);
   }
}

//All the variable we want to expose outside needs to be property of "exports" object.
exports.math = math;

//some other js file
//no file extension required
var math = require("./math").math;
console.log(math.findSum(1, 2)); //3
console.log(math.findSub(1, 2)); //-1

The code above describes two files. The first section is a file named math.js, and the second is just another file that calls to the math.js file via the require function and runs it. If you know a little Node.js, then this syntax should be familiar to you. This design is called Asynchronous Module Definition (ADM) the the library that allows us to use it is called commonJS, and is available mainly in Node applications. It’s a lot easier and more intuitive than IIFE, but for the most part, unfortunately it’s only possible to implement it in a server environment.

 

Sure, there are all kinds of solutions that allow us to use AMD in the browser, but they’re not really good enough. Thankfully ECMAScript 6 has come along, allowing us to use modules inherently and simply, just like in AMD.

 

Defining the Module

 The example we have is quite simple—we have a module called math and an attribute called pi, and a method called sum. So how do we create the module? Let start by making a folder called lib and a file called math. This is how the file will look:

export class Math {

   constructor() {
       this.sum = function(x, y){
           return x + y;
       }
       this.pi = = 3.141593;
   }

   findSum(a, b) {
       return this.sum(a, b);
   }

   getPi() {
       return this.sub(a, b);
   }
}

If you’re following close, the syntax of class will look very natural. If however you’re wondering what exactly I’m getting at here, then now is the time to have a look at class. We can see that the class exposes two lovely little methods. Another critical component is export. The export is, well, what we export. So what about implementation? For each file in the project, we only need to execute import for that file. Remember, we saved it in lib/math.js. After the import, we’ll do an instance to class inside a variable and that’s it!

import {Math} from 'lib/math';
var math = new Math();

console.log(math.findSum(1, 2)); //3
console.log(math.getPi()); //3.141593

So what’s going on here? Don’t be alarmed. The most important part is the import in which we must put two things: the name of the class the we ran import on (in this case Math) and the name of the local file. After we’ve done this, the class called Math is available to us and we can make an instance of it (in other words call it) and use its methods with no problems.

 

Want another example? Why not? When don’t even need to use class. Just keep your eyes on the file called name that I made:

//File: directory/name.js
export var environment = 'develop';
export var userName = 'Moshe';
export function sum(x,y) { return x + y;};

//Other file
import * as names from "directory/names";
console.log(names.environment); //develop
console.log(names.userName); //Moshe
console.log(names.sum(2,3)); //5

Awesome! Everything that we do export to, we can import it. Note that we can use this

import {environment, userName, sum} as names from "directory/names";

or use an asterisk in order to get everything. The import we do inside of a variable, and now everything that we ran export on is available without issue and without fear of scope problems. Now, go on and try to say that this isn’t nice and simple.

 

Previous article: ECMAScript 6 - Lambda Expressions

Next article: ECMAScript 6 - Breaking Down Arrays

 

About the author: Ran Bar-Zik is an experienced web developer whose personal blog, Internet Israel, features articles and guides on Node.js, MongoDB, Git, SASS, jQuery, HTML 5, MySQL, and more. Translation of the original article by Aaron Raizen.

By Ran Bar-Zik | 2/20/2018 | General

{{CommentsModel.TotalCount}} Comments

Your Comment

{{CommentsModel.Message}}

Recent Stories

Top DiscoverSDK Experts

User photo
3355
Ashton Torrence
Web and Windows developer
GUI | Web and 11 more
View Profile
User photo
3220
Mendy Bennett
Experienced with Ad network & Ad servers.
Mobile | Ad Networks and 1 more
View Profile
User photo
3060
Karen Fitzgerald
7 years in Cross-Platform development.
Mobile | Cross Platform Frameworks
View Profile
Show All
X

Compare Products

Select up to three two products to compare by clicking on the compare icon () of each product.

{{compareToolModel.Error}}

Now comparing:

{{product.ProductName | createSubstring:25}} X
Compare Now