Writing Modular JavaScript

LESS

I will start off by saying that I am no guru when it comes to JavaScript. There are guys who will have me for breakfast when it comes to this stuff, as they were in this business way before I knew what a span was. That said, I am starting to get cosy enough with JavaScript to a point where I feel that I can share some of what I have learnt over the past few years. This article is geared towards intermediate JavaScript developers who aspire to becoming better developers. In my quest to becoming a decent developer, I scoured the web for good resources and I feel that it is only right that I give back.

Programmers with a background in languages such as Java and C++ dislike JavaScript because it does not have structure and well, it is a ‘weakly typed’ (= no type declarations) programming language. What the detractors don’t or refuse to see however, is that; because JavaScript does not force a structure on you, this allows expressiveness and imagination. That said, this freedom is often abused by developers who write unreadable and unmaintainable code. To combat this, we can approach coding in a more pragmatic way, by writing our code in a Modular fashion and adopting proven coding techniques, better known as design patterns.

Design patterns are proven coding techniques that make code readable, scalable and maintainable.

There is a plethora of material on design patterns and I give a few links to my favourites in the “useful resources” section below.

Modular code is a term that is now prevalent in the JavaScript echelon which simply means; writing your code in sections that are readable, scalable and maintainable. We have all written ‘spaghetti’ code due to time constraints or just out of sheer ignorance (we didn’t know any better). Usually within a few months we can hardly discern our own code, not to mention the mess we leave for people who inherit our code.

Writing Modular JavaScript gives structure to your code, and helps in limiting the number of global variables, which in turn improves the overall performance of your application/website. I particularly like the object design pattern when writing Modular code as it makes reading and maintaining code such a breeze. Well, I think it’s time to get down to the nitty gritty of Modular JavaScript.

Task at hand

To demonstrate the concept, let’s set up a module for a twitter widget that displays the latest tweets from a twitter account on a website. It displays the first 6 tweets and offers a ability to load more tweets by way of a button.

Our Module

Let us simply call our module TweetsWidget. Normally, I would use the camel case naming convention for my variables but I will capitalise module names as it makes them stand out.

Module definition


	var TweetsWidget = {}

Configuration

To make our widget configurable and give the users more leverage we will provide some settings that can be changed to suit the users needs. Our widget module will have methods that perform different tasks. Since these methods might need access to the configurations, we will create a variable c which points to the configuration settings.

Settings

var c,
    TweetsWidget = {
	settings:{
		tweetCount: 6,
		tweetsWrapper = $('#our-tweets'),
		moreTweetsBtn = $('#tweets-btn')
	},

	/*------------
	| innitialise
	-------------*/
	init: function(){
		c = this.settings;
	}
    };

Binding widget events

Since we are adding a button for users to load more tweets if they so wish, let’s create a method that handles the UI events of our widget. Some developers may view this as unnecessary, but I think it makes our code more structured and readable. This will invoke the method that actually does the work. i.e loads more tweets.

Settings

var c,
    TweetsWidget = {
	settings:{
		tweetCount: 6,
		tweetsWrapper = $('#our-tweets'),
		moreTweetsBtn = $('#tweets-btn')
	},

	/*------------
	| innitialise
	-------------*/
	init: function(){
		c = this.settings;
		this.evntHandler();
	},

	/*---------------
	| click handler
	-----------------*/
	evntHandler: function(){
		c.moreTweetsBtn.on('click', function(){
			TweetsWidget.getMoreTweets(c.tweetCount);
		});
	},

	/*------------------------------
	| utility that loads more tweets
	----------------------------------*/
	getMoreTweets: function(num){
		//we use num as a parameter for the number of tweets we want
		//we probably use some AJAX here to avoid entire page reloads.
	}
   };

We will not write the getMoreTweets method as this is only a demonstration of how to structure our code. That’s it! We now have a module whose job is to handle the loading and displaying of recent tweets onto our site. It is evident that there is no ambiguity as to what the code does, it’s readable and maintainable. If we decide to augment our module, all we have to do is add another property to TweetsWidget and invoke the method via the init function.

What next?

We can now use another script, whose job is to load modules, to call the TweetsWidget module. This script will probably be used as a module loader as it is very likely that we will have more JavaScript on our site.

Module loader


(function(){
	
	//load tweets widget
	TweetsWidget.init();

	//load some other module
	AnotherModule.init();

})();

This is perfect on small projects. On big projects however, the number of modules can quickly get out of hand which could lead to big performance overheads and slow page load times due to the number of files being loaded. Also, you might not necessarily want some of the modules loaded into every page on your site.

To combat this, we can use a Asynchronous Module Definition loader (AMD). RequireJS is a very popular script that handles module loading very well. I am not going to go into details about AMD or RequireJS as they both deserve their own forum. I will nonetheless encourage you to check out the ‘useful resources’ section below.

Summary

The benefits of writing Modular JavaScript are clear for all to see. Some people might argue that loading several JavaScript files increases page load times. I would say that this is becoming less of a problem with modern browsers that have faster rendering and JavaScript engines. Another solution to the problem is to load your files asynchronously using tools such as RequireJS. Among other useful features that RequireJS brings to the table, is a build tool that amalgamates all your files and minifies them before serving them to the browser.

Writing JavaScript in a Modular fashion will also go a long way in nullifying the perception that JavaScript is messy, unreadable and unmanageable. If we all as developers get onto the Modular JavaScript bandwagon, then maybe, just maybe, all the naysayers might come along for the ride.

Useful resources