#Emberjs2018 — my safari into the future

Chris Masters
14 min readJun 6, 2018

--

Introduction

I’m a bit late with this but after reading lots of the posts #Emberjs2018 posts I was inspired to write my own—and to also try something slightly different.

Instead of repeating many of the same suggestions already covered in the numerous excellent other posts I’ve read I want to try to see how close I can get to that experience today — using the latest builds and addons already available — to try to piece together what is and isn’t possible.

The goal of this post is to document my experience from the perspective of a fairly typical Ember developer. By that I mean someone who keeps up to date by reading the latest blog post announcing a new stable release and keeping applications pretty much up to date with them.

But for this experiment I’m going to start with a brand new application and work through step by step documenting what it takes to experiment with features which may still be far off landing in an official release.

To guide me I’m going to be using a combination of information gleaned from various sources from official release notes, slack, twitter etc to blog posts like this one. I’ll also try to include all these references.

My explanations are quite verbose as my aim is that doing this it might provide something of interest not just to people already using Ember but is accessible enough for anyone who might have an interest in giving it a try.

Ember is a big project with broad scope and lots to cover so I’m going to start with the file structure and focus on components and templates. After that I plan to tackle some of the other common wishes in future posts.

So with that in mind on with the journey…

New file structure (AKA module unification)

Background

If you haven’t worked with Ember before but have experience of other frameworks that adopt a convention over configuration approach you’ll be familiar with the general concept but might not appreciate the need for this specific change.

If you’d like to deep dive into the motivations then the best place to start would be the original RFC written by Dan Gebhardt. It’s comments are also a great example of the transparency in the decision making and care over the implementation.

As someone who hasn’t been tracking the progress carefully I can also add that I had a certain amount of confusion over the current situation.

Whilst I can appreciate the current file flat structure for applications with a huge number of components from my perspective of much more interest is the change to locating files more logically together, including tests (a structure closer to that formerly referred to as pods).

Progress

As it isn’t really a pressing issue for my day to day development I’ve just casually tracked the progress and made a quick mental note when I read something that seemed relevant.

The only ‘big events’ I can recall offhand were when the RFC was merged (Oct 2016) and then much more recently some discussion around Robert Jackson’s Ember module migrator when I think he was asking for people to test whether their apps would migrate to the new layout without any issues.

Using now

I felt like it made sense to kick off by creating a new application with this layout so my first stop to investigate this was to check the status board on the EmberJS website (which turned out to be a really useful source for tracking the progress of features).

The status was ‘in implementation’ and included some links to resources—one of which being the Github quest issue.

Reading Gavin Joyce’s comment from only 18 days ago gave an update on how to get this working in a project now.

The first thing was to upgrade Ember CLI to the very latest from github.

yarn global upgrade ember-cli@https://github.com/ember-cli/ember-cli.git

Then generate a new project with the module unification flags.

MODULE_UNIFICATION=true EMBER_CLI_MODULE_UNIFICATION=true ember new emberjs-2018 --yarn

This successfully generated a file layout using /src instead of /app.

Poking around the files I noticed that /config/environment.js had a few references to module unification, but besides that and the new app folder naming everything seemed much the same as usual.

Currently it’s necessary to append the module unification flag (also mentioned in Gavin Joyce’s post) to ember serve . So running

EMBER_CLI_MODULE_UNIFICATION=true ember serve

Resulted in a running Ember application using the new module unification layout.

Next was to use the blueprints to generate a component and to see if this followed the new layout.

EMBER_CLI_MODULE_UNIFICATION=true ember generate component tomster-logo

It didn’t initially—it resulted in still generating the files in the /app and /test directories.

Getting the latest Canary version of Ember

From reading this Quest issue, I discovered that as the updated blueprints had only been merged into master a matter of days ago I’d need to get the latest version of canary for them to work.

This in turn led to a short detour discovering how to obtain the very latest version of canary.

Another project by Robert Jackson, ember-source-channel-url, helped me easily get the url for the latest tarball for ember-source .

