Modularisation with Require.js

Require.js is well covered ground. Smarter people with more experience working with it have got the basics at very least sorted. I’d recommend reading some or all of the linked articles for your Require hit, really. This one by Aaron Hardy in particular is wonderful, although only the last page actually covers Require, the whole thing is excellent. So, with the caveat that there are better places to get this information in place, what is Require.js?

What is Require.js for?

Require is a JavaScript library for Asynchronous Module Definition. It is by no means the only one available, but it is one of (if not the) most popular. Asynchronous Module Definition is an API for defining distinct modules of JavaScript with explicit dependencies. These dependencies can then be loaded asychronously if that’s your bag, although in the real world I have reservations about this. Powerful and unfounded reservations.

So why use it?

The main attraction to me is project structure. Using Require I can write my JavaScript in small cohesive files without any fuss. Gone are the days of sprawling JavaScript files that keep everything together because of a chain of dependencies and a reluctance to separate files based on some faith that they’ll sort themselves out in the end. With require each file is a sensible module of code and the other modules that it has a relationship with are listed at the top of the file. Lovely.

It also kills the risk of accidentally introducing an unintended dependency. I won’t start referencing things I shouldn’t just because they are available to me because making them available is an action that requires a moment’s thought (and it really is just a moment).

The final thing it brings to the party is asynchronous loading. As the page is loading, Require will establish all the dependencies of your Main Javascript file, including nested dependencies and load them asynchronously. When I say Main here I really mean it in terms similar to a Main file in Java – this should be the single starting point for all your JavaScript on the page so the dependencies and nested dependencies should be all the JavaScript on the page. Since all these files are loading asynchronously it should give you a full suite of JavaScript very quickly. It’ll also cache your modules so if a single module is reused on future pages, its already loaded and don’t need to be grabbed again.

I haven’t done any tests of the actual effect of this in reality yet, so what follows is really nothing but prejudice and a resistance to change. Loading modules asynchronously like this means adding a huge number of extra http GET requests to your page load. Sure each file is coming down quickly, but that goes against everything at least one thing that I’ve been taught about web performance – keeping requests to a minimum. However! Require even has suspicious curmudgeons like me covered too.

Part of the attraction of Require over alternative AMD loaders is its optimizer r.js. This can be used before serving your code up to minify, obfuscate and concatenate your modules. So far my only success has been bundling everything into a single file, but I understand it is possible to configure it so that you produce a site-wide bundle and a separate bundle loaded separately for every page. This is my preferred solution based on no actual testing. Fortunately though, once I’ve worked out how to make it go, it should be easy to try all three of these options without impacting the actual code. This flexibility makes me happier than is reasonable.

Next time: details of how to use Require (Spoiler alert: It’s really easy).

Tagged , , , ,

One thought on “Modularisation with Require.js

  1. […] is, as you know, all about modularisation. Fortunately, Backbone makes it pretty obvious what makes up a Module. Is […]

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: