Ember-Light: A Build For Migrating Page-based Apps

Wow! This takes me back! Please check the date this post was authored, as it may no longer be relevant in a modern context.

The Ember source code is organized into several packages. The Assetfile manages a list of files built when you run bundle exec rake dist, each file a collection of packages.

These packages are a bit interdependent, but do not all need to be included to use Ember. For example, you could use the ember-runtime build if only the Ember object environment is desired (as when using Ember in Node.js). The data-deps build has only what you need to use Ember-Data.

If you are migrating from a traditional web application with a request for each page to a single page application with Ember, it can be useful to start building with Ember for only dynamic parts of the page. This isn’t how Ember is meant to be used in the long-run, and it is not where Ember shines. It is a useful way to start using Ember and evolving your application.

A lighter build of Ember can shed about 40K off the minified Ember source, and make you learn some internals of the framework before going whole-hog.

Customizing The Ember Build

First, we’re going to customize a build of Ember for our application. Clone the GitHub repository for Ember and checkout the latest release tag:

> git clone https://github.com/emberjs/ember.js.git
Cloning into 'ember.js'...
remote: Counting objects: 35223, done.
remote: Compressing objects: 100% (13296/13296), done.
remote: Total 35223 (delta 23409), reused 32765 (delta 21238)
Receiving objects: 100% (35223/35223), 8.66 MiB | 1.24 MiB/s, done.
Resolving deltas: 100% (23409/23409), done.
> cd ember.js
> git checkout v1.0.0-rc.5
Note: checking out 'v1.0.0-rc.5'.
HEAD is now at 9f2b6ac... Version bump - 1.0.0-rc.5

Now edit Assetfile. Add a line in the distros hash for a custom light build:

distros = {
  "runtime"           => %w(ember-metal rsvp container ember-runtime),
  "template-compiler" => %w(ember-handlebars-compiler),
  "light"             => %w(ember-metal rsvp container ember-runtime ember-views metamorph handlebars ember-handlebars-compiler ember-handlebars),
  # ^^ The custom build you should add.
  ...

Build the new file with bundle install && bundle exec rake dist. In the dist directory you will find ember.js with a file size of 810K, and ember-light.js with a file size of 632K. .prod.js and .min.js files are also generated. You save about 40K on the .min.js file by creating this custom build.

Using Ember-Light

The ember-light build excludes ember-routing, ember-application, and ember-states. When a view is rendered, the controller, view, and template parts of Ember need to be wired together by hand. An example:

// Despite not using ember-application, you must still create
// an application.
window.Funk = Em.Application.create();

Funk.BandsController = Em.ArrayController.extend();

Funk.BandsView = Em.View.extend({
  // For my experiments with this, I used ember-rails. This template is
  // pre-compiled from `app/assets/javascripts/templates/bands.handlebars`
  //
  // {{#each this}}
  //   <p>{{name}} -- {{funkiness}}</p>
  // {{/each}}
  //
  template: Em.TEMPLATES['bands']
});

// The `ready` callback from `Em.Application` is not called, so manually decide
// when to create controllers and views.
$(function(){
   bandsController = Funk.BandsController.create({ content: [ /* Some bands */ ] });
   bandsView = Funk.BandsView.create({ controller: bandsController });
   bandsView.appendTo('#band-view');
 })

Is this a little crazy? Yes. But if you want to start moving to Ember without migrating everything today, and you are willing and interested to learn Ember’s internals before rewriting your whole app, Ember-Light may be a good option.