|

Introducing the Ember App Kit

A guest post by Matthew Beale, a web developer based in Brooklyn, New York. He is a JavaScript consultant and has contributed to projects such as: Ember.js, Ember-Data, SeedFu, and Facebooker.

In June, core team member Stefan Penner released Ember App Kit (EAK), a build pipeline for Ember.js apps created around a few unique ideas. EAK is not an “official” Ember tool or “finished” project, but it is far and away the best starting point for an ambitious app. Follow along in this post to get started with the EAK, and to better understand how its features can best serve you.

EAK is strongly opinionated, and it’s unique development workflow stems from several interesting facets:

“JavaScript linting” is a moderately technical term for static code analysis that tries to identify and flag bugs or syntax errors in code. As your site builds in EAK, bad syntax will be flagged and errors raised. Linting provides a good first-line of defense against common errors.

Getting a test harness put together for an Ember app can still be a little tricky. EAK is based upon the modules system, which I’ll discuss later, and it is quite well-built. QUnit, with it’s simple and reliable async testing strategy, provides the test runner. Tests can be run with Karma, or right in the browser at http://localhost:8000/tests.

The latter two features, wildcard server-side routing and modules, are less trivial to understand. I’ll walk through how each of them helps you write Ember apps more quickly, and with better architecture.

An Introduction to Using Ember App Kit

Ember App Kit has a fantastic Getting Started document, covering how to enable and use CoffeeScript, SASS/LESS/Stylus/Compass, and even Emblem. Rehashing that guide isn’t necessary here, instead I’m going to demonstrate only the simplest of steps to get rolling with EAK.

EAK is an initial set of files to start your own app, and so is not installable via a package manager. To create a project using EAK, clone the repository and destroy the .git directory included in the clone.

git clone --depth=1 https://github.com/stefanpenner/ember-app-kit.git my_project && 
  rm -rf !$/.git

The file structure of the app is straightforward. I’ll mention a few specific files and paths for an overview:

           app/app.js  Ember app creation and configuration
        app/router.js  Ember app routes
     app/controllers/  Ember app controllers
          app/styles/  Stylesheets
              vendor/  3rd party code, bower-installed files
    public/index.html  HTML to serve up your app
         Gruntfile.js  Build pipeline configuration
       tasks/options/  Build step configurations
 tests/test_helper.js  Test helpers, harness setup
          tests/unit/  Unit tests

Code specific to your project lives in app/. So, nothing too surprising here.

EAK uses Node.js and the Grunt library for much of its functionality, and so has several npm dependencies. So, cd into the my_project directory and install those dependencies.

npm install

To start a server, run tests, or build files for distribution, you will often use the grunt command. You likely want to install it globally:

npm install -g grunt-cli

And now your app is ready to roll; grunt -h will display a list of tasks available. The most important of these is probably server:

grunt server  Run your server in development mode, auto-rebuilding
              when files change.

From here I suggest you review the Getting Started guide for more details about installation and usage. For this article, I’m going to move forward and talk about two of the more interesting features of Ember App Kit:

Catch-all Server Routing

Ember’s default routing uses a “hash” option, based on the hashchange event. When using this API, URLs have a “#” character: http://myapp.com/#/cars.

Many apps unilaterally use the “history” option, which is powered by the history API. This is enabled by setting an option on the router:

App.Router.reopen({
  location: 'history'
});

With the “history” option, URLs appear as normal paths in the location bar. The “cars” route would be served as http://myapp.com/cars.

With most build pipelines or servers, this requires that you handle the “/cars” route explicitly. For instance, in Rails, you must map it to a route.

In EAK, there is a default wildcard route handler. It serves up your index.html file for any request of an HTML document, so long as that path is not already provided for by a file in the public/ directory.

So with EAK, if you navigate to http://localhost:8000/cars/42 and reload the page, your app will still be served up. This removes lots of frustration when developing with the history API.

Modules Part 1: ES6 Modules

The most interesting and defining feature of Ember App Kit is its module system.

EAK uses ES6 modules. Each file is wrapped in a module, so for instance:

// app/controllers/application.js
var ApplicationController = Ember.Controller.extend({
  someProperty: Ember.K
});
export default ApplicationController;

This will become a module when the file is built:

module "appkit/controllers/application" {
  var ApplicationController = Ember.Controller.extend({
    someProperty: Ember.K
  });
  export default ApplicationController;
}

Module names are derived from file paths. Today, ES6 modules are not supported by any browser. To circumvent this, EAK uses the ES6 Module Transpiler to convert ES6 modules into AMD modules. It converts both the import and export statements, so you rarely see or write AMD syntax.

Modules ensure that nothing leaks into a global namespace, like window. They also make it possible to express dependencies between files in JavaScript. In an asset pipeline like the Rails pipeline, you express dependencies in comments. In other pipelines, you may need to edit a file specifying what order files are concatenated in. In EAK, you can use ES6 module syntax:

import Car from 'appkit/models/car';
var IndexRoute = Ember.Route.extend({
  model: function(){
    return Car.find();
  }
});
export default IndexRoute;

Car itself is only imported to this local namespace, not leaked to any global. The dependencies of this JavaScript are expressed in JavaScript, and decided at runtime. The order that files are concatenated in bears no relevance.

Using modules is future-safe (you are already using ES6 syntax), involves less server-side complexity (the server does not know about dependencies), and encourages better code practices.

