close

Day 8: Architecting your Front End JavaScript

Front end development has matured a vast amount in the past few years. We’ve seen a focus on tooling, testing and dependency management, with libraries and tools like Grunt, QUnit, Jasmine, Bower, and RequireJS to name but a few. As front-end developers, we now work in an environment akin to that of our back-end relatives. The workspace of the back-end developer is one of terminal windows, multiple command line tools and plugins to make every part of their development cycle as easy and as frictionless as possible. Front end developers have this too now, and that’s brilliant.

However, one area that deserves a lot more attention than it gets is architecture. The process of architecting applications is something that can’t be ignored. Don’t panic, this isn’t an article about structuring and designing complex JavaScript applications. Instead, what I want to talk about is the process of structuring any JavaScript, and hopefully convince you that it’s always worthwhile, regardless of if you’re building the next Rdio or adding some finishing touches to a standard CMS based type website. If you don’t, it will come back to bite you. We will look at some common faults in code, and how you can avoid them.

This article isn’t just about writing new applications, and structuring them. Most of us have plenty of old projects that could use a bit of care. If you don’t have any new projects coming up to apply some of this article too, there’s nothing wrong with going back and tackling the code base on an old project. Before we dive into architecting applications, I’d like to look at some common red flags when it comes to writing code. By avoiding these common pitfalls, you can increase the maintainability of your code ten-fold. After we’ve tackled these problems, we can look at architecture.

We’ve all been in the position of revisiting a project that’s been left untouched for a long period of time, and been unable to determine half the code’s purpose, or what on earth you were thinking back when you wrote it. This is symptomatic of not putting due care and consideration into your code’s structure, how it works and how it reads. Front-end JavaScript is particularly vulnerable to this; the reuse of code through a jQuery plugin you found on GitHub, or a library someone tweeted once that you happily copy and paste into that exponentially growing app.js file, does not immediately lend itself to structure and maintainability.

Code Smells

The term “Code Smell” was coined by Kent Beck in the late 1990s, and was popularised further in the book “Refactoring: Improving the Design of Existing Code” (a book I highly recommend every developer reading). When you find yourself reading over some code and grimacing a little, or hesitating before moving on, there’s a high chance you’ve spotted a smell. It’s something that makes you nervous, you can see room for improvement or you’re aware that the code could be written better. It might feature some easy to spot problems, such as duplication, have some badly named variables, or be a function that’s far too long to be understood at a glance.

Signs of unmaintainable code and how to avoid

Developing in such a way that code remains maintainable over long periods of time, throughout changes to requirements and over many iterations of library versions is challenging. It’s probably one of the most difficult things developers have to cope with, and it’s something that can only really be properly learned and appreciated over time. The more code you write, the better you will become at it. That said, there are some things you can do along the way to help you and your team out. By learning to spot and quickly refactor any smells, you can keep your code more maintainable with very little overhead.

Comments

I’m sure I will get some flak for this, but recently I’ve been finding that having to excessively comment my code is not a good practice, as a lot of programmers are initially taught, but a smell. Sure, I understand any file with more than a few lines of code may have a general comment describing its purpose, but what I’m talking about here are comments to explain what one small section of the code is doing. I’ve seen three lines of code preceeded with a four line comment explaining what the lines below achieve, and why they are such. That’s a sure fire sign that you’ve written something that is just confusing.

Repetition

If you have to write the same line multiple times, with only a couple of very small tweaks, something is probably untoward. It might seem insignificant, to copy and paste a couple of lines and make a small tweak, but the short term gain is far outweighed by the extra cost in changing. Requirements change, and now you’ve just made one change have to now be done manually in another place.

Friction

Have you ever gone to make one change to a site, perhaps a quick JavaScript behaviour change requested by the client (“that carousel should go the other way!”), and found it much more awkward than it should be to change? Maybe you have to dramatically change your HTML (and hence your CSS) to accomodate one small JavaScript tweak, or one JavaScript tweak leads you down a rabbit hole of problems. This one change has a knock-on effect and before you know it you’re rewriting everything. Clearly something’s awry when this happens. It’s particularly easy, especially with jQuery or similar, to tightly couple your HTML to your JavaScript. Of course, the nature of JavaScript means that your JavaScript will be linked to your HTML, but making that link as little as possible is the goal. By doing this, a small HTML change need not dictate an entire JavaScript rewrite. Keep your code decoupled, and the friction is dramatically lessened.