npm install -g ember-source-channel-url
ember-source-channel-url canary
The URL for the latest tarball from ember-source's canary channel is:
https://s3.amazonaws.com/builds.emberjs.com/canary/shas/6f1b0605f5220530b45a1dd5ec41bb2a01f21e82.tgz

Success

After replacing replacing ember-source in /package.json with this new url and running yarn I was very happy to see that generating a component with the module unification flag created files in the right locations.

Creates files correctly using blueprints

Verdict

It was remarkably painless to get started working with the new file layout on a new project. The only slight pain point was with using the new blueprints, but for that there was a simple fix.

As I’m yet to try using the Ember module migrator on an existing project I can’t really comment on that but will update as soon as I have.

Also to note: from creating an application on another machine a few days later with a more recent Ember CLI it seems like this has already been resolved and works without the need to update ember-source now anyway.

Code

If you want to see the code that matches any of these steps I’ve uploaded it publicly to Github.

This is the commit to the Emberjs-2018 github repo that matches this progress.

Native javascript classes and decorators

Background

For some technical reasons Ember has not yet adopted some of the more modern syntax like classes and decorators by default.

The desire to switch to this more modern class based approach cropped up regularly in #Emberjs2018 blog posts as a desired feature.

From the status board resources section there is an excellent write up by Chris Garrett on ES Classes in Ember.js and why the process is being implemented so carefully.

Progress

Although it’s not yet ready to be the default there is a recently released addon Ember Decorators which already implements the ES Classes RFC. The documentation is clear, using the excellent ember-cli-addon-docs.

Using now

It’s as simple as installing the addon.

ember install ember-decorators

I had to run yarn afterwards to solve a small issue withbabel-eslint dependencies but it worked fine after that.

The next step was to try using the new class syntax and decorators in a component. I began by using a simple computed property with parameters.

Also worth noting that since Ember 3.1 native ES5 getters can be used avoiding most instances of needing to use this.get() .

src/ui/components/tomster-logo/component.js
src/ui/components/tomster-logo/template.hbs
src/ui/routes/application/template.hbs

Success

Component rendering using classes and decorators (& a couple of lines of CSS)

Verdict

This is just a very basic example and is going to get more complex as my journey progresses—but again I was very pleasantly surprised by how painless it was to start working with.

It left me with a couple of small questions which I still need to investigate further, though.

How to enable code hinting with something like atom-ember-snippets?

Why, even though it looks like the blueprints have been merged, doesn’t the generate command use a class? My guess is that perhaps it’s due to using both this and the module unification flag but I need to look into it more.

Code

This is the commit to the Emberjs-2018 github repo that matches this progress.

Angle bracket components

Background

Another long-running wish which cropped up in many of the #Emberjs2018 posts I read was to be able to to write components using angle brackets rather than the existing handlebars curlies.

I think that the RFC demonstrates the concept well

The original angle bracket components RFC focused on capitalizing on the opportunity of switching to the new syntax as an opt-in to the “new-world” components programming model.

Since then, we have switched to a more iterative approach, favoring smaller RFCs focusing on one area of improvment at a time. Collectively, these RFCs have largely accomplished the goals in the original RFC without the angle bracket opt-in.

This has led to a bit of confusion on my part, especially with the creation of Glimmer components, in understanding exactly what was changing, how it was changing and when.

Basically, this first step—of angle bracket invocation—paves the way for Glimmer components, but currently behaves much like curlies under the hood.

Using now

EDIT TO ADD: Thanks to josemarluedke on slack as of this commit a couple of days ago including the polyfill is no longer necessary when using Ember canary. Just update to the latest version and it ‘just works™’.

This commit shows it working without the need for any polyfill.

This feature is on target to be available officially as of the Ember 3.4 release.

In the meantime Robert Jackson and Martin Muñoz have created a polyfill so that it can be used right now (with nearly all of the proposed features from the RFC) and that works all the way back to version ~2.12!

