Organizing A jQuery Application

by Brian Moschel

Organizing A jQuery Application

Brian Moschel Earlier this week, I realized that every

posted in Development on November 11, 2010 by Brian Moschel

Earlier this week, I realized that every organizing-a-jQuery-application
blog, article, and conference talk misses the most important lesson on
how to organize a jQuery app.

They talk about how to organize an individual widget or piece of
functionality, but not how you can break up an application into
logically separate and testable components.

Separation of concerns is the bedrock of software engineering. It is the
best way to achieve a quality, error free, and maintainable project.

Think about it … If your code’s logic is isolated, how much damage
does making an incorrect decision do? Very little!

The secret to building large apps is NEVER build large apps. Break up
your applications into small pieces. Then, assemble those testable,
bite-sized pieces into your big application.

This article shows how to do this elegantly with JavaScriptMVC 3.0
(which was created with this pattern in mind). We’ll use Rebecca
Murphey
‘s Srchr
app

as an example of this pattern in practice.

Srchr

The Srchr app makes searches using multiple services and saves the
searches between page loads.

Srchr

Install Srchr

To install our srchr app:

  1. Download And Unzip
    JavaScriptMVC

  2. Install Srchr

    ./js steal/getjs srchr
    

Note: window’s users do js steal\getjs srchr

Open srchr/srchr.html to see
something like:

Srchrjmvc

Note: this won’t work in Chrome on the filesystem b/c of it’s insane
cross domain
policy
.

Srchr’s Sweetness

Srchr was built the ‘JavaScriptMVC’ way (i.e. competently). It has a
folder/file structure where:

  • Code is logically separated and tested
  • Code is easily assembled into higher-order functionality.
  • Higher order functionality is tested.
  • We are able to regression test.

Logically Separate and Test

We’ve broken up Srchr into the following components:

  • Disabler – Listens for search messages and disables tab buttons.
    demo
    test
  • History – A cookie saved list of items.
    demo
    test
  • Search – Creates a search message when a search happens.
    demo
    test
  • Search Result – Seaches for results and displays them.
    demo
    test
  • Tabs – A Basic Tabs widget.
    demo
    test

Note: For the test pages, make sure you have popup blocker off!

The following shows the srchr folder’s contents:

Srchrdir

Each of Srchr’s sub components has its own folder, demo page, tests, and
test page. For example, srchr/search looks like:

Searchdir

This makes it extremely easy to develop a component in isolation. Lets
look at the Srchr.History and Srchr.Search widgets a little more in
depth:

Srchr.History

Srchr.History maintains a list of items in a cookie. You can add items
to the list like:

$("#history").srchr_history("add", search);

You can also listen to when items in the list are selected like:

$("#history").bind("selected", function(ev, item){});

The srchr/history folder has the following files to make developing
and testing the history widget independently easy:

Srchr.Search

Search maintains a form that creates search events. You can listen to
search events like:

$("#searchArea").bind("search", function(ev, item){});

You can also set the search form by passing it a ‘search’ object like:

$("#searchArea").srchr_search("val", search);

The srchr/search folder has the following files to make developing and
testing independently easy:

Assemble Higher-Order Functionality

Now that we’ve built and tested each of our widgets, it’s time to
assemble them into the final application. We do this in
srchr/srchr.js

This file pulls in all the widgets and models we will need with steal:

steal.plugins('srchr/search',
    'srchr/history',
    'srchr/search_result',
    'srchr/tabs',
    'srchr/disabler')
    .models('flickr','yahoo','upcoming','twitter')

.then(function($){

And then assembles them.

The following code makes Srchr.History and Srchr.Search work together:

// when a search happens, add to history
$("#searchArea").bind("search", function(ev, search){
    $("#history").srchr_history("add", search);
});
// when a history item is selected, update search
$("#history").bind("selected", function(ev, search){
    $("#searchArea").srchr_search("val", search);
});

Pretty nifty. It’s like we’re hooking up big legos. It’s almost like it
was engineered that way!

Now lets test the app as a whole.

Higher Order Testing

Srchr has the same file structure as our widgets for testing:

When you run the test page
(funcunit.html), you’ll
notice that it runs all the widget’s tests before running the Srchr
tests. This is regression testing! You just have to open up Srchr’s
funcunit page and it will test all the other widgets before testing the
application itself. This is a great way to find low-level bugs. And, the
lower you can find a bug, the more easy you can solve it.

P.S. Unit Testing!

Srchr also tests connecting to the various search services. The test
page is at srchr/qunit.html
and the tests are at
srchr/test/qunit/srchr_test.js

Conclusion

We’ve pretty easily accomplished our goal of splitting the application
up into reusable components that are individually testable and testable
as a whole.

This type of development isn’t really possible without solid dependency
management. Srchr.js just has to include its submodule, view, and model
files. It doesn’t have to worry about their individual dependencies.

If we need to make a change, we can work in the submodule folder, test
it, make changes, then regression test the whole application.

This is why JavaScriptMVC is simply the best way to develop large
applications – it makes the process straightforward and repeatable.

There are multiple (and probably better) ways to break up Srchr’s
components. How you divide up your app is up to you. But hopefully we’ve
shown that you CAN break up your applications easily and it’s a damn
good idea.

blog comments powered by Disqus

CanJS 2.2 Release

Justin Meyerposted in Development, Open Source, Uncategorized on April 5, 2015 by Justin MeyerCanJS 2.2 is out. It's awesome. This article covers the top 10 enhancements added since 2.1. Some of the improvements include Browserify and StealJS support, can-EVENT arguments, observable promises, and in-page automatically rendered templates. The article includes a lot of good JSBins to learn from too.

Getting Started with Cordova

Brian Moschelposted in Development on March 26, 2015 by Brian MoschelAt Bitovi, we’re big fans of building applications with web technologies and using build tools to target other platforms like iOS, Android, and desktop. This article will provide a quick guide to getting up and running quickly with Cordova.

Contact Us
(312) 620-0386 | contact@bitovi.com
 or cancel