Large methods

In his talk on refactoring, Ben Orenstein lays down some rules for writing methods (or functions). The basic rule is as follows: large methods are inferior to small methods, and methods with more parameters and inferior to those with less. Simply put: write smaller functions. The best type of function has a one line body, and takes no arguments. Of course that’s not always possible, but splitting your code up into functions brings so many benefits – and not only from a reuse point of view. Consider a method named calculateAreaOfSquare(x):

var calculateAreaOfSquare(x) {
    return x * x;
}

The example is a little contrived, but as a function goes it’s pretty good. It only takes one argument, and its body is also one line. This is great, we now have a nice method for calculating the area. What’s more, when we use this method elsewhere in our code base, its name tells us immediately what the function does, without us having to hunt down the code.

Naming Conventions

Naming things is often quoted as one of the most difficult things that we do as developers and I tend to agree! There’s a fine line to be draw between succinctness and verbosity. Personally, with most editors having some form of autocomplete, I prefer to come down on the more verbose side of naming. As soon as I type two characters, my editor will pop up suggestions and I can tab to complete it anyway, so trading an extra few characters in return for clarity, particularly when I revisit some code further down the line, is an exchange I am more than willing to make.

Embracing JavaScript for Architecting

A lot of people get into JavaScript through a library, commonly jQuery (jQuery was my first exposure to JavaScript). This is a good thing but it does mean that people sometimes skip out on the fundamentals of JavaScript, meaning often code is written much more awkwardly than it has to be. Developers who enter JavaScript this way are often left unaware of the basic constructs of the language.

The prime example of this is JavaScript objects. jQuery uses them all the time for passing in options. I see people do this all the time quite happily, unaware that they are actually using a JavaScript object.

$("foo").animate({
    width: 200,
    height: 300
});

But even so, not many learn the basics of a JavaScript object and what it can do. When it comes to structuring code, they are invaluable. A typical JavaScript file might be strewn with global variables and methods:

var height = 20;
var width = 50;
var x = 0;
var moveToNextItem = function() { /* snip */ }
var startAccordion = function() { /* snip */ }

When this happens, it becomes incredibly difficult to tell what’s going on, which functions affect which variables and which code is related, and which are entirely different parts of your app. Objects can help:

var accordion = {
    currentItem: 1,
    domElem: $("#accordion"),
    startAccordion: function() { /* snip */ },
    isAtEnd: function() { /* snip */ }
    // and so on
};

var carousel = {
    currentItem: 1,
    domElem: $("#carousel"),
    transition: function() { /* snip */ }
    // and so on
};

Immediately, with very little extra typing or effort, code is nicely contained, and it becomes easily apparent what each part of the code does. I’d also go further and split these objects into their own files, as there are plenty of tools that can help you concatenate and minify when it comes to deployment. Setting your own conventions, as I’ve done above with the domElem property, for example, is also recommended. You absolutely do not have to follow how I do it, but come up with a set way of structuring your code and naming it, and then referring to other parts when you are typing will be second nature.

These objects can then be exposed globally by attaching them to a global variable:

window.App = {};
App.accordion = accordion;
App.carousel = carousel;

This is a vast improvement compared to the code we saw earlier, which throws variables and functions all around the place with no structure or logic. It might make sense to you now, but will it in a few months time when you have to revisit it? I doubt it. If you’ve structured your code, named methods and properties properly, and have each individual part of your JavaScript app in its own object, it will take a lot less time to reacquaint yourself with the code.

Conclusion

If you go away from reading this article and, the next time you sit down to add some JavaScript to a site, you stop and pause, thinking about how you could structure your code, then my job has been done. Even if you think you might only write 2-3 lines of code, I would still encourage you to give it some thought. It’s easy to start off without thinking about it, and before you know it be face to face with a giant monolith of a file of unstructured nonsense. Time spent at the beginning pays dividends later on. If you’d like to read more, I recommend Addy Osmani’s Essential JS Design Patterns, which covers in detail a number of approaches to structuring complex code.