Aurelia - could it be solid gold?

Kudos to those who caught the reference in the title - pun definitely intended. They say puns are the lowest form of wit, or something like that, but it's 11:30pm and it's all I got =)

Oh God - not another bloody framework I hear you say, and I can sympathize with that. If I hadn't been working with Durandal these past few years it may have been pretty daunting as well. But the truth is, this framework is not new, it's just the good parts of almost a decade's worth of work in other frameworks all neatly pulled together in a package called Aurelia. Lots of Durandal made it in here (so it will be familiar if you've used it), a splash of Angular from what I can see, a hint of Knockout and some foundation bits from Caliburn Micro if you can believe that :)

So without further ado - let's get cracking...

Getting started

OK, so you're an early adopter and looking to break the ice, but you also don't have a wheelbarrow full of time to throw at it. The absolute worst thing an OSS project can do when asking for early feedback is to make the "Getting Started" story a bitch to get right.

Well I can definitely say that the team did a sterling job in making sure you fall into the pit of success in this area. Whether you're working on Mac or Windows, the nodejs runtime and npm are very much a prevailing standard when it comes to setting up development environments and I think the team have backed the right horse here. Not to mention their use of jspm - if you haven't checked it out, seriously, stop reading this, and go do that, it's incredible!

Combining their excellent getting started tutorial and the skeleton app as a sample, you can't help but be up and running in less than 15 minutes - and most of that will be time spent reading all the interesting tid bits they've thrown in there. They'll take you from configuring your environment and setting up your project through to building out a mini-site with navigation all hooked up. The bonus material was a nice touch and not too overwhelming.

So from that perspective, I'd call it a solid touchdown. If you need to dig any deeper, then you're officially no longer "getting started" and you can expect some learning ahead.

Documentation

It's early days, so you kind of expect that the developers (if anything like me) are far more excited about cranking out the next feature than documenting the one they just shipped. Once again, not so on the Aurelia team. They have surpassed my expectations in this area as well. The docs are light on the ground, but they are razor focused - they get to the meat of what 95% of us want to try when taking the new framework for a spin.

I'm sure we'll all get to the fancy stuff in the coming weeks and months, but then given how good the docs are now, I think we'll also see those grow accordingly. It really has been professionally put together, surprisingly so for a preview - I guess it must mean they're serious about getting this out the door ... with jets on!

Given that the docs will appeal to the vast majority of devs and the 5% who can't find what they need are probably the same 5% smart enough to build something like this themselves, and so I'd call the early days of the docs a surprising slam dunk.

And if you are in that 5%, then you also probably already know about incredibly active Gitter Channel where you can ask, and you shall receive. I tried it. It worked!

Environments

I'll just come out and say it. Visual Studio is a total fail for ES6, but I can hardly hold that against Aurelia can I? Go vote for ES6 support in Visual Studio if you care enough about it. So I did what any sane developer would do and fired it up in 3 more environments. Happy to let you know that Sublime, WebStorm and Atom are all doing fine with their respective plugins - give me a shout if you can't find one that works for you.

So assuming you're using the gulp watch task (and you should be), you'll notice that it uses 6to5 to spit out ES5 to your dist folder on the fly while you code away in the src folder. Of course you're not stuck using the default folder structure, you're free to structure any way you like, I'm just talking defaults here.

It's actually an incredible teaching tool you have in your hands right here. I write (and am learning) ES6 as I go, and I can take an instant look at the ES5 it transpiles to. I can teach other team developers and run show-and-tell sessions on the benefits of learning the more expressive and cleaner code - not to mention learning a ton about what I didn't know JavaScript could already do.

I never thought about it until I was messing with it, but this is great for internal company training, preparing developers for the next jump in front end coding. I have tangible ES6 code, that transpiles to ES5, and I'm building views and interaction that works in a browser as a live demo. Whole talks could be made this way!

