In this post, I’ll talk about the technical challenges we’ve encountered as we’ve used Ember for a medium-sized project, as compared to the smaller apps I’d written before.
The target audience is other developers that are interested in moving the Ember.js project forward. The post is mostly intended as a conversation starter. My hope is that through discussion and code, we will be in a better place a few months from now.
Note 1: If you are just trying to decide on a framework for your app, then after our experiences, I can wholeheartedly recommend Ember. I’ll blog about framework choices some other time. In the meantime, check out Peter’s talk.
Note 2: I believe that the problems I describe tend to arise with other frameworks, like Angular or Backbone, as well. (Backbone in particular doesn’t even try to address many of these things.) If you have seen or come up with solutions for other frameworks, please share them!
1. Debugging and Inspectability
This is a surprising issue, so I’ll start with this one.
Ember has great top-down documentation.
However, as my team-mates dove into our Ember app, one complaint was this: The
documentation gives simple, self-contained examples. Dropping from
president.get('fullName') into a fully-featured Ember app is pretty brutal.
It’s very hard to know what’s actually going on.
Unfortunately, Ember doesn’t make it very easy to inspect app state (check out this gist for a demonstration).
I think we need several pieces to solve this puzzle:
Integration with Web Inspector and Firebug: When showing Ember objects, Firebug exposes the type (through
toString), but not the properties. Chrome doesn’t even show the type – just a generic
I’m guessing that we’ll need a “list all properties” function. Ember should already have all the necessary infrastructure for this (
Ember.meta, etc.). Secondly, I wonder if we should link up with the Web Inspector and Firebug folks to see if there’s a way we might be able to get custom UI for inspecting Ember objects.
I wish it was possible to click into the page to see the view hierarchy. I’m not sure how to implement this, but my pie-in-sky dream is something like Firebug’s DOM tree, except for nested Ember views instead of DOM nodes. This might be a couple notches too ambitious, but maybe a “light” version of this will go a long way.
In my smaller Ember apps, I was able to get by with Selenium, but this is too slow for more complex apps.
Ember already brings some helpful things for testing, like the FixtureAdapter in ember-data. Still, the whole setup doesn’t feel very mature to me yet. There is no pre-made testing environment set up for you, like with Rails, so instead every project ends up with their own test setup at the moment.
So where do we go from here? It seems that there are two big issues:
How do we reliably reset an app between tests? I’m suggesting a solution in #1318 (Application#reset), but it seems fraught with issues. I suspect that we may need to come up with a better way. Much of the complexity of this problem comes from global state, like the App.router object.
But if many of the JSON attributes are cooked or computed, you’ll want your
fixtures guaranteed to be in sync with what the server generates. We ended up
defining our fixtures in Ruby, and dumping them out as JSON into a
fixtures.js file, using a generator rake task. This works OK, but it doesn’t
feel very clean.
I think we’re caught between a rock and a hard place here:
I’d love to hear how other people approach this issue.
3. DRY Model Definitions
In smaller projects you can repeat your database columns in the Ember-side model definitions. For our more complex app, we found that this doesn’t scale. We ended up going with code generation for the ember-data model definitions, generating a schema.js file using a rake task.
I really wish there was a nicer way to get DRY model definitions.
The information for the model definitions needs to come from the server, so this cannot be solved in Ember core.
In Rails’s case, the authoritative source might be the serializer classes used
by active_model_serializers. Getting that information into the client is
surprisingly non-trivial: You can’t dump complete model definitions at
precompilation time, along the lines of
App.Blog = <%=
BlogSerializer.ember_definition %>;. This is because the type of each
attribute is stored in the database, and during precompilation, you don’t
generally have a database.
I’m not sure how this will be solved. I do think however that we need a real, DRY solution, not just more generators in ember-rails.
These are my thoughts so far. As I said, this post was intended as a conversation starter. Once we figure out how to approach some of these things, you’ll hopefully see me writing code and not just complaining idly on our blog. ;-)
Leave a comment, open an issue, or find me on the #emberjs channel.