Modules Part 2: Module-aware Resolver

The explicit import statements used in my previous example could easily become unruly. Because AMD module dependencies are run-time dependencies, EAK can teach Ember how to require them on-demand.

Ember has a container that delegates the responsibility of resolving factories to the aptly named resolver. In easier terminology, there is a resolver which is responsible for finding the classes in your app. If your app is named App, the resolver will find your application route at App.ApplicationRoute.

One of our goals with ES6 modules is to avoid globals. This is why each EAK file uses export default to expose it’s exported class. The application route is not set on the App object, and the default resolver would not find it.

The resolver, however, is just a class than can be replaced with custom behavior. EAK does exactly this with a custom resolver. Instead of looking to App.ApplicationRoute for the application route, and EAK Ember app will load the appkit/routes/application module.

For instance, given that App is configured to use the EAK resolver:

define("appkit/routes/application",
  [],
  function() {
    "use strict";
    var ApplicationRoute = Ember.Route.extend({
      model: function() {
        return ['red', 'yellow', 'blue'];
      }
    })
    return ApplicationRoute;
  });
// Fetch the ApplicationRoute:
App.__container__.resolve('route:application');

Modules are named according to their paths, so overriding a generated route, controller, view, or component is as easy as creating a file.

Writing JavaScript with private namespaces and automatic class-to-file resolution is just like working with a mature server-side language. Namespaces make app development less error-prone and brittle, and encourage you to write re-usable code.

The Future of EAK

I encourage you to try Ember App Kit today, and embrace it for your next project. When the pipeline does not fit your needs, I also encourage you to edit the Gruntfile and task configuration files. EAK is a starting point, and you should not shy from modifying it for a specific need. I’ve heard of module sharing between two projects with a git submodule and modified build process, and I’ve modified the pipeline myself to build two Ember apps in the same repo.

In the future, EAK will likely support per-environment configuration and a better way to include 3rd party assets (today you must edit more than one file). The changed-file watching will get faster and individual files may be rebuilt instead of the entire tree being compiled on each change. Bower may become a harder dependency that it is today. Ember App Kit may become part of the Ember.js Starter Kit.

But if you are a developer who still remembers what coding in a mature language with namespaces is like, Ember App Kit will get you excited to start a new project today.

Be sure to look at the Ember.js resources that you can find in Safari Books Online.

Not a subscriber? Sign up for a free trial.

Safari Books Online has the content you need

Developing an Ember.js Edge will take the reader from a casual interest in Ember.js through to building a complete application. Along the way we’ll cover the current state of client-side web development, the history and evolution of Ember, and the projects and challenges that have informed its design. Then we’ll dig deep into each of Ember’s constituent component libraries, demonstrating how each operates on its own and how they work together harmoniously as a framework.
Instant Ember.js Application Development How-to is a practical guide that provides you with clear step-by-step examples. The in-depth examples take into account the key concepts and give you a solid foundation to expand your knowledge and your skills. That will help you use the power of Ember.JS in your applications.

About the author

matt.beale Matthew Beale is a web developer based in Brooklyn, New York. He is a JavaScript consultant and has contributed to projects such as: Ember.js, Ember-Data, SeedFu, and Facebooker, who can be reached at @mixonic.

About Safari Books Online

Safari Books Online is an online learning library that provides access to thousands of technical, engineering, business, and digital media books and training videos. Get the latest information on topics like Windows 8, Android Development, iOS Development, Cloud Computing, HTML5, and so much more – sometimes even before the book is published or on bookshelves. Learn something new today with a free subscription to Safari Books Online.
|

4 Responses to Introducing the Ember App Kit

  1. Juarez P. A. Filho says:

    Hey Matthew, nice article. I just heard about EAK yesterday in Ember SK Meetup in a presentation of Rose from Zendesk which is using Ember.js a lot. I am really convinced to use EAK, actually I need to migrate my actual project using Yeoman Ember.js generator to use EAK. Do you have any recommendation about it? Besides that I think you can write an article about Ember Data using an API with a different JSON expected by Ember Data like http://www.reddit.com/dev/api
    Thanks a lot for share!

    • Howdy Juarez! I haven’t used Yeoman much myself, so I can’t give you any specific tips. EAK will support the same features as Yeoman, so the transition should go smoothly.

      The Ember-Data 1.0 beta has really thrown many people for a loop- and I’m in the same boat of having had a bunch of my domain specific tossed out. I’m looking forward to an excuse to explore the new APIs though, and a post might be just the ticket.

  2. Rose says:

    Could you perchance briefly go over what you’re referring to by “you have to edit more than one file” when including 3rd party libraries?
    You might start by bower-installing or adding to vendor/, but then what’s the best path for properly integrating it into the app?

    For instance, to include Ember Data, what do you have to import before classes that use it? All I can guess is you need the resolver and perhaps to bring in the App global. docs are kinda skimpy on best practices for this.

    • To add a new asset in EAK, you’ll need to: 1) add the file, 2) add the file to public/index.html, 3) add the file to tests/index.html. This is more steps than any of us working on the pipeline would prefer to have. It’s easy to forget the tests file, or have an inconsistent order by mistake.

      Ember-Data would need to be a script tag after jquery and Ember itself. The loader is only used by your application code, not by Ember or Ember-Data themselves. Today, the libraries still just add themselves to the global scope.