Tasks!

This is a sample JavaScript application hosted on github using RequireJS, Publisher, jQuery, Dust, QUnit, QUnit-TAP and PhantomJS. Addy Osmani has a great article describing some of the challenges this application attempts to overcome. Download it from github and read through the app/js source, I hope it'll be insightful. The repository also contains a README about all the application utilities for testing / building / etc.

Yes, this could be done in less than 100 lines of jQuery inside a domready function. The point is to demonstrate how to build an application that can scale to something really complex. Note that every module is small, and every method is tiny. It's easy to find and fix a bug in three lines of code.

RequireJS - Modular Development with AMD

Writing modules with RequireJS helps keep code organized both in the file system and in the business-logic of the application. During development, files are loaded asynchronously in the browser. This makes adding new modules completely painless, removing the temptation to do too much in one place (too many verbs, not enough nouns). The moment you recognize a pattern, you can create a new module without a fuss: no configuration, no build scripts. Debugging is great too, since each file is loaded individually.

In production, RequireJS optimizes the application by combining all of the modules into a single, compressed file--without requiring any changes to the application.

Publisher

Often, your modules start requiring other modules that aren't really dependencies but rather interactions: if you wave, I'll say Hello!, but you should be able to wave without knowing every person in the world you may ever wave to. You should also be able to wave even if I die. Making each module aware of the others leads to tightly-coupled code that gets error prone and really difficult to maintain. Enter publisher.

Some modules have hard dependencies that make sense but keeping dependencies to a minimum provides more reuse. Rather than coupling our modules together and adding a lot of dependencies, publisher can connect the modules together. The modules don't even need to know about the publisher object. The lib directory contains the modules, the src directory defines how the modules interact with each other.

Building an application this way makes deciding where things go easy. If the list needs to change when something happens, then you edit the list.js files. Easy as that.

jQuery

Not much to say here. The world's most popular, simple, and functional DOM library. In this app, it's been adjusted to work as an AMD module.

Dust - Super Fast Templates

Dust provides asynchronous, mustache-like templating for node and the browser. The templates are compiled into simple functions, so rendering is impressively fast.

Rather than keeping templates in JavaScript strings or <script type="text/html" id="myTemplate"></script> tags, the templates live in the views folder. The app has a compiletemplates script that uses dust's server-side ability to compile the functions into JavaScript strings for inclusion in the browser. There's also a script that watches for changes so it gets compiled as the views are developed.

Testing with QUnit, TAP, and PhantomJS

QUnit provides a great interface, and simple syntax for testing. TAP is a great testing protocol that is gaining momentum in the JavaScript community. You can open up test.html to test in the browser, but sometimes you want to script your testing, consume the output, etc. PhantomJS is a headless WebKit with a JavaScript API. The exact tests run in the browser can be run from the command line or a script. If you have it installed, run $ runtests in the root of this repository.

Fork me on GitHub