Ember Module Unification

By Sam Bleckley on 07 07 2016

That of dividing things again by classes, where the natural joints are, and not trying to break any part after the manner of a bad carver.
-- Plato, Phaedrus

Ember, being in its restless teenage years, has spent some time in Bad Places. One Bad Place looked like this:

| app/
| -- templates/components/my-component.hbs
| -- app/components/components/my-component.js
| tests/
| -- unit/components/my-component-test.js
| -- integration/components/my-component-test.js
| stylesheets/some-styles.css

(It's a fair cop -- you caught me. This is actually going to be about ember-cli, and how to make the most out of it).

Why is this a Bad Place?

A component's controller refers to its template, and vice versa. A component's styles refer to the component's template. The meaning of each depends on the meaning of the others.

A component, being a component, has a defined interface. It should not affect the app outside that interface.

Component styles should be scoped to only apply to the component; styling is part of the component's interface.

To rename a component, to move it, to inspect the relationships, to recognize when a component has no style, no template, or no controller, to put a component in its own addon -- these should be simple things that only take a moment.

Scattering the files for a component across many directories makes these simple tasks far more difficult. It also obscures the shape of your project -- we all know an ember project has templates, components, and styles; a list of components gives an app identity.

A Better Place

Luckily, Ember(-cli) is on its way to a Better Place:

| app/components/my-component/
| -- template.hbs
| -- component.js
| tests
| -- unit/components/my-component-test.js
| -- integration/components/my-component-test.js
| stylesheets/some-styles.css

Template and controller, together! This is better! With the ember-component-css addon, we can take yet another step:

| app/components/my-component/
| -- template.hbs
| -- component.js
| -- style.css
| tests
| -- unit/components/my-component-test.js
| -- integration/components/my-component-test.js

There, now we're beginning to see the joints and seams of the app appear in the structure of the code! The sharp cut of the interface is made visible even in the directory structure. Art!

The Course is Set, and the Wind Favorable

| app/components/my-component/
| -- template.hbs
| -- component.js
| -- style.css
| -- test.js
| tests/integration/my-component-test.js

There's an encouraging proposal to bring the CSS changes into Ember proper, along with co-located tests. Check out this RFC for a rosy vision of the future; and prepare your own projects for the joyful shift.


Image by Windell Oskay