EmberJS 2019 Roadmap

It's that exciting time of the year again! The Ember community has been asked to write about their vision for the 2019 roadmap, and this is my response to that request. It's almost the deadline now, but so far I have seen so many fantastic blog posts that I feel we are in good hands for the next roadmap. However, I still wanted to express my ideas and where I see the priorities should be.

Ember Octane is about to bring so many significant improvements to Ember apps, to the programming model, and some long waited for enhancements. A few of the most existing features for me are Glimmer Components, Tracked properties, and Modifiers. We have been using Ember Octane in production for a couple of months in a small app, and it has been working great. We even have FastBoot Ryhadration enabled, which is one area that is not widely used, not even in Classic Ember apps.

Controllers / Query Params

As many others have already written, I firmly believe controllers must disappear as a programming concept from Ember. They must die. I even wrote about controllers in my last year's roadmap post, and I wish we had removed them for Octane. It is the weirdest thing in Octane right now.

For us to kill controllers, we must find a new home for Query Params and the recent updated RFC, gives some excellent ideas. I believe the query params definition should be part of the router definition (Router.map), and access to them should be thru the router service.

Template Imports

Template imports should be a high priority for the next Ember edition.
It will allow us to get templates to the next level. Imagine you don't need to worry about polluting the global namespaces with specific components and small helpers. You can know exactly where a component, modifier, or a helper is coming from. It will be super powerful for beginners in a project, but also great for tooling.

Routes

We need to rethink how routes in Ember work. Removing controllers and reworking Query Params means that we are going to have a clean slate for rethinking where routes should go.

Rethinking routes should be a high priority because of template imports. I believe that without reworking how routes and its template work together, template imports will be an afterthought for them.

I have two ideas for routes:

  1. Remove its template and render a component from the route JS file.
  2. Make routes just a map to components.

The community has been discussing option 1 in the last few days, while I think this could be a good alternative, let's also consider other approaches.

With option 2, it would mean that in Router.map instead of just defining the URL paths and hierarchy, we would also determine the component. Also, we would move the data fetching from model hook to components. This approach is very similar to the Vue Router.

Here is an example:

//...
import Index from 'my-app/components/Index';  
import Posts from 'my-app/components/Posts';  
import PostShow from 'my-app/components/Posts/Show';  
import Login from 'my-app/components/Login';

// ...

Router.map(function() {  
  this.route('index', { component: Index });
  this.route('posts', { component: Posts }, function() {
    this.route('show', { component: PostShow, path: ':id' });
  });
  this.route('login', { component: Login });
});

export default Router;  

Typed Templates

With templates imports, we have an opportunity to take templating into the next level, and typed templates would be a massive step in that direction. For TypeScript users, we could get type checking for object access and things like that.

Typed Arguments

I would like to have type checking for the arguments that we pass to components, helpers, and modifiers. I don't have all the answers here, but we would probably need a way to, explicitly state what the arguments for these are. It would be nice to achieve that without requiring apps to use TypeScript, but they should work nicely together. Template-only components would also need a way to state what are the arguments.

Prettier for Templates

Every time I onboard someone into Ember templates, one of the first things they ask is: "Can I use prettier to fix formatting and linting issues of these handlebars files?" Unfortunately, I need to say: "No, you cannot." Let's fix that.

Splatarguments

Splatarguments is one more thing that I would like to see for templates in the next Ember edition. Let's create a similar feature from ...attributes, but for arguments.

I want to forward all arguments from a component to another, something like this: <MyComponent ...arguments />. Bonus if we can splat any object into components as arguments or even attributes.

One area we need attention on is the syntax for the Splatarguments. If Ember would ever allow splatting an object to an element as attributes, then we would have ambiguity. Another possible syntax for Splatarguments is using curries. For example:

  • <MyComponent {{...this.args}} />
  • <MyComponent {{...this.myCustomArguments}} />

Of course, this does create incompatibility with Classic components and Glimmer components arguments. Also, it does look like a modifier.

Server Side Rendering & Rehydration

Ember needs to get a little more serious about Server Side Rendering. In particular, Ember needs to finish and enable rehydration by default.

Dependency Injection

I think it's time for Ember to have a look at the DI system again. Maybe entirely remove it or maybe rework it a bit. With template imports, the DI system will be one of the "magic" parts of Ember that will stay intact. I believe it would feel more aligned with the rest of Ember if services would be imported instead of relying on the container lookup using a string.

File System Layout

I was super excited for Module Unification to land, but we are not getting that for now. We use pods in our apps because it allows us to co-locate component JS and template, routes, and controllers. We also use css-modules to author our styles, and the co-location is essential for us to organize our files. The same applies to GraphQL files for queries.

I'm happy Ember is taking a step in the right direction with the Component Templates Co-location RFC, but I would like Ember to do the same for routes and controllers.

Single File Components

Ember has an RFC open for a few months on this topic, but no actual movement on it as far as I can tell.
SFC will, with template imports, make authoring components a joy. I would love to see SFC been part of the next Ember edition as an official concept.

Build System + Embroider

Many others have talked about Embroider and how it's such an essential piece for Ember in 2019. I completely agree with them. If I would have to choose from the features that I described above - minus controllers & query params - I would focus on getting Embroider to the finish line. After that, start working on the other pieces. However, I believe these features must be implemented in parallel by different teams; most of them shouldn't be one or the other.

Things that I would like to see in tooling/embroider space are:

  • Get Ember in actual packages, remove shims.
  • Lazy routes. There is some initial work on this in Embroider already.
  • Components should work with import(). (Maybe something like React Suspense, but keep SSR support.)
  • Code Splitting.
  • Remove deprecated code, so new apps don't need to pay for it. Aka Svelte builds.
  • Targeted Builds. (check Robert Jackson's post for more info).

While I'm in the tooling topic, I would like to see a proper Ember Language Server implementation. That will become even more valuable with template imports. And please don't forget to architect it in such a way that Vim users can take advantage of it (check coc.nvim).

Whishes from last year

There are a few things that I still want to see in Ember that I had written in my last year's roadmap.

Ember Data not being part of the default ember new.

I think we should remove Ember Data from the default blueprint and remove it from the tutorial.

Errors and stack traces

Sometimes it is very difficult to debug errors in Ember because we don't get a useful stack trace. Errors that get thrown within the run loop or internally in Ember don't get a useful stack trace. Usually, the stack trace given is just a bunch of Backburner and Ember.onerror references. I would love to see this fixed.

Also, errors and test failures from QUnit should contain the location of the test file (in disk). It is very disappointing to see the error message leading to the vendor file without much information where the test is located.

Website Redesign

About six months ago, the RFC for the website redesign was posted, and no real progress on it has been made. This project is super essential for Ember to attract more folks, and we do need to show how awesome Ember is. I have seen a few PRs in ember-styleguide, but nothing too significant. Why not create a strike team to get this done? I would be happy to help out if there is a clear consensus on how to approach it.

TL;DR

Ember is in the right direction on many fronts, and I'm excited about all the template work that the community is talking about. All the work that will go into templates will make them more statically analyzable and improve the overall experience with them. However, Ember also needs to take action on the rough parts. Ember needs to work on tooling and get Embroider to the finish line. To summarize: Kill controllers; Rework Query Params; Reimagine Routes; Get Template imports; Get Typed Templates & Arguments; Get Prettier for Templates; Get Splatarguments; File System Layout needs to keep evolving; Get Single File Components; Rethink Dependency Injection.