Creating Modular Front-End Components with RequireJS (Part 2 of 4)

"Previously, on BitCubby..."

In the previous post within this series, we took a brief look at RequireJS. We discussed the purpose of the AMD API and explored some simple examples that illustrate how RequireJS can be used to break your application down into smaller, "loosely-coupled" components.

In this post, I'll dig a little deeper into the process of creating reusable Javascript modules. The jQuery UI Widget Factory will also be making a special guest appearance.

The Revealing Module Pattern

When creating reusable Javascript components, I'm a big fan of Christian Heillman's "revealing module pattern". In a nutshell, the revealing module pattern provides developers with a method for incorporating the concept of public and private properties into their Javascript modules. Here is a simple example of the revealing module pattern at work:

var MyModule = function() {

    var self = this;

    self.publicMethod = function() {
        console.log("Are you down with OPP?");
        self.privateMethod();
    };

    self.privateMethod = function() {
        console.log("Yeah, you know me.");
    };

    self.api = {
        'publicMethod': self.publicMethod
    };

    return self.api;

};

var instance = new MyModule();
instance.publicMethod();

In this example, our module returns an object (self.api), which serves as a window into its inner workings. This object can reference select properties and methods within the module (making them public), while ignoring others (making them private).

To summarize - the "revealing module pattern" will allow us to provide the final user of this module with a straightforward API, while hiding the inner workings behind a nice layer of abstraction. This pattern will form the foundation upon which our module will be built.

The jQuery Widget Factory

The jQuery Widget Factory will aid us in creating the best possible experience for the developers tasked with actually using our module. Before we dig into the code that actually makes this possible, let's take a look at the end-result that developers will be presented with:

HTML

As you can see, a DIV with the "weather_module" ID serves as the container within which our module will live.

<body>
    <div id="weather_module"></div>
</body>

JavaScript - Setup

The code below is all that is required to create an instance of our module.

$("#weather_module").weather({
    'postal_code': 60629
});

JavaScript - Teardown

The process of removing our module from the page is even simpler:

$("#weather_module").remove();

With the help of the jQuery Widget Factory, we can easily tie the "teardown" process of our module with its removal from the DOM. In other words, we can create a function that will be run automatically as soon as our module is removed from the page. The code that makes this possible is shown below.

Code

$.widget('namespace.weather', {
    /**
     * Here, we can define default options for our module.
     */
    'options': {
        'postal_code': 37204
    },
    /**
     * This method is the first to be called when our module
     * is instantiated.
     */
    '_create': function() {

        /*
        Here, I take the "public" methods from our original
        module and create references to them within our jQuery
        widget. As a result, developers can access our original module's
        public methods like so:

        $("#weather_container").publicMethod();

        */
        var module = new MyModule(this.options);
        for ( var key in module ) {
            this[key] = module[key];
        }

    },
    /**
     * This method is automatically called when our module
     * is removed from the page. Any cleanup procedures that
     * need to be run can be referenced from here.
     */
    '_destroy': function() {
    }
});

$("#container").weather({
    'postal_code': 60629
});

While not absolutely necessary, the jQuery Widget Factory provides some additional functionality that the developers tasked with actually using our module will greatly appreciate. That being said, depending upon the needs and constraints of your particular project, you may decide not to include this particular step.

Roundup

In this post, we took a look at the "Revealing Module Pattern," which allows us to introduce the concepts of public and private methods into our module. We also dug into the jQuery Widget Factory, which (among other things) allows us to simplify the process of destroying our module when necessary.

This concludes this installment of "Creating Modular Front-End Components with RequireJS." In Part 3, we will combine the code that we looked at today into an actual RequireJS module. We will also take a look at three important RequireJS plugins related to template and stylesheet loading.