Thứ Hai, 14 tháng 4, 2014

Angular and Durandal Converge

Hello! My name is Rob Eisenberg (@EisenbergEffect). I'm the architect and lead developer behind Durandal, a JavaScript framework that has historically been an alternative to AngularJS...or you might even say "competitive" with AngularJS. So, what am I doing here on the AngularJS blog? Did I exploit the Heartbleed Bug to steel passwords and post my own content here? Far from it. Actually, Brad Green asked me if I would cross-post my latest article, written for the Durandal community. He thought you might find it interesting.

...

Frequently I receive questions about Angular vs. Durandal. "Which one should I use?" I usually have to answer with "it depends." While these two frameworks are very similar in many ways, each one has unique strengths and weaknesses. Sometimes their differences can be critically important for certain projects. This fact can make choosing the right framework a very difficult or risky decision. But, what if you didn't have to make any trade-offs? What if you could have the best of both worlds?

tl;dr

  • I've been working as a member of the AngularJS 2.0 Core Team for almost three months now. We're taking the best ideas of Angular 1.x and the best ideas of Durandal 2.x and converging them in Angular 2.0 to make a truly amazing developer experience.
  • Durandal 2.x isn't going away. I'll document how to migrate, but if you don't want to or can't, don't worry. Durandal 2.x will continue to be maintained.

Three Months

Back in January, the AngularJS team held their first conference, ngConf. My friends John Papa and Ward Bell attended and had the opportunity to share with Brad Green (AngularJS Manager) about some of the cool things I was doing with Durandal, as well as our NextGen focus. John thought we should meet and so he introduced us via email. I sent Brad a few links to my work and prototype demos. He was very interested, so we set up a meeting.

