The majority of Ember applications I’ve worked on have been powered by the Ember-Rails gem. Ember-Rails is great but can make your Ember app feel like a second class citizen when it’s just as important as the Rails API that powers it.
Ember CLI solves this issue by separating your Ember application from Rails and providing an environment to develop, build, and test your Ember applications.
From globals to modules
The biggest change when migrating to Ember CLI was moving away from a global
App
namespace to ES6 modules. With Ember-Rails app.coffee
would look like
this:
window.App = Ember.Application.create
rootElement: "#ember_app_container"
Ember CLI uses ES6 modules to import dependencies and export functions and objects:
`import Ember from "ember";`
App = Ember.Application.extend
rootElement: "#ember-app-container"
`export default App;`
Unfortunately CoffeeScript doesn’t support ES6 module syntax yet, so we have to embed JavaScript directly using backticks to import and export modules.
Instead of creating our App
instance directly we export it and Ember CLI will
instantiate it for us. If we were using JavaScript instead of CoffeeScript we
could export it directly instead of having to assign it to a variable:
import Ember from "ember";
export default Ember.Application.extend({
rootElement: "#ember-app-container"
});
Ember CLI also comes with its own custom resolver that takes advantage of ES6
modules, giving us different filename conventions. Underscores are replaced with
dashes, .js.coffee
is replaced with just .coffee
if you’re using
CoffeeScript, and the “_type” suffix is removed entirely, e.g.:
controllers/application_controller.js.coffee
would become
controllers/application.coffee
.
These changes are necessary since ES6 modules use the relative path and filename
to generate the module name. For example, controllers/application.coffee
would
export to a module named your-app-name/controllers/application
.
Testing
Ember CLI ships with a test environment with QUnit as the default testing framework. When we converted from Ember-Rails we were using Mocha and were forced into adopting QUnit.
Fortunately QUnit-BDD allowed us to get away with minor changes to our test
suite such as eq
becoming equal
and having to write our own include
helper.
Now that Mocha is supported in Ember CLI through ember-cli-mocha we can skip QUnit/QUnit BDD entirely.
Deploying
After the migration was completed and the tests were passing we needed to figure out how to deploy it. We ended up going with Heroku and this Ember CLI buildpack that builds and serves our application for us.
We took advantage of Ember CLI’s config/environment.js
file to point
Ember-Data to different endpoints based on the environment the application is
built/running in.
if environment == "staging"
ENV.API_HOST = "https://api-staging.herokuapp.com"
if environment == "production"
ENV.API_HOST = "https://api.herokuapp.com"
We import these values into app/adapters/application.coffee
as config
and
set the adapters host
property.
`import DS from "ember-data";`
`import config from "../config/environment";`
ApplicationAdapter = DS.ActiveModelAdapter.extend
host: config.API_HOST
`export default ApplicationAdapter`
Now every time we use the adapter the host is set for us based on the environment.
Wrapping up
Ember CLI is still young and has a few bumps to smooth out but also has some advantages over other options with fast incremental builds, live reload support, and the ability to extend Ember and Ember-CLI through addons.
Best of all, Ember CLI allows us to separate our front-end from our API and makes Ember feel like a first class citizen instead of an afterthought.