Thursday, November 20, 2014

Dart one year later : AngularDart one week later

Looking at my commit history I realized that a week has past since I started evaluating angular dart for koparo.com. This is also the day that I decided we won't go forward with angular or polymer for that matter for the foreseeable future.

The good, the bad & the ugly is the subject of this post. If you want to get an insight to why we are backing out read on - we will also probably stick to dart itself.
changeset:   0:394d16883231
user:        Adam Wolk <adam.wolk@koparo.com>
date:        Wed Nov 12 14:59:34 2014 +0100
summary:     Initial commit

Epilogue

History tends to repeat itself. Initially I tried out Dart for Koparo a year ago (+ 1 week). There was no Angular in sight yet so the choice back then was Polymer.


commit 9f45b614423f7be24ffcc878209de6200e09892e
Author: mulander <netprobe@gmail.com>
Date:   Fri Nov 29 20:45:15 2013 +0100
    Case 763 Initial commit
   
    This commit includes the project generated by Dart Editor by
    default for a new polymer based web application in Dart.
   
    Polymer is a Dart library that allows bi-directional communication
    between HTML DOM and Dart code by defining new HTML tags.
Back then everything felt in flux. It was not clear for me what the Dart team wanted the community to use. WebUI was still a first class citizen without the big warning that it's 'deprecated' being presented on it's documentation page.

Polymer itself felt under-documented, buggy & under heavy development. No fault there we knew that the language is extremely young and didn't expect a mature Web ecosystem.

Now, a year later with AngularDart 1.0 out the door we felt it's a good time to re-evaluate our options.

The good

Let's start with Dart first. I love the concept of the language and revisiting the app written a year ago was a great feeling compared to our current javascript stack. It reminds me a lot of smalltalk and that's not a big surprise considering the background of some of the main developers of the language.

The Dart Editor got better. Less crashes all around and mostly just one issue that got reported by us upstream and fixed in 3 days.

We had the bad luck of starting the AngularDart evaluation while the angular.dart.tutorial was still out of date but fortunately it was already updated a few days later allowing us to move forward without hunting for the required changes in the framework.

So what was great?
  • Template binding of course which we also loved in Polymer over an year ago
  • More structure to the application (routes, components, services)
  • A much cleaner language than javascript
  • Greatly reduced dart2js deployment size compared to what was generated in the past
  • No issue with using bootstrap this time thanks to Agnulars userShadowDom=false annotation on components

The bad

We unfortunately started hitting issues early in the development cycle. The tutorial of course was flawless in Dartium but as soon as we started to go down our own path we started to hit issues with the existing documentation and additional ones after deployment to our staging area.

The first problem we hit was described in my previous blog post about fixing pub build on Debian. Since that's mostly a devops issue it didn't deter us from pursuing the setup further. 

Trucking along we saw minor issues with views not being refreshed on the first visit to the page and the documentation felt lacking to say the least. I'm sure most of the problems is us starting with AngularDart without prior AngularJS experience but still this raised some red flags here & there.

The real problems cropped up when I actually tried to deploy and use the code on our staging areas.
Most of you are aware of CORS - our backend is currently written in Ruby on Rails and perfectly capable of serving http/json responses. We deliberately wanted a clean slate approach without integrating the new UI with our Rails pipeline so a decision was made to serve the AngularDart UI from a sub location in nginx. The following lightly reflects our current nginx setup:

server {
      listen 80;
      server_name staging_server;
  location /newui/ {
    autoindex off;
    root /home/webui/newui/build/web;
  }
  root /home/webui/staging_server/public;
  rails_env development;
  passenger_enabled on;
}
The moment our ansible jobs deployed the most recent change in the AngularDart UI issues popped up. Exceptions that were never hit on Dartium or a local pub build + serve cropped up in droves. Parts of the app were simply broken with stack traces that were useless.

The reason for the problems was serving the application from a different URL then the root URL. We did report this problem upstream yesterday but didn't heard back on it as of yet.