When I met Brad, I found him to not only be an amicable fellow, but someone who was generally interested in collaboration, innovation and advancing the web. (In fact, I've found this to be true of the entire Angular team.) What we discovered was that the goals I had for Durandal NextGen were strikingly similar to what Google was planning for AngularJS 2.0. Doesn't it just make you want to ask "Why not join together to build the best JavaScript app building experiencing imaginable?" So, we hatched a plan. There were two primary goals:
  1. I would join the AngularJS 2.0 Core Team and help to design and implement AngularJS 2.0, bringing all my experience with Caliburn.Micro and Durandal into the mix.
  2. Whatever ideas or critical features from Durandal did not make it into the Angular 2.0 code-base, I would build as optional plugins to Angular 2.0. Thus, most Durandal users will have a direct migration path to Angular 2.0 either by using "vanilla" Angular 2.0 or by using the Durandal "flavor" by dropping in one or more optional plugins.

The idea here is simple. Let's work together. Let's take the best ideas of Angular 1.x and the best ideas of Durandal 2.x and converge them in Angular 2.0 to make a truly amazing developer experience.

I've been quietly working towards these goals for almost three months now.

Shared Ideas

As I mentioned, Durandal and Angular already had a lot in common and our separate plans for future versions had even more in common. Here's a summary of some shared ideas we had:
  • Modules - Durandal 2.x already had an extremely versatile module system based on AMD. In our NextGen we were looking to add support for ES6 modules and possibly CommonJS as well. Angular's module system was non-standard and they were looking to move towards support of AMD and ES6 modules.
  • Lazy Loading - Due to Durandal's AMD module system and its internal "asynchronous world" approach, it already could eager or lazy load any component of an application. We were planning to carry this over into NextGen and even make some improvements around app packaging. Angular didn't have this as a capability but was planning to add it in 2.0.
  • Web Components, Behaviors and Directives - Durandal didn't have true custom element support and its binding behaviors were tied to Knockout and required a certain bit of expertise to create correctly. We were planning to create a simpler model of custom elements and behaviors for NextGen. We were also planning to support Web Components. Angular had a very rich Directive capability but it was difficult to learn. They were planning a huge simplification in the way that directives were created and were also desiring to support Web Components.
  • Databinding - Angular's binding system is awesome. Just use plain JavaScript objects and simple binding expressions in your HTML. In their next version they were planning tons of perf improvements as well as possible integration with Object.observe. They also hoped to remove the need to worry about interacting with digest and scope. Durandal relied on Knockout which required you to create special observable properties and apply bindings through a single attribute on each HTML element. It wasn't very pretty or maintainable for large projects either. Durandal was looking to possibly leverage Object.observe and/or dirty tracking for its NextGen version, making it much more like Angular.
  • Modern Browsers - Both Angular and Durandal had pretty solid cross-browser support, including support for older versions of IE. However, we were both looking at a new version that was designed for modern browsers in order to remove unnecessary hacks, take advantage of new, faster APIs and generally re-imagine the JavaScript app development experience around more modern capabilities.
  • Mobile - In Durandal we made some minor optimizations to improve mobile performance, mostly via view caching. We were looking to continue making improvements in this area, mostly around faster templating and binding. Angular recently added nice CSS3 animations and was planning a similar set of improvements to templating and binding. They also had some great ideas for touch gestures and other mobile-specific enhancements.
  • ES6 - Aside from general "modern browser" features, we were also both looking towards ES6 language features and APIs. A lot of this has to do with  modules, loaders and promises. But since we were also taking this opportunity to do major code rewriting, we wanted to look towards the future and leverage new  language capabilities that would make code easier to write and maintain (classes, lambdas and string templates come to mind).
  • Simplicity without Sacrificing Power - Both Angular and Durandal are very powerful...and both have fairly steep learning curves too. Every framework requires some learning, but we both agreed that things could be simpler.
As you can see, both projects had unique strengths and weaknesses. In some cases the strengths and weaknesses compliment one another. But there are other cases where both fall short. Ultimately, both parties came to very similar conclusions about what a "next generation" framework would look like.

By working together we can bring about an even stronger implementation of our shared vision.

New Ideas

In addition to our shared vision, both parties had some new and unique ideas to bring to the table. As for my part, those ideas consisted mostly of things that Durandal was particularly strong in but which were mostly lacking in Angular. The team has been very receptive and we're starting to see the seeds of these ideas make their way into our early development efforts. Here's a few examples of ideas I've contributed which I'm excited about:
  • Dynamic View Composition - Sometimes you have to construct highly componentized screens where the models, views and controllers are all driven entirely by data and can only be known at run-time. We hope that Angular's new templating engine will support this out of the box. But, even if it doesn't, our goal is to build a directive system that is so capable that you can build it yourself without much effort.
  • Convention over Configuration - Wouldn't it be nice if you could teach the underlying framework how your team wants to organize and build apps and then let it do the grunt work for you? I'm working really hard to ensure that key parts of the new API are explicitly designed around this concept and it's been cool to see other members of the team jump on board.
  • Screen Activation - What happens when someone is editing data and, without saving their work, they navigate to another screen, losing their progress? Nobody likes that. Screen activation patterns provide the developer with a clean, encapsulated way of hooking into the navigation process and allowing, canceling or redirecting either when leaving a previous screen or entering a  new one. It's hard for me to think of an app I've built where I haven't needed some form of this. It's so common and it should be easy to do.
Note: We are still in the early stages of development. None of the features or capabilities discussed here are set in stone.

Progress Report

As I mentioned, I've been working on the Angular 2.0 Core Team for almost three months now. Things are trekking along and I'm really happy about the direction we are heading in. We spent the first month doing design work. We had lots of discussions and cross-examined each other's ideas. It was a great opportunity for me to really think hard about what my top priorities were. What could I absolutely not live without? Brad has an excellent post discussing the results of that process.

After a good period of design work, we set out to start writing some code. I had the opportunity to build a small, simplified prototype of the new templating engine and directive API. It served to prove out some of our ideas and was a good way to get an early "feel" for the developer experience. Since then I've been involved with work on the actual templating system, which is still in early development, but is shaping up nicely. I've also done work on the expressions parser and more recently been involved designing and implementing a new router.

Final Thoughts

It's an exciting time in the project where we're beginning to see the first fruits of our labor. I'm glad to be a part of the team and I'm confident the Durandal community is going to be quite pleased with the result. Our community stands to benefit greatly by this convergence. It will result in expansion, stronger support, better tooling, faster releases and a sustained development effort, among other things.

As a reminder, Durandal 2.x is not going away. It will continue to be maintained by myself and a core team of committers. It will remain compatible with current technologies and focused on supporting pre-Evergreen browsers much like Angular 1.x. A new release is coming in the next couple of months where you'll see some new features and many bug fixes and improvements. After that, future work will focus on Angular 2.0 and Durandal's plugins. There will be a direct upgrade path from 2.x to the new Angular 2.0-based version. I've recently blogged some tips for developing Durandal apps today, with an eye to this future upgrade. So, if you are interested in keeping that option open, please have a read through that article and take it to heart.

I hope you'll subscribe to my blog or follow me on twitter or GitHub. I'll have lots more information to share as we move ahead over the coming months.