Creating and Using Modules in JavaScript

Posted on - Last Modified on

On a conceptual level, software development and software engineering feature many similarities to construction engineering. If you think of a normal family house, which has different spaces such as bedrooms, a kitchen, bathrooms, a living room, and a closet, all these places have a very clearly defined purpose and role and everybody knows what these are for. In the same way that a house requires structure, software or a Web page should be structured too. The building blocks of a house are the rooms and spaces it has, and in the case of an application, these building blocks are the modules. As such, each module should have its own clearly defined purpose.

Using modules in software development is a best practice, where each module has a well-defined task and a known set of features. An example of a module could be a logger module or an authentication module. Since modules are (actually should be) separate code files with a well-defined and minimal public interface, these can be changed at any point in time and will give you flexibility in the application architecture.

Another important aspect of modular software development appears during the development phase of the application, because, while developing a module, you can concentrate on smaller chunks of work without having to bother with all aspects of the application. Last but not least, modules can be reused in other projects; for example, if you have a correctly working and bug-free invoicing module, then you can reuse this when developing a new online store or a next-gen warehouse logistic management tool.

Modules in JavaScript

In the new ES6 standard there is a clear way to define modules in JavaScript. Since the ES6 standard is not yet supported by most browsers, I will show you how modular programming is done with today's JavaScript standard.

First, I will use a self-executing function for defining a module called CarManufacturer.

var CarManufacturer = function() {
    var manufacturers = {
        GM: {
            name: 'General Motors',
            brands: {
                Cadillac: ['Escalade', 'ATS', 'XTS'],
                Chevrolet: ['Camaro', 'Spark', 'Malibu'],
                Buick: ['Verano', 'Regal']
            },
            models: { }
        },
        BMW: {
            ...
        }, Mercedes: {
            ...
        }, Volkswagen: {
            ...
        }, Ford: {
            ...
        }
    };
    return function(name) {
        return manufacturers[name];
    }
}();

I created a function where I declared that the manufacturers object should have inner objects for each manufacturer, and that the manufacturers have a name, brands, and models. At the end of the function, I return a new function, which receives the name parameter. The function returns the corresponding JSON object for the name parameter. When you execute the code inside a browser, you can see the details in the console window:

javascript modules

The code above basically makes the CarManufacturer function available in the global scope, which, in case of bigger module hierarchies, is not a good practice because it can cause name collision between functions and objects. A better alternative is to pass in an object, which will hold the function CarManufacturer. With this approach, we can simulate the existence of name spaces in JavaScript.

(function(exports) {
    var manufacturers = {
        GM: {
            name: 'General Motors',
            brands: {
                Cadillac: ['Escalade', 'ATS', 'XTS'],
                Chevrolet: ['Camaro', 'Spark', 'Malibu'],
                Buick: ['Verano', 'Regal']
            },
            models: { }
        },
        BMW: {
            ...
        }, Mercedes: {
            ...
        }, Volkswagen: {
            ...
        }, Ford: {
            ...
        }
    };
    exports.CarManufacturer = function(name) {
        return manufacturers[name];
    };
})(window);

Notice the difference in the first line, where I defined a self-executing function that received a parameter called exports (it's a best practice to give this name). Everything is the same in the manufacturers declaration, but at the end of the function, I assign a new parameter to the exports object, CarManufacturer, which is a function and returns the name, brands and models assigned to the manufacturer.

When I invoke the self-executing function, I pass in an object that I'd like to assign the new module to. In this case, I passed in the window object because I wanted to use the module in the browser. With this code, I get the same functionality that I had before, but with the flexibility to assign the module to a different name space (not only to the global scope).

javascript modules second pattern

As you can see, the window object has the CarManufacturer object available, and the result of the executed code is the same.

Another option to define and reuse modules is to use RequireJS and AMD. You can read more about these two on the RequireJS website.

Nowadays, JavaScript packages usually contain only one module. The Node Package Manager and JavaScript Package Manager (JSPM) is a good example of creating, publishing and reusing JavaScript modules. You can read more about these here: JavaScript Package Management and How to build your own NPM package.

Posted 2 July, 2015

Greg Bogdan

Software Engineer, Blogger, Tech Enthusiast

I am a Software Engineer with over 7 years of experience in different domains(ERP, Financial Products and Alerting Systems). My main expertise is .NET, Java, Python and JavaScript. I like technical writing and have good experience in creating tutorials and how to technical articles. I am passionate about technology and I love what I do and I always intend to 100% fulfill the project which I am ...

Next Article

Using WebAssembly