The key takeaway from this for me is that although there's a small amount of learning taking place that's related to Aurelia and the conventions it uses, 90% of the learning was all about ES6 and that my friends is 100% transferable to any future framework. You are not learning Aurelia - you are learning EcmaScript, and therein lies a big differentiator for me when compared to many other frameworks. I had so much fun doing this I almost didn't want to put it down to come write this article, so I'd call that smashing a home run!

OK OK, you're tired of my sports references, I can tell - no more I promise =) I will leave you with this though:

A couple of handy tips

If, like me, you want to use push state instead of hashes in the URL when navigating, then you'll want to take these extra couple of steps. The example code below is taken from the getting started tutorial and skeleton app, so if you're following the guide, you just need to add in those bits I've indicated.

First you need to tell Aurelia in the router config that you want to use pushState like so:

this.router.configure(config => {
      config.title = 'First Impressions';
      config.options.pushState = true; // this is the daddy!
      config.map([
        { route: ['','welcome'],  moduleId: 'welcome',      nav: true, title:'Welcome' },
        { route: 'child-router',  moduleId: 'child-router', nav: true, title:'Child Router' }
      ]);
    });

Next, you'll recall that for a Single Page App, the server side needs to send back the same index.html file regardless of the request being made because all the routing is done client side. So, if you're using the gulp watch task with browsersync (and you should be during development) running a node server, then you can modify your setup like so:

From the console in the root of your project, run the following: npm install --save connect-history-api-fallback which will bring down the middleware plugin you need for this.

Then open up your gulpfile.js in the root and put this somewhere near the top with the others:

var historyApiFallback = require('connect-history-api-fallback')

And lower down you can modify the serve task to use the new middleware:

gulp.task('serve', ['build'], function(done) {
  browserSync({
    open: false,
    port: 9000,
    server: {
      baseDir: ['.'],
      middleware: [historyApiFallback, function (req, res, next) { // spot that bad boy in there!
        res.setHeader('Access-Control-Allow-Origin', '*');
        next();
      }]
    }
  }, done);
});

Now your node server should behave itself and let Aurelia deal with the routing.

If you're using an awesome .NET server side framework like ~~ASP.NET MVC~~ Nancy FX, then the config is just as simple. Locate your IndexModule.cs or whatever you called it and make sure it looks something like this and all will be well:

public class IndexModule : NancyModule
{
    public IndexModule()
    {
        this.Get["/robots.txt"] = p => this.Response.AsFile("robots.txt");
        this.Get["/sitemap.xml"] = p => this.Response.AsFile("sitemap.xml");
        this.Get["/"] = x => this.View["index"];
        this.Get["/{path*}"] = x => this.View["index"];
    }
}

And so on for your particular server environment - you just need to make sure that whatever server you're using, it needs to send back the same index.html regardless of the request being made. Aurelia will figure out which page to load based on it's own incredibly powerful router.

Conclusion

I have literally just scratched the surface, but I wanted to give my first impressions before digging any deeper or just regurgitating the docs (badly) with examples of custom elements etc. You can check those out yourself - but one thing I will be doing is migrating some of the Angular and Durandal apps over to Aurelia in the coming months, and I'll describe the experience in detail.

It's likely that's when I'll start hitting blockers if at any point, but who knows, maybe it'll be plain sailing and a smooth migration path will unfold. If not, then I'll try and document the obstacles faced and how we surmounted them - but surmount them we will - of that I have no doubt!

Until next time
RobertTheGrey



5 comments

Robert Greyling
2/4/2015 1:42:27 PM
Hopefully the folks viewing on mobile devices now hav a better experience with the article on its own page. Would be grateful for any feedback!

Paul Wheeler
2/4/2015 2:06:20 PM
Great guide!

Adam Morgan
2/4/2015 4:14:29 PM
Thanks for sharing your thoughts. I've been considering Aurelia as a weekend project.

Robert Greyling
2/4/2015 4:21:24 PM
No problem Adam, thanks! I'd say it's well worth a rainy day's worth of coding :)

cmichaelgraham
2/4/2015 7:02:06 PM
Great article :)