We also hit some additional issues. Failed assertions deep down in the Angular stack that we also reported here, not to mention plain warnings even in the updated AngularDart tutorial that were reported here.

Unfortunately the #dart freenode channel was only able to help with obtaining the Dart stack traces for those issues but not resolving them which is an additional concern. The below redacted transcript perfectly illustrates the issue. People are helpful and I do greatly appreciate it but everything seems to be spread a bit too much so you're most likely the first person to encounter a particular problem.
18:26 <REDACTED> mulander: sorry don't know angular enough to answer that. There must be a root configuration someplace.
18:28 <REDACTED> If not you can fake it with the html base tag. Sets the root for relative calls. Its a long shot.
18:29 <REDACTED> Relative urls*
18:31 <REDACTED> mulander: also try and build you project and see if the built version has the same issue. Angulars dependency injection code is different on built code.
18:31 <mulander> the testing I've done was with pub build
18:32 <mulander> and deployed both with nginx and a local small test server in go to confirm that the issue is the suffix url
18:32 <mulander> it's funny because more than half of the code works
18:32 <mulander> ie. the router picks up path changes and redirects to correct views
18:32 <mulander> but some parts just blow up with exceptions that are inllegible since they are dart2js compiled
18:33 <REDACTED> How do the the setup work if you connect wit dartium.
18:34 <REDACTED> You may get better error message at least. If not you have found a rare js only bug.
18:34 <REDACTED> I am not going to lie they are a pain.

The ugly

All of the above brings us to the ugly part. I really wanted to find solutions for the issues we hit. First thing that alarmed me was almost no activity in the main angular dart repo where the last commit was almost a month ago on Halloween.

I started going through the mailing lists and hit some interesting posts - most notatbly this one:

With the release of 1.0, we're entering a new phase of development on AngularDart. For the next few months, instead of new features for AngularDart 1.0, the core team is devoting our attention to a working prototype of our next-gen Angular, Angular 2, with the goal of taking the lessons learned from AngularDart and making them available for both AngularJS and AngularDart going forward. Angular 2 is ultimately where we'll make functional improvements like the one you're requesting in 1307. Our hope is that our approach to the next generation of Angular will give us a way to advance both platforms in greater sync.

What that means for AngularDart in the immediate future is that we will only be actively working on issues that are critical to how AngularDart 1.0 behaves. In this case, I closed your issue because -- although not ideal -- there's a reasonable workaround today, and the kind of change you're requesting has a strong probablility of causing breaking changes for others.

So if you're using AngularDart 1.0, the good news is that you can expect greater stability and few (ideally no) breaking changes. The bad news is that if you are asking for a new feature or something outside the scope of what already exists in 1.0, you'll have to wait a little while until we can consider it part of the Angular 2 effort. 
 That pretty much ruled out AngularDart for us until the development effort settles. During the research we also stumbled on this post regarding paper elementst:

PaperElements are not very stable yet and Dart PaperElements are even less stable.
Currently there are known issues with two-way-binding in PaperElements.dart.
Topped off by the following comment in simple_router.dart from the TodoMV example
// A very simple router for TodoMVC. Real app should use package:route, but it
// does not currently support Shadow DOM.
All in all. This feels like the Dart team is not yet dedicated to what's the promoted way to develop rich web applications with Dart. The Angular team is off working on a prototype for the next best thing while polymer understandably is in big flux as the area is barely explored.

Prologue

Where does this all leave us? Not with Angular or Polymer unfortunately. We still want to stick with Dart as plain javascript - even with frameworks is not something anyone of us wants to dive deep into. Dart showed steady progress & improvements since the last time we tried it. Even if we stumbled upon one or more undocumented parts of the standard library - it's still miles better than what AngularDart offers.

What we all would really love to see is the Dart team clearly stating what is the preferred way to develop web applications with Dart - currently the platform offers too many incomplete choices that I think hurt mostly the newcomers.

We will be watching the Dart landscape closely but for now our focus is to evaluate pure Dart as the way to go forward for us - unless we hit some major issues in the coming week then I don't see a way for Dart itself dropping out of our scope.