Modularity in JavaScript MVC Frameworks
JavaScript MVC architectures are a de-facto standard when you create complex single-page JavaScript applications. But it doesn’t stop here. MVC helps to separate reponsibilities for coordinating the data (model) and visualization (view), but it doesn’t have a concept for coordination among an application’s modules or widgets as you might call them.
Modules? I don’t Have Anything Similar to that!
Modules is probably not the right term in JavaScript applications, better call ‘em widgets. A widget is something atomic with a clear responsibility, a mini-app basically that can be instantiated (possibly multiple times) on an arbitrary part of your application. You might not be accustomed to think from such perspective and therefore start straight off without building your app. That might work just fine initially, but once it gets more complex you’ll get into trouble for sure. Therefore, next time when you start building something bigger, stop for a moment and try to identify possible widgets.
Consider for example GitHub’s site:
I just quickly went over its UI and marked the regions that “might” possibly be independent widgets. I just highlighted some of the most obvious ones (but there are obviously a lot more than those).
Separating your application into smaller parts is essential for keeping your architecture clean, reusable and mainly maintainable. The principle is a known concept in computer science: “divide and conquer”. Divide everything up into smaller parts which have
- lower complexity
- are easier to test
- easier to extend
- cause less headaches
- (etc…)
and then compose them again together to form the whole application.
But Wait: My Widgets Have to Communicate!
Sure, modules (or widgets) within your application need to communicate with each other. Such communication creates dependencies as widget A needs to have a reference to widget B if it needs to invoke some operation on it, right? Well, not necessarily, as that would again couple those widgets together and you couldn’t exchange widget B arbitrarily without having to also change widget A.
Therefore, a common practice for creating a modular architecture is to decouple communication among components through event broadcasting mechanisms. Candidates are pub/sub architectures but also the Observer pattern. Below are just some frameworks I picked out that target the issue of modularizing large-scale applications.
AuraJS - Widget Architecture for Backbone
Addy Osmani - who is a big proponent of JavaScript architecture best practices - started a project called AuraJS with the intention to bring such modular widget-like architecture to Backbone.
Aura is a decoupled, event-driven architecture for developing widget-based applications. It takes advantage of patterns and best practices for developing maintainable applications and gives you greater control over widget-based development. Aura gives you complete control of a widget’s lifecycle, allowing developers to dynamically start, stop, reload and clean-up parts of their application as needed. AuraJS GitHub
You can read more on its GitHub repo or here.
Addy also published some good reads related to this topic. You should definitely take a look at them:
- Patterns for Large-Scale JavaScript Application Architecture
- Presentation: Scalable JavaScript Application Architecture
MarionetteJS - Another Backbone Extension
Similar to AuraJS, also MarionetteJS takes an event-driven architecture approach.
Backbone.Marionette is a composite application library for Backbone.js that aims to simplify the construction of large scale JavaScript applications. MarionetteJS Homepage
A couple of weeks ago, they released v1.0 with components like RegionManager
and EventAggregator
. Those concepts sound quite similar to PRISM (another modular application framework for .Net) and indeed when I asked the author:
:) definitely not coincidence. I spent 5+ years building large scale winforms apps, and worked with prism just enough to understand the composite architecture it created. I built a very large system with patterns from the Enterprise Integration Patterns book, which are all present in PRISM and Marionette now. This is definitely the influence and direction that I took with Marionette :)
Decoupling in JavaScriptMVC
JavaScriptMVC has the concept of modularization already build-in since v3.2.
The secret to building large apps is to NEVER build large apps. Break up your applications into small pieces. Then assemble those testable, bite-sized pieces into your big application. JMVC Docs: Organizing Your App
Already the proposed folder structure of a JavaScriptMVC project suggests such approach. A couple of days ago, Justin (one of the creators of JavaScriptMVC) published two videos where he dives into this concept again.
The videos give a preview of how the upcoming release of JavaScriptMVC v3.3 further facilitates such decoupling among widgets.