As a preface, make sure you’ve read my super-smart and talented yayQuery co-host Rebecca Murphey’s blog post on this topic
here: On jQuery Large Applications and here: On Rolling Your Own.
Rebecca points out some huge holes in the jQuery-verse when it comes to large-application development, and gives her opinion on why she doesn’t think jQuery is ever a good fit for a large application. I disagree, and she’s successfully convinced me to write a post on why I think what I do, so here we are.
Also, please, no one point out that I prefer Django over Pylons, which is essentially the same argument :D . The difference, though, is that I think Pylons is awesome, and that people should totally be using it for large applications on the backend, as long as they prefer it!
jQuery is a tool (lolz)
I build large applications that use jQuery. I don’t build large applications on top of jQuery. This incredibly important distinction hasn’t been very well clarified thus far in the conversation. I think it’s a fair ambiguity, however, because while it’s possible to use jQuery in well-structured ways, it’s certainly the road less travelled. The ‘common jquery user’ tends to throw everything onto the jQuery namespace, and pull in everything as plugins, and generally very tightly couple their applications to jQuery. I think the distinction is still important for the argument, because it doesn’t rule out the fact that you can write some really nice applications using jQuery.
It’s not jQuery, it’s you.
I think the thought that people are incapable of using jQuery in this manner stems from quite a few bad consulting experiences with companies using jQuery for no reason other than the fact that it’s
the cool thing to do, but using it entirely in an entirely backwards manner. This is also not a good way of making library decisions (at least in the long term). It doesn’t reflect poorly on the code in jQuery so much as it reflects poorly on either the messaging from the jQuery team, or just the general population’s inability to write good code and tendency to do what’s popular. However, if Dojo were the hip-cool-designer library, they would suffer from the exact same problem.
Aiight, with all that out of the way (yikes), let me give my most objective reasoning possible for why I think it’s ok to use jQuery in a large app. Please keep in mind that I’m not advocating against Dojo or YUI3, I’m advocating against the absolute notion that ‘jQuery should never be used for large applications.’ Use what you prefer, of course.
Rebecca’s core argument against rolling your own jQuery large app is that 1) no one else knows your code-base, so supporting is harder, and 2) the solutions in a library like Dojo are built to work together by smart people who have thought long and hard about the problems, and rolling your own are more fragile and can cause issues with upgrade paths and compatibility, etc. These are valid points, but I think they are painted with a narrow frame of reference for the type of app structure you might use in a large jQuery app.
It’s common knowledge that a separation of concerns is key to any large application. Loose-coupling is something that I’ve blogged extensively about in the past. If you have a problem updating a portion of your application, it’s because you wrote it too coupled. This is not unique to jQuery. Dojo’s API stays about as backwards-compatible as they come (seriously), but that doesn’t mean your old code will just work. In fact one of the few experiences I’ve had with DojoX code is that some of the less popular DojoX modules often need changes to return the correct values, or not throw errors. The core of the library, has been significantly more impressive in regards to this, but we’re talking about code that you write, not the library core. I am a fan of Dojo’s backwards compatibility efforts over jQuery’s. Changing an API in a point release isn’t always the most friendly change for devs.
Here’s the list of things that she’d expect from a framework, along with the appropriate solutions I’d consider:
- DOM manipulation tools - jQuery core
- Ajax tools - jQuery core
- A dependency management and build system - RequireJS
- Clear patterns for code organization, such as namespaced modules - The module pattern and a few object literals
- An inheritance system, preferably one that offers multiple inheritance, for sharing code across modules and staying DRY - modules +$.extend
- A non-DOM-centric, loosely coupled API for communication between modules - pub/sub || custom events
- A widget system that makes use of the inheritance system, with lifecycle management (setup/teardown) and templating - $.fn + mustache/microtemplates
- A system for abstracting RESTful server communication - assumes you want REST - but $.ajax usually works anyways…
- For a UI-intensive project, a rich widget system pluggable to arbitrary data sources and designed with an easily-extended API - jQuery UI or ExtJS on jQuery
- For an enterprise project, a11y and i18n provisions, as well as clear patterns for file organization - jQuery UI has many of these, you can also build them in. Require dictates some directory structure.
These requests are pretty obviously skewed to someone who likes working in Dojo. They are all pretty awesome ways to do things, but to say that you needed the module pattern is to entirely overlook other very valid ways of structuring complex code. Of course Dojo offers ways to do things like event-oriented programming over object-oriented. The point here is that, if Dojo has answered every question, and jQuery and friends has also answered every question (perhaps not in the same place), it’s going to be just as hard to pick up the code base and figure out what’s going on. I could structure my Dojo app in a way that Rebecca doesn’t like, and use template overrides for template-languages that she despises, and I could tightly couple my dom elements and their attributes to my data, and it’d all be in beautiful Dojo. That Dojo has answered all the questions does not facilitate that you understood those answers or that you agree with them.
I somewhat reject the notion that using jQuery, Underscore, Require, Mustache, and the module pattern (as facilitated by Require) is “rolling your own.” Sure you piece them together, by choosing how you use them, but you do the exact same thing when you choose how you use the various parts of Dojo. I think that all of these tools are as strong as the Dojo alternatives. You can argue that you could use any of these tools with Dojo because it’s so flexible that you can put anything in, but then you can’t argue that ‘rolling your own’ is bad, because that’s what you just did. Either use Dojo, or agree that sometimes, it’s not that bad to pull in a different way of thinking, you can’t have it both ways.
jQuery normalizes things across browsers when you need it to, and serves as a mostly-fantastic way of doing dom-manip and ajax. If you use it according to it’s strengths, you still can choose some really strong software alongside it that was specifically designed to be awesome at what it does.
Underscore gives you a very solid utility library, much like you’d find in Dojo, and it’s extensible to boot. You can use it in two of the major paradigms natively, and it falls back to native implementations when it can. It’s hardly fragile, and it’s insanely easy to integrate into your project. It’s no worse or better than Dojo’s offering.
RequireJS is likely going to be used in Dojo 2.0 and James Burke, who wrote Require, also wrote most of the Dojo dependency management system. Require incorporates all the sweet stuff from Dojo, plus some really awesome future stuff coming from the CommonJS peeps. Some apps, though, don’t require a ton of dependency management. Single page apps are likely not going to be terribly dependency heavy, and if you want… you can leave out the dependency management system all-together, and still use your modules, just like you always wanted. You can switch it out for LabJS if you want speed too.
Templating was the example that Rebecca used to show that she could roll her own templating style in Dojo. She used mustache instead of the default Dojo offering. I can’t argue against that. I’m in favor of pulling together the correct tools for the job.
A lot of what is nice about Dojo, is it’s prescribed format for creating modules. There’s quite a bit of flexibility, but anyone who could understand the way that Dojo does this could easily understand some of the basic underlying patterns that it’s enhancing. I can use object.create and the module pattern to my hearts content to structure my app, and that’s not some ‘wild tangent’ that no one will ever be able to unravel. It’s a simple, and common pattern that you’d be required to understand to use the Dojo method. Sure there’s no prescribed way to exactly structure this, but that’s the case with the ‘extremely flexible’ Dojo offering as well.
Dojo is a fantastic library that I would encourage you to pick up and add to your skillset. jQuery can be a fantastic tool to use as well. “Rolling Your Own” application with good tools alongside jQuery is no harder to understand than a Dojo app, nor is it harder to support, and it’s likely more specific to your needs. The fragile part of your code isn’t in the tools you use, it’s in the code that you write around them.