JavaScript MV*: Knockout & Durandal
I've been doing a lot of work with JavaScript MV* frameworks lately and I thought it would be a good idea to write down some of my experiences. This isn't going to be about which framework is better, this is just my opinion about several frameworks based on my experiences with them. I've got quite a bit of experience using Knockout on several projects, so I thought that would be a good place to start.
Knockout
This isn't an MV* framework in the fullest sense. It's a really good data binding library, that also happens to render small HTML templates (really just snippets). There are a lot of comparisons made between Knockout and MV* frameworks, but I think anyone that tries to make those comparisons either doesn't understand what Knockout is trying to accomplish or doesn't understand what the other frameworks were designed for. I don't blame them though. It took me quite some time to get my head around the complex landscape that is client-side MV* frameworks; for the longest time I thought Knockout versus Angular was a valid comparison, but now I know it's not.
In my opinion, Knockout has two use-cases that it's really good at:
- Adding a layer of rich client-side interactivity to a server-side MV* framework.
- Serving as the data binding component in a client-side MV* framework you assemble yourself.
In either case, Knockout is only one component of an MV* framework; it isn't a complete MV* framework on its own. In the first scenario, I've successfully used it in the past to add rich client-side interactivity to a traditional ASP.NET application. In the second scenario, you could build your own MV* framework using various specialized libraries (e.g. data binding, routing, etc.) or you could use a framework that someone else has assembled using the same methodology. In this particular instance I'm referring to Durandal (which I'll talk about shortly).
If you decide to use Knockout for either scenario I would recommend a few things to get you started in the right direction:
- Don't mix your JavaScript and your HTML; keep them completely separate. I've covered this specific topic before and the quick summary is to use the classBindingProvider plugin to keep your HTML and your logic separate.
- Spend some time thinking about how you should structure your JavaScript models and logic. Knockout doesn't care how you structure your code, but if you don't come up with a standard structure it will quickly get out of hand (especially if several developers are working on it at the same time).
- If the models coming from your server are big and complicated, the default mapping plugin might not cut it. I've had good experience with the viewModel mapping plugin and I'd recommend it to others if you have to deal with these more complex scenarios.
- If you're only targeting browsers that are ECMAScript 5 compliant (IE9+), then I'd recommend using the Knockout ES5 plugin. This plugin makes use of ECMAScript 5 getter/setter pairs, which means that you don't have to remember all of the parentheses the Knockout traditionally demands.
Durandal
This is the framework that should be used when attempting to compare Knockout with various MV* frameworks. Durandal is a fully-featured MV* framework that uses Knockout as its data binding mechanism, along with few other libraries and some custom code to make everything work well together. If you're a big fan of Knockout or have a lot of experience with it, using this framework is an easy way to take your first step into the client-side MV* world.
I don't have a ton of experience with this framework compared to a lot of the others, but I did spend a full week building various demos to give this framework a fair chance. Based on my limited experience, Durandal does one thing very well:
- It makes it very easy to create a client-side MV* application if you have experience with Knockout and the standard ASP.NET stack.
It's great for that and I found it very easy to use given that background; however, I believe Durandal has some weaknesses:
- It has a very small community compared to the other major players in this space. This is fine for small applications, but when you need to build bigger applications that you need to support for years, a large community becomes a significant resource that must be considered.
- By definition, the framework is an assembly of several other libraries. For some this could be an asset since you can easily switch-out components. For me, if I'm reaching for a large framework like this to start with, I'd actually prefer something that was designed end-to-end with that intent.
- The project is maintained largely by a single developer. Rob Eisenberg has done great work and I'm honestly impressed with everything he's done, but having a larger number of people backing the project and driving it forward gives me more confidence that it will be around for a long time (I know that's largely an illusion, but it still makes me feel better).
- There was recently a failed Kickstarter to fund the next phase of development. I know that doesn't signal the death of the project, but it doesn't inspire confidence that this is something that the community will get behind for years to come.
Again, I think it's a great framework for what it's good at, but it just didn't match the criteria for the project I was evaluating it for.