These days, I write a lot more code, and my projects have increased in complexity. Often, a single application brings many kinds of data sources and bleeding edge web features together. On the other hand, most of what I build are prototypes, which need to be churned out quickly, work reliably in demos, and look/feel good.
MVC frameworks help write UI code much more quickly, but there are drawbacks too: there are too many to choose from, they don't interoperate with one another, and if you want to release parts of your code to the open source community, only those developers that use the same framework will benefit. The solution is to create a clear separation between core application logic and MVC UI code. This way you can reuse a lot of code and reduce switching costs.
Before jumping in, here's a diagram of the approach:
The rest of the post is about interop problems with JS MVC frameworks, and a closer look reasons for taking the above approach.
MVC frameworks are great
My current weapon of choice is Ember.js, mostly because it makes many decisions that I agree with, providing easy two-way binding, a sane templating syntax, observers and computed properties. All-in-all, it is pretty effective for whipping up consistent UIs quickly.
But there are problems with buying into an MVC framework.
JS libraries are like insects
If you've ever taken a hiatus from client-side web development, you were probably overwhelmed with the amount of new stuff available when you returned. The flipside is that many of the frameworks you were familiar with could have easily disappeared. To be fair, some winners have emerged in the past, most notably in the utility frameworks, where jQuery has risen to the top, and Prototype has fallen to obscurity. In MVC frameworks, however, there are many interesting contenders and, as I wrote earlier, still no clear winner.
So at this stage, going all-in in on a framework may be a bad idea, because what if the community moves on to something else? What if the framework developers get bored, stop caring or cease maintenance for some other reasons? I have this feeling all the time, despite framework authors promises to the contrary. And this is the case even though I build mostly prototypes with relatively short life spans.
Switching cost between MVC frameworks is high
Once you bite the bullet and decide to invest in a framework, you often have no easy way to move your code out of it. If you pick Backbone, but decide mid-cycle that it's not for you, you are in for a world of hurt:
For the reasons outlined above, I'm very much in favor of the former option: having a language-level class abstraction. This seems to be coming soon in ECMAScript 6, and will basically provide syntactic sugar on top of prototypal inheritance. Having a consistent class and module system is one of the main reasons why languages like Dart, TypeScript and Coffeescript are increasingly appealing to me.
Coding to a framework restricts your audience
Because of a lack of interoperability between frameworks and their class systems, if you write non-UI code using a framework, only users of that framework will use your code. It's very unlikely that someone building an Ember application will want to use your library that uses Backbone objects.
Solution: defensive architecture
The basic idea is to separate the core functionality of the application from the user interface into two separate layers. With this separation, you can implement the two layers differently:
Use an MVC framework to implement the UI, and call into the base layer directly. This lets you move quickly and focus entirely on writing the user interface. This architecture lets you build your UI on a solid foundation and avoid getting stuck.
Benefits of this approach
You get many benefits by taking this approach:
If you want to scrap your existing UI and write a new one very quickly, you can easily do this and still reuse large chunks of your logic.
Clear layer separation leads to more maintainable code.
Easy to ship the underlying core functionality as a library or standalone module.
Easy to write unit tests for the core functionality of the application. Unit tests aren't well suited to user interface code anyway.
This is why we can't have nice things
All other widely used programming languages provide a consistent class system, and popular platforms provide a framework for separating application logic and user interface. Until these things come to the web, I'll continue to have second thoughts about embracing any particular MVC framework or custom class system.