Genuine Interactive recently built a new site for the MIT Regional Entrepreneurship Acceleration Program (MIT REAP). We tried some new libraries and architecture for the first time, so let's take a look.
The revealing module pattern has been our go-to application pattern for a while. Another recent project used Backbone.js, but with no particular structure. That was a learning experience, but I wasn't sold. Then I attended BackboneConf, and got excited to try it again.
Right before we started front-end development on MIT REAP, Addy Osmani and a crack team of developers revealed Aura. Aura implements a modular, distributed, event-driven application architecture of the type advocated by Addy and Nicholas Zakas. Aura gave me an opportunity to work with Backbone while letting us try this distributed architecture and giving us a sensible file structure to work with.
Once we got started with Aura, going back to the old way never even crossed my mind . I'll likely dig deeper into Aura in a future post, but in short, it provides an easy way of building and wiring together our widgets. Nearly every part of the front page is a separate widget that does what it needs to do and alerts other widgets to user interaction. Fire-and-forget is a fun and easy way to build an application.
…though the really early version of Aura we used didn‘t let us do this as nicely as we might have hoped. The publish/subscribe functionality in this version was completely intertwined with widget start/stop functionality. Publishing an event caused the application to look for and attempt to start a widget by that name. If a widget didn’t exist, it would throw an error. I ended up using Ben Alman's Tiny PubSub gist to get the messaging I needed between widgets. I thought maybe I didn't understand how this part of Aura worked, but it turns out that it was a real issue that Addy has since fixed. I recently updated Aura on another project I'm working on and removed Tiny PubSub.
Some other tweaks I made were part personal preference and part what I believe are real improvements. I replaced Underscore in the Backbone implementation with Lo-dash , which is higher-performing drop-in replacement. I also implemented a version of Rebecca Murphey's SuperView, which she showed off at BackboneConf. The SuperView provides several helpful methods for Backbone Views that you always tend to find yourself writing over and over as well as some useful post-render and post-place-at methods. Instead of directly extending the Backbone View object, we extend SuperView and get these awesome methods to use.
The one thing I found lacking in Aura (and is still a bit of a drawback) was its lack of routing support. We wanted to follow a link from the front page map, but then use the back button and return to the same zoom level and focus area. Aura‘s set up breaks Backbone’s built-in routing, which is simple, stable, and powerful, but for a this application, I had no problem using History.js.
It looks like the direction Aura will go on the routing issue will be to add it as an optional extension, or more likely, leave it as an exercise for the user to fill in their own routing solution. I‘d like to tinker around with Backbone’s routing to see if I can create a plugin that will ‘fix’ the functionality for Aura. Or maybe I'll just stick with History.js.
The Intro Tour
The introductory tour is pretty straightforward. It is essentially a modal that fires events to tell other widgets to highlight themselves by setting their z-index to higher than the translucent overlay. After I put this together, I saw Joyride, a jQuery feature tour plugin, mentioned somewhere. It might have saved us a little time, but it was fairly trivial to build our own from scratch.
The most functionally interesting front-end feature of the site is the interactive map. This is actually a pretty straightforward implementation of MapBox using the Leaflet and Wax libraries pretty much exactly as the tutorials show you.
The one big exception was the dynamic country dots. These are markers that change in size depending on the number inside (which are also a live-text part of the marker). To do this, I ended up using a modified version of the workarounds found on the Leaflet forums.
Lastly, to make the country dots switch out to the granular point icons at higher zooms, I used multiple GeoJSON layers tied to the map's zoom level. Leaflet has built-in events I was able to tie into to change out GeoJSON layers on map zoom.
My only complaint about Leaflet was that in the last week or so of active development, they upgraded from 0.3.x to 0.4. That doesn‘t sound like a huge jump, but there were some huge breaking changes - especially in GeoJSON layers. Obviously, I didn’t want to change out the library that would break my existing site, but the Leaflet team updated all the documentation on the Leaflet site to the 0.4 version. All of the 0.3.x documentation I needed to fix a couple of last-minute bugs was gone. I spent a lot longer than I would have liked tramping through 0.3.x‘s source code figuring out available options and ways to fix my bugs. There’s a link in the API documentation now for the 0.3 docs, but it's really just a link to the 0.3 source code on github - not nearly as useful as the all-in-one-place API documentation on the Leaflet site.
So library developers, my plea to you is this: If you make breaking changes in your library, leave an easy way to reach the previous version‘s documentation. You’ll be saving those of us unable to upgrade hours of headaches.