Once again, it was simple as installing the addon.

ember install ember-angle-bracket-invocation-polyfill

Then I could update the application template to the new syntax.

src/ui/routes/application/template.hbs

Success

With that small update to the template (including prepending @ sigil to the parameters) the component rendered perfectly.

But this did leave me asking myself a question—why the need for the @ sigil?

Luckily there was another RFC on named arguments by Godfrey Chan which specifically covers this and I found well worth reading. There was also a clear explanation in the release notes for Ember 3.1. For an even deeper dive there is plenty about this in the Glimmer.js Progress report on component attributes.

Put briefly, it’s a way to disambiguate between named arguments from the caller and local variables. Although they’re not strictly necessary for the current components (due to auto-reflection) they pave the way for Glimmer components (when it will be obligatory) and therefore is a good practice to start adopting.

My next experiment was to try adding id and class attributes directly to the component.

Same component but with id and class

Adding an id alone worked fine, but adding a class resulted in this error.

Assertion Failed: You cannot use class as an attributeBinding, use classNameBindings instead.

This issue has already been raised on the polyfill addon, so I imagine that it will be resolved soon.

In the meantime I used the equivalent component decorators to add a static class name in a similar way to the ‘old’ style.

Using decorators to apply a class

This worked perfectly.

Verdict

I think this is really exciting and going to be an important change.

Remembering the syntax for things like classNameBindings has never really felt that natural to me, especially with their location hidden in the component file.

It brought back memories of a video from Godfrey Chan from a while back which explains what I’m trying to describe in a much more entertaining way.

It doesn’t cover all those kinds of use cases completely yet but it demonstrates to me that components are heading in a great direction.

I also think it will be a big help for people starting out with Ember. Adding attributes to components was one of the learning curves which, while not particularly complicated, I remember considering somewhat unintuitive.

I’ll be keeping an eye on that class issue being resolved and then looking forward to updating my existing apps to this new syntax.

I’m also eager for 3.4 to be released when it will even be possible to use single word component names.

Code

This is the commit to the Emberjs-2018 github repo that matches this progress.

Removing the application template wrapper

Background

This was more of a detail but seeing this clean new markup drove a desire to also get rid of the wrapping div Ember creates by default. For more information on what that means here is the RFC.

Using now

As simple as installing ember-optional-features and then disabling the application-template-wrapper.

ember install @ember/optional-features
ember feature:disable application-template-wrapper

Verdict

Worked perfectly.

I get this might not be a big deal for others but it isn’t just for aesthetics as it makes it easier to deal with some obscure CSS edge cases, such as the height:100% issue.

With easily setting ids also removing the need for any defaultid="emberXXX" attributes the contrast with pre-HTMLBars days when markup was littered with metamorph tags feels stark and very much for the better.

Code

This is the commit to the Emberjs-2018 github repo that matches this progress.

Template-only Glimmer components

Background

Another optional feature from Ember 3.1 that I hadn’t yet got around to using was to be able to create handlebars-only templates without the need for a complimentary javascript file and wrapping element.

Using now

Having already installed the optional features addon it was just a question of enabling it.

ember feature:enable template-only-glimmer-components

Using the generate template with the unification flag didn’t work for me (it created the file in /app) so I just created it by hand following the module unification layout.

src/ui/components/tomster-title/template.hbs

Then used the curly braces approach from the guides to include it in the component. This worked perfectly, so I went a step further and tried using the new angle bracket syntax too.

Also worth noting is that this includes the new@ sigil approach to named arguments in the templates which I think illustrates the advantage of being able to easily disambiguate between local and argument properties.

src/ui/components/tomster-logo/template.hbs

Success

This also worked as expected the resulting markup is impressively clean considering there are two components being displayed.

No extraneous tags or ids necessary

Verdict

In reality I’m not sure how often I would use a template without any javascript but now I’m aware how trivial it has become this view could easily change.

