Sunday, April 10, 2011

The jQuery module anti-pattern

I don't really know why I'm writing about this now, but it is on my mind and I want to let it go :)
I like jQuery. Boom. I'm sorry if that hurts your feelings. I like it as a neat DOM access layer and basic building block of desktop websites and applications. I'm saying building block, because only jQuery will not get you far, but that is another story.
There is one rule that you have to keep in mind when you are using jQuery and you care about your code to scale beyond a few lines:
You can never use jQuery modules.
jQuery modules (as in methods and properties hanging off the jQuery's prototype object or, to a lesser extent, things hanging off the jQuery function itself) are practically always the wrong design.
  • They all live in a single namespace, so there is risk of collision.
  • They force a DOM centric application design.
  • It almost never looks nice as an API if you are not implementing actions like "show" and "hide".
Instead for almost all use cases where people use jQuery modules it would be better to use a "stratified" API which is this case just means that you pass the jQuery object you want to work on to a function, rather then calling the function on the jQuery object. While jQuery's beauty derives from chaining its basic methods, this usually doen't make sense for more complex modules.
jQuery.sub() has been introduced to somewhat reduce the risk of namespace collision. I think it will go down in history as the most blatant example of a leaky abstraction because you end up never knowing the exact type of a given jQuery object unless you instantiated it yourself.
What about all those nice jQuery modules, you can copy and paste into your application to make fancy things? My personal experience is that most are of very bad quality, so it makes sense to rewrite them to a stratified API style (usually this only take a few minutes) and then assume ownership of the code and fix bugs as they appear.

Post a Comment