Migrating a CoffeeScript Ember Application to Ember CLI
The Ember community has spoken and standardized on a set of tools to write and build ambitious web applications. This is great, but what about us early(ish) adopters who didn’t choose what the community has standardized on?
We chose to rewrite our Rails marketing app as an Ember app in March of 2014. Back then, there weren’t obvious choices for how to write, build and deploy Ember applications. Ibotta.com has been in production for almost a year and uses a build, test and deployment system that highly varies from the choices made by the Ember community.
It seemed clear that the Ember Community was moving toward a standardized build and deployment system, but it wasn’t abundantly clear that Ember-CLI, ES6 Modules and ES6/2015 syntax would be so heavily adopted by the community.
Because this wasn’t obvious, we made some decisions that go against the grain of the 2014/2015 Ember Community. Specifically, we bet on the following:
Some of these things will continue to work, and others are falling to the way-side.
At EmberConf 2015, we finally realized that we need to move off of our custom architecture and follow the standards being set by the Ember community. No one likes to argue for a multi-week engineering-only transition but, in this case, it was necessary.
So, starting this week, we at Ibotta are going all-in on a migration to Ember-CLI. Here’s how we’re doing it.
Initializing Ember CLI
The most obvious thing we need to do is to get off of Brunch and onto Ember CLI as our build system. For the most part this isn’t a difficult move and we actually get a lot of things “out-of-the-box” that we had to implement custom solutions for.
We really wanted to retain our git history since over a year of development went into our previous application. Since git is pretty smart at recognizing renames, we used the following strategy to retain as much history as possible.
To get started, we began like a new app by running
ember new in a new directory.
Specifically, we ran
ember new --skip-git to retain our previous private GitHub
repository. Next, we moved our previous repo into a folder called
the newly generated Ember CLI app folder. We moved
old-app/.git into the new
directory to retain file history.
Commit! You’re on your way. Run
ember s to see a lovely Hello World.
As you migrate your existing application files over, make sure to move to the new file and delete the old one. Git will realize that the file is essentially the same and retain history from when you first wrote it.
In our case, we had a few dependencies we couldn’t move away from right away. Our next step was to take care of this infrastructure to start migrating our app.
As was extremely evident at EmberConf, CoffeeScript is not the way forward for the Ember Community. Though it provides a lot of syntactic sugar, the Ember community greatly prefers using ES6 syntax and the Babel transpiler to CoffeeScript. Though I still think that Coffee has some merits (exitensial operator, no need for semicolons, inline hash definitions), we realize that this is not the way forward. However, we can’t scrap and rewrite a year of development work, so we need to get CoffeeScript running with Ember CLI.
Luckily, we aren’t alone. The ember-cli-coffeescript project is pretty active, and supports most things we need to get up and running. It allows us to write application code and tests in CoffeeScript to migrate our app.
Get started by setting up the plugin as
described in the README.
You can test it out by changing your
router.js file to a
and fixing the syntax to see that it’s truly working.
You’ll need to hack your existing files a bit to get it working with
but it’s pretty formulaic. Let’s start with your Router, because you almost
undoubtedly have one.
In CoffeeScript you’d have something like this:
and with Ember CLI CoffeeScript, you’ll translate to something like this:
The biggest change here is the ES6-style module import/export. You need to explicitly
import Ember (and your environment) and export the
Router when you’re done.
ember generate to help with the transition. It will deal with the backtick
imports and exports for you, making your copy/paste task a bit easier.
Sass was a bit easier. The Ember community still likes Sass and they’re working on a first-class Node port, so it’ll be around for a bit.
Just install the ember-cli-sass add-on, follow the README and migrate your styles. Now you’re rockin’ sass. Easy.
We have a bunch of CoffeeScript Mocha tests around, and we want to retain these tests as we port our app over.
Getting Mocha Tests Running
Get it installed and try writing a quick test - does your Index Hello World app run?
For this task, we ended up forking a repository of ember-cli-mocha-coffeescript. We decided to do this because it provides handy generators for Ember Mocha tests and allows us to port most of our tests over verbatim (inside the blueprint structure).
Get it installed and try generating a new CoffeeScript flavored test by running
ember generate <test>
The Rest of the Plan
So this is where we’re at today. Not bad for only a few hours in, right? We have started to migrate over our application piece-by-piece, migrating application code and tests over as we see fit. In all reality, it’s grabbing a (seemingly) independent piece of code and migrating it, it’s dependencies and tests over to CLI.
It was really helpful to get our tests running with Jenkins CI as part of this process to make sure we were on the right track.
I’m going to continue posting with specifics on the rest of our migration process, but here’s the general plan for those of your who are interested.
OK, it has got to go. The maintainers realize that Ember CLI is the way forward for the community and they’re not going to support it anymore. Here’s the plan to get away from it.
Broccoli + Ember CLI does most everything we need. There’s not much we neeed to change here to get up-and-running.
This is where things get interesting. Our previous app constructed the
file in the ExpressJS server at request-time. We’ll need to modify this slightly
to be CLI-compatible.
As announced at EmberConf 2015, the best Ember-CLI add-ons for deployment are merging into the new ember-cli-deploy project and (in my opinion), will be the de-facto way to deploy your Ember application.
Make sure to watch the talk from Ember.JS Munich to get the general gist of how ember-deploy works. This will get us most of the way there, but we’ll need to modify it slightly to work for us.
At request-time, we need to embed some session-specific information, like an
app token and the request’s IP location, so we’re going to need to modify from
directly serving the
index.html file generated by
ember build --environment=production.
My plan is to implement a plugin as I describe on
this GitHub issue I
opened to easily support building the
index.html file at request-time on our
ExpressJS app server. I hope for ember-cli-deploy 0.5.0 to be finalized before
I start to tackle that problem.
Overall, this has been a really fun project. After EmberConf it feels really good to be moving toward the standard way of building an ambitious EmberJS webapp. Stay tuned for more posts on migrating to the new Ember CLI infrastructure!