For me, it is more significant that in that it really highlights how well considered the approach to implementing Glimmer into Ember is and see it as another milestone in that direction.

Purely from a tooling perspective I feel like my expectations are not always matched but this is a trivial concern and I’m confident it’s just a matter of time before details like the blueprint generators and code editor support match the progress of the features themselves.

Code

This is the commit to the Emberjs-2018 github repo that matches this progress.

Glimmer components

Background

Drunk off the success I had adopting the latest conventions I thought I’d go for broke and reach for the holy grail. Glimmer.

For an intro into what it is (if you’re not already aware) check out this introductory video by Tom Dale.

Or, if you don’t have time for that then from my (basic) understanding it’s a template rendering engine architected like a VM—which means it’s both extremely fast and lightweight.

But there are also some great benefits purely in terms of code style.

The whole story here will make Ember feel much more modern in a variety of ways, as well as enabling some great performance and programming model wins: Immutable component arguments! Auto-tracked class properties! <AngleBracketComponent> invocation! Clear semantic distinctions between arguments and local context! So many good things. We just need to land it!

#EmberJS2018, Part 1 by Chris Krycho

Using now

Although the real implementation is very much a work in progress it seems like there is already a possible temporary solution by using the Ember Glimmer Component addon.

Though at the time the readme was written it was awaiting a merge of @tracked properties—that has now happened.

Success

EDIT TO ADD: Since posting this a few days ago things have now already changed for the better.

Using CompatComponent does now work with the latest version of canary.

Here’s the commit to the emberjs-2018 repo which reflects that.

At the time of this update there is still an issue with using the Component imported from ember-glimmer-component and this is the issue I raised for this.

Sadly, no.

I installed the addon

yarn add ember-glimmer-component --dev

and started by replacing the current component import

import { CompatComponent as Component } from ‘ember-glimmer-component’;

The result was an error

Uncaught Error: Assertion Failed: ‘component-manager’ is not a recognized type

I tried to use Component instead of CompatComponent as I am using classes but with the same result.

Looking at the stack trace hinted that the problem may lie with the resolver, but I decided not to spend much time investigating further, for now.

Verdict

I think that trying to use Glimmer components right now in an Ember application might just be one bridge too far (or, someone, please prove me wrong!).

The thing is for me that’s fine—I already have plenty to do by starting to adopt all the previous updates in real-world applications and that will prepare for unlocking the benefits of Glimmer further down the line.

Code

I made a separate glimmer branch on the Emberjs-2018 github repo that matches this non-functioning progress.

Conclusion

I hope this has been even remotely as interesting to read as it was to write—I started off unsure of where to even get started but have ended up with a simple javascript app—with the new file layout, using classes, decorators, and using angle bracket syntax.

Atom editor showing new features and layout

To quote William Gibson

The future is already here — it’s just not evenly distributed.

For me personally, looking at the improvement in code readability and file structure simplicity makes me energised to become more involved in helping to make these features a reality.

It’s also given me a greater desire to better understand some of these newer javascript features like classes and decorators.

To anyone else who maybe, like me, are usually wary of getting too far ahead of the ‘safety’ of the stable channel I’d encourage you to give it a shot too.

Credit where it’s due

You may have noticed I’ve mentioned several names throughout this post and that’s intentional on my part.

It blows my mind that so many people with such talent and skill spend their time working on Ember to make it what it is.

There are many others whose names I haven’t included—a big thank you to all of you.

Onwards…

In my next post I’m going to continue where I’ve left off — moving on from components and templates to begin to see what the future is bringing in dealing with topics like data loading, handling asynchrony and server side rendering (with rehydration).

For now, this has already turned out to be a longer post than I’d anticipated (my apologies) but if you made it this far I’d love to hear if you have any thoughts, feedback, suggestions on what I’ve written. Thanks for reading.

More where this came from

This story is published in Noteworthy, where thousands come every day to learn about the people & ideas shaping the products we love.

Follow our publication to see more product & design stories featured by the Journal team.

--

--