Modularized JavaScript with Backbone.js and CommonJS Modules/2.0

As part of my project to create a port of the excellent PHP Twig templating language to JavaScript I've been putting together some demos of how to use it with some of the more popular JavaScript frameworks available. Parallel to that I've been to several different conferences (Wakanday and Rich Web Experience) recently with talks about modularized JavaScript and JavaScript MVC frameworks. So I decided to put together one of the demos using what I've learned from the different talks.

You can find the completed demo in the my twig.js github project. The following are my thoughts from the experience and some instructions for setting up a project using Backbone.js and BravoJS.

You have to do some work to use Backbone as a CommonJS Modules/2.0 Module

Currently, backbone and underscore have Modules/1.1 style exports for use in node.js (or other Modules/1.1 environments). This makes it easy to adapt them to support Modules/2.0 by simply wrapping the js files with a modules.declare call. This would be very easy to automate with a build script for your application.

MVC on the client is not MVC on the server

It's worth making the point that you don't have to do MVC on the front-end the same way as you do it no the backend. Because you don't have to serve different content types (JSON, HTML) from the same MVC you can take more liberties with your design. Also, because of the way Backbone lets you bind to events from the view, it makes it very convenient to write your control logic in the Backbone.View and handle the view rendering with a template.

A good templating engine makes your life much easier

Because you do a lot of the controller-type logic in the Backbone Views, you need a good templating engine for rendering the views. This keeps the HTML out of the JavaScript and makes it much easier to maintain. What I found (using twig.js) is that very granular templates work best. For example, in my twitter demo, the TweetView binds to the change event of the backing model and re-renders the template anytime the model changes. This keeps the UI updated everywhere a TweetView is used.

Here's an example of the TweetView Backbone.View and template:

tweetView.js

tweet.twig

This pattern is by far the best I've used for maintaining a dynamic web application and I'll probably take this tack with future projects of mine. I'm a proponent of well modularized code and this fits the bill nicely. It avoids the pitfalls of relying on global definitions of objects in JavaScript and makes your code much more portable. I anticipate being able to share a lot of code (modules) in future applications between a backend running on Node.js and the frontend web browser; which will be a big improvment over my current stack of Java or PHP on the backend and JavaScript on the frontend. I'll be continuing to experiment with this pattern and I'll likely have more to say on the subject over time as I try it on larger projects.