Help – I don’t know my JavaScript library!

You may have come across some scripts out in the wild that have different versions available for a few libraries and wondered how it’s done – surely the author didn’t write the same script 5 times, how on Earth would he remember to roll out the bug fixes across all the versions? You may also have had to create a script that your client will redistribute to other websites; you don’t know what library the website will use, if anyway. You will have to hand your script over to that website’s developer and he will not want to go through your application decoupling it from your preferred library, he will have his own preference that may not match yours or he may have to use the company’s own (that’s how BBC Glow and YUI started).

This may surprise you but using an object oriented style of coding, it’s remarkably simple to abstract out the library itself. It gives you all the advantages of the library without being so tightly coupled. In essence, it’s possible to swap out the library (or even remove it) without affecting the application at all. In programming lingo, this is known as “separating the interface from the implementation,” a phrase I first encountered in the book Pro JavaScript Design Patterns by Ross Harmes and Dustin Diaz (also the book at got me thinking in object oriented terms – I’d recommend it if you’re comfortable with JavaScript and want to improve.)

In technical terms, you create a series of mixins and call them with the objects as the context (because Angus Croll’s idea was really cool), the mixins contain the interaction with library. So long as the mixin retains the same methods (although more may be added if it makes interaction easier), the interface is preserved and the implementation doesn’t matter. If the objects never interact with the library directly, the library itself becomes modular through the mixins.

Examples

To better explain that previous paragraph, let’s build a jQuery image viewer using this mentality. To start with, here’s an example of the image viewer tightly coupled to jQuery. While it’s a far better idea to build the objects with an abstracted library in mind rather than taking an existing object and slowly abstract the library out, this order does make demonstration easier.

When abstracting a library, the first thing to do is to stop passing instances of it to your object and stop storing instances as well. With libraries that wrap DOM nodes to manipulate them, this means storing the raw DOM node rather than the wrapped object. The DOM node is the lowest common denominator between all DOM-manipulating JavaScript libraries, so this step will make changing the library much easier. Every library that wraps DOM nodes should have a way of getting the raw node back.

Start mixing

Now we start building the mixins. The mixins will be the only part of the application that directly uses the library, everything else will interact with the mixins. I’ve find it easier to think of the mixins controlling a small part of the library: classes, DOM tree traversal, animation and so on. Here’s the same example with the classes abstracted out and the “show” and “hide” methods re-written to take that into account. You may have noticed that I use the “jQuery” variable inside the mixins rather than the dollar sign; this simply helps me identify the library being used at a glance, it’s not essential.

You may have noticed the leading capital on the mixin name. This is because of a side effect of Croll’s idea (and one that he didn’t mention at the time) is the ability to execute the mixin and create a new instance of it. I’ve found this to be a remarkably handy trick when it comes to DOM tree traversal and especially for events. Here’s the same example with the traversal abstracted. As you may have noticed, we’ve had to do a little more work in the “draw” method so that we’re only passing DOM nodes to the mixin. Also notice inside the DOM ready function we now use the mixin to find the elements rather than jQuery itself.

Mixins can have static properties (since they’re just JavaScript functions after all) making it possible to abstract things like jQuery’s DOM ready function. Check the “addHandlers” and “handleClick” methods to see the Events mixin in action.

Finally, take a critical look at your library usage. There are some instances where creating a mixin isn’t worth the hassle. A perfect example is jQuery’s createElement wrapper: when creating a simple element, document.createElement will do the same job and without the overhead of a wrapper. This can be the same for simple appending and removing of nodes, although I have found that the amount of time necessary to create my own version of “insertBefore” or “empty” is about the same amount of time necessary to make the mixin, if not more. My next example shows the application without any references to jQuery.

Changing the library

Now that we have an application that’s completely detached from the library, it’s possible to change the library itself without changing the application at all. Best of all, if you need to use a library you’re not familiar with, you simply need to learn how to build the mixins. As you can see in my next example, replacing jQuery with PrototypeJS is fairly straight forward.

However, it should be noted that not all libraries are so interchangeable. The YUI library is more popular than PrototypeJS (according to PPK’s JavaScript library poll) and it’s asynchronous nature means that the mixins can be a bit of a challenge. Not impossible, but a challenge none-the-less.

Wrapping it up

By abstracting out your library, it’s possible to make it changeable at a later stage. I’ve heard it said that the best thing you can do to make your code robust is to think “I don’t know how this will end up” (I think Nicholas Zakas said that, but I can’t find the link) because you instantly start coding more defensively. If you don’t even know which library you’ll end up using, start here.

By the way, if you like this style of coding you may like my Mixin Micro-library – it takes some of the more repetative tasks that this style of code generates and provides handy functions to do it for you.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>