Menu Search
Jump to the content X X
Smashing Conf San Francisco

We use ad-blockers as well, you know. We gotta keep those servers running though. Did you know that we publish useful books and run friendly conferences — crafted for pros like yourself? E.g. upcoming SmashingConf San Francisco, dedicated to smart front-end techniques and design patterns.

Write Your Next Web App With Ember CLI

When you start a fresh web project or start digging into an existing code base, chances are you’re trying to create or enhance a feature for your users. The last thing you want to do is spend time customizing build tools and creating infrastructure to develop your application. If you land a new client, you want to show them features today, not in a week after you’ve cobbled together a build pipeline.

As you might already know, Ember1 is an “opinionated” JavaScript web framework focused on building ambitious, rich client web applications. Technologically, Ember has positioned itself as the antidote to hype fatigue2. It’s a framework that just won’t die3, but keeps pressing on with each innovation4 and with a commitment to backwards-compatibility.

Ember CLI375 is the Ember community’s shared solution for front-end tooling. It provides a productive and feature-rich development experience out of the box.

The Challenge Of Trivial Choices Link

On the face of it, front-end build tools appear too diverse for a shared solution. There are too many factors to account for, and every project has its own specials needs. As stated on React’s documentation page for “Tooling Integration6,” “Every project uses a different system for building and deploying JavaScript.”

Are you using Rails or .NET? What CSS preprocessor are you using? Does your application consist of a single page or “islands of richness”? Are you using JavaScript globals, asynchronous module definition (AMD), universal module definition (UMD), CommonJS or ECMAScript 6 modules? What testing framework do you prefer?

Because developers’ needs vary so much, low-level build tools such as Gulp, Grunt and Broccoli are often the starting point for front-end development. Yeoman, Lineman and Brunch take us further by generating the boilerplate needed for various use cases.

So, how is Ember CLI different? By making Ember CLI the official build tool for Ember, the community gets a default suite of tools that are integrated by 225 Ember CLI contributors and battle-tested around the clock by the Ember user community. These tools provide useful conventions, clear paths to best practices, and escape from the burden of trivial choices7. As Chris Eppstein tweeted8, referring to the Sass language, “It’s our belief that this consistency promotes a vibrant ecosystem and that it’s a bigger benefit than the ‘just right for me’ approach.”

Some developers might find it difficult to give up choice in favor of productivity. I argue that we must become experts in the domain in which we work and, for most developers, that domain is the intersection of the client’s business and maintainable application development. Frankly, I’ve never heard of a development team that created build tools they were happy with. However, I have seen custom build tools be disastrous for projects. You should try Ember CLI before attempting to build your own.

New Opportunities Link

Ember CLI isn’t just about building assets better than before. When a community coalesces around a technology, new opportunities for productivity emerge. Here are a few innovations that have become possible with Ember CLI.

  • Ember Addons9
    These are libraries that can be installed in an Ember CLI application and that “just work” with zero configuration.
  • Ember CLI Deploy10
    This is for conventional front-end deployment.
  • Ember FastBoot11
    Render Ember applications on the server for faster initial page load.

Another side effect of Ember CLI is that developers receive the latest and greatest technology, without even needing to know it exists. Out of the box, Ember CLI applications have ECMAScript transpilation with Babel, live reloading during development, and a simple way to proxy AJAX requests to a local or remote server.

Let’s Create An Ember App Link

Before creating an Ember CLI app, you’ll need to install Node.js. You can find out how to install it on the Node.js website12, or you can use the popular Homebrew13 project if your computer runs Mac OS X:

brew install node

Next, install Ember CLI itself:

npm install -g ember-cli

With the prerequisites out of the way, you’re ready to create your first Ember application:

ember new my-app

Once that’s finished, move to your app’s directory (cd my-app), run your app with ember serve, and visit localhost:4200 to see your application in action.

A freshly minted Ember CLI app14
A freshly minted Ember CLI app. (View large version15)

Using Ember CLI Link

Using the blueprints feature of Ember CLI, let’s add some meat to our app and show a list of posts when a user visits the /posts URL. You can also follow along in the accompanying GitHub repository16.

ember g resource posts title:string body:string

This tells Ember CLI to generate a posts resource — it creates a route entry in your router, a route, a posts template and a post model. The post model will have title and body attributes that are cast to strings.

We’ll need to loop through our posts and render them in our posts template. The each helper makes this possible in app/templates/posts.hbs.

{{#each model as |post|}}
  <h3>{{post.title}}</h3>
  <hr>
  {{post.body}}
{{/each}}

Next, we’ll want to find our posts’ data and hand it off to the template when the user visits /posts. We’ll fetch the posts in the model hook of our posts route, located at app/routes/posts.js.

export default Ember.Route.extend({
  // Add this method
  model() {
    return this.store.findAll('post');
  }
});

You might notice that we’ve used ECMAScript 6’s shorthand syntax for objects to define the model method. Because Ember CLI uses a JavaScript transpiler by default, expect to see modern JavaScript code in most Ember applications.

We could have just written some JavaScript objects for the post data in our route here and called it a day, but let’s go a little further and actually fetch posts from a server.

We’ll generate an Express17 web server to serve up some data to our application.

ember g http-mock posts

Then, we’ll return some dummy data from /api/posts. Edit the generated server/mocks/posts.js file to return some data from the index route.

postsRouter.get('/', function(req, res) {
  res.send({
    'posts': [
      // Add these objects
      { id: 1, title: 'First Post', body: 'Blogging' },
      { id: 2, title: 'Second Post', body: 'Blogging again' }
    ]
  });
});

The last thing we’ll need is a customized Ember Data18 adapter.

ember g adapter application

To make sure Ember Data knows to find the posts at /api/posts, we’ll add a namespace to our adapter in app/adapters/application.js.

export default DS.RESTAdapter.extend({
  namespace: 'api' // Add this
});

Now, if you visit localhost:4200/posts, you will see the posts in all their glory.

Your client-rendered list of posts19
Your client-rendered list of posts. (View large version20)

Of course, you’ll probably want to hook up your application to a real web server at some point in the development process. When you’re ready, you can remove the mock server and run your app with the proxy option:

ember s --proxy http://localhost:3000

In this command, replace http://localhost:3000 with your local or remote web server.

This is a great way to build your front end immediately and transition to a production web server later.

Using Ember Addons Link

If you’re familiar with using Bower21 and npm22 to install dependencies, then Ember Addons might impress you.

Let’s install and use a date-picker in our Ember app. My date-picker of choice is Pikaday23. Luckily, several people have already integrated this library with Ember CLI. Here, we’ll use the ember-pikaday addon.

ember install ember-pikaday

Now, let’s create a file at app/templates/index.hbs and try it out.

{{pikaday-input value=date format='MM/DD/YYYY'}}
<p>You picked: {{date}}</p>
A Pikaday date-picker rendered as an Ember component24
A Pikaday date-picker rendered as an Ember component. (View large version25)

This addon installed Pikaday and Moment.js26, it provided an Ember component named {{pikaday-input}}, and it included the Pikaday CSS in our build — all with a single installation command.

Testing Link

Integrating your application code, a testing framework and a test runner can be challenging. You’ll want to run unit tests against isolated parts of the code and integrated tests against the running application. You’ll also want to run tests from the command line for continuous-integration testing on a build server.

Let’s write a test for the posts page that we made earlier. We’ll start by generating an acceptance test called “posts.”

ember g acceptance-test posts

Now, you can visit http://localhost:4200/tests to see the running test.

16 passing tests already27
Sixteen passed tests already. (View large version28)

We already have 16 tests? That’s right. Our generators from earlier each created a test to help us get started, and each of our files was tested with JSHint for errors.

Let’s fill out the generated acceptance test with something that tells us that all of our posts are rendered.

test('visiting /posts', function(assert) {
  visit('/posts');

  andThen(function() {
    var titles = find('h3').toArray().map((el) => el.textContent);
    assert.deepEqual(titles, ['First Post', 'Second Post'], "Has both titles");
  });
});

This test starts up our Ember app in an isolated portion of the test runner, visits the posts path and then asserts that each post title is on the page. The andThen helper waits for asynchronous processing to stop before making assertions.

If you’re not an avid tester, you might find yourself running out of excuses with Ember CLI. If you do get excited by testing, you’ll find it easy than ever to get started. The blueprints put current best practices at your fingertips, so that you don’t have to spend time Googling “how to test [x] in Ember.”

Going To Production Link

Before shipping the code to production, you’ll want to optimize for speed, minify the code, fingerprint your assets and link those fingerprinted assets in the index.html file.

You can accomplish all of that with a single command, which puts your production-ready files into the /dist directory.

ember build --environment="production"

Once your assets are built for production, the next step is to deploy them to a remote server. Many Ember CLI users choose to integrate these build files with the same deployment process they use for back-end server code. However, an emerging best practice, refined and championed by Luke Melia29, is to use a separate front-end deployment workflow that allows your Ember application to be deployed independently of your server code.

At EmberConf 2015, Luke announced30 that the maintainers of prominent addons for deployment had joined forces to create one addon under the name Ember CLI Deploy. The newly formed team released its first joint effort, version 0.5.0 of the addon.

Ember CLI Deploy embraces a “core and plugins” architecture. The add-on provides the deployment workflow, but users install different plugins according to the exact infrastructure they use. For instance, one setup proposed by Luke uses Amazon’s S3 service to host files and Redis to store and link the Ember application’s index.html file.

You can install the current addon using the same installation command we saw before:

ember install ember-cli-deploy

We’ll also install ember-cli-build to build our application for production.

ember install ember-cli-build

From there, you can install the asset-adapter plugin that you need:

ember install ember-cli-deploy-s3

Then, you’ll need to install an index-adapter plugin, which provides a way to link your index.html file to the server:

ember install ember-cli-deploy-redis

Finally, you can edit your config/deploy.js file to include information about Redis and S3, so that Ember CLI Deploy can interact with these services.

With those adapters installed and configured, you can deploy with one command.

ember deploy production --activate

This command will:

  • build your assets for production,
  • upload your JavaScript and CSS assets to S3,
  • upload your index.html file to Redis,
  • “activate” the last index.html file that was uploaded.

In this sequence of events, only the last step, activation, changes the version of the Ember application that is served to users. Previous versions of index.html are stored on Redis, and previous versions of your assets are stored on S3. To switch the version of the running Ember application, developers use the activate command to tell their server to use a particular index.html file that is pointing to single set of assets stored on S3.

ember deploy:activate production --revision 44f2f92

To learn more about how you can deploy an Ember application with your infrastructure, checkout the documentation for ember-cli-deploy.

Not Just For Ember Link

All of that talk about eliminating trivial choices might have left you with the impression that Ember CLI isn’t flexible or configurable. Because Ember CLI needs to accommodate a wide range of use cases from the community, it has a well-defined public interface for customization. In fact, despite the name, Ember isn’t a requirement for Ember CLI. For instance, the Firefox OS team has used Ember CLI with an addon that it created31, rather than create its own build tool.

Suppose you want all of the wonderful features of Ember CLI without Ember. Again, you can follow along in the accompanying GitHub repository32 if you like. We’ll start with a new Ember CLI application:

ember new no-ember

Next, we’ll get rid of Ember so that it isn’t in our JavaScript build. We’ll remove Ember and Ember Data from the bower.json file.

// In bower.json
{
  …
  "dependencies": {
    "ember": "2.2.0", // Delete
    …
    "ember-data": "^2.2.1", // Delete
    …
  },
  "resolutions": {
    "ember": "2.2.0" // Delete
  }
}

We also need to remove Ember Data from the package.json file.

// In package.json
{
  …
  "devDependencies": {
    …
    "ember-data": "^2.2.1", // Delete
    …
  }
}

Next, let’s delete most of the things in our application directory. To have a working application, we only need, styles, app.js and index.html.

app/
├── app.js
├── index.html
└── styles

Ember CLI is expecting us to export an object from app.js that has a create method which mirrors the interface to an Ember.Application. Let’s replace the default content in that file with a simple exported object.

export default {
  create() {
  }
};

Finally, let’s create an ECMAScript 6 module that renders something in our application.

In app/modules/render-something.js, we’ll export a function that renders some content.

export default function renderSomething() {
  document.write("Who needs a framework?");
}

You can put the modules wherever you want in the app directory. You’ll use the same path when importing from your application’s namespace. Here is how we can import and use that module in our app.js file:

import renderSomething from 'no-ember/modules/render-something';

export default {
  create() {
    renderSomething();
  }
};

Now you can see your web app running at http://localhost:4200.

A pure and simple web app, free from framework tyranny33
A pure and simple web app, free from framework tyranny. (View large version34)

The Future Of Ember CLI Link

Without question, Ember CLI is here to stay. Although the Ember community was the first of the modern front-end framework communities to take build tools into their own hands, others have begun to follow suite. AngularJS 2.0 has its own CLI tool, angular-cli35, which is an Ember CLI addon. Because React has a narrower scope than AngularJS 2.0 or Ember, an official build tool is not planned, but something promising will hopefully emerge from its current ecosystem of tools36.

If you’ve been waiting to give Ember a try, why not start today with Ember CLI? All you need to get started is this:

npm install -g ember-cli
ember new my-first-ember-project

References Link

(rb, ml, al)

Footnotes Link

  1. 1 http://emberjs.com/
  2. 2 http://brewhouse.io/blog/2015/05/13/emberjs-an-antidote-to-your-hype-fatigue.html
  3. 3 https://twitter.com/wycats/status/597772107510976512
  4. 4 https://github.com/emberjs/ember.js/pull/10501
  5. 5 http://www.ember-cli.com/
  6. 6 https://facebook.github.io/react/docs/tooling-integration.html
  7. 7 https://youtu.be/9naDS3r4MbY?t=1m47s
  8. 8 https://twitter.com/chriseppstein/status/590211838782013440
  9. 9 http://www.emberaddons.com/
  10. 10 https://github.com/ember-cli/ember-cli-deploy
  11. 11 https://github.com/tildeio/ember-cli-fastboot
  12. 12 https://nodejs.org/
  13. 13 http://brew.sh/
  14. 14 https://www.smashingmagazine.com/wp-content/uploads/2015/06/01-default-app-opt.png
  15. 15 https://www.smashingmagazine.com/wp-content/uploads/2015/06/01-default-app-opt.png
  16. 16 https://github.com/mitchlloyd/smashing-ember-cli-my-app/commits/master
  17. 17 http://expressjs.com/
  18. 18 https://github.com/emberjs/data
  19. 19 https://www.smashingmagazine.com/wp-content/uploads/2015/06/02-posts-opt.png
  20. 20 https://www.smashingmagazine.com/wp-content/uploads/2015/06/02-posts-opt.png
  21. 21 http://bower.io/
  22. 22 https://www.npmjs.com/
  23. 23 http://dbushell.github.io/Pikaday/
  24. 24 https://www.smashingmagazine.com/wp-content/uploads/2015/06/03-pikaday-opt.png
  25. 25 https://www.smashingmagazine.com/wp-content/uploads/2015/06/03-pikaday-opt.png
  26. 26 http://momentjs.com/
  27. 27 https://www.smashingmagazine.com/wp-content/uploads/2015/06/04-all-tests-opt.png
  28. 28 https://www.smashingmagazine.com/wp-content/uploads/2015/06/04-all-tests-opt.png
  29. 29 https://youtu.be/4EDetv_Rw5U?t=11m1s
  30. 30 https://youtu.be/4EDetv_Rw5U?t=18m59s
  31. 31 https://github.com/mozilla/ember-cli-fxos
  32. 32 https://github.com/mitchlloyd/smashing-ember-cli-no-ember/commits/master
  33. 33 https://www.smashingmagazine.com/wp-content/uploads/2015/06/05-no-ember-app-opt.png
  34. 34 https://www.smashingmagazine.com/wp-content/uploads/2015/06/05-no-ember-app-opt.png
  35. 35 https://github.com/angular/angular-cli
  36. 36 https://github.com/facebook/react/wiki/Complementary-Tools#build-tools
  37. 37 http://www.ember-cli.com/
  38. 38 https://www.youtube.com/watch?v=J6vPwvFdUiE
  39. 39 https://www.youtube.com/watch?v=9naDS3r4MbY

↑ Back to top Tweet itShare on Facebook

Advertisement

Mitch Lloyd is an independent developer who is passionate about creating humane software. He produces online learning materials, teaches Ember trainings, and contracts with companies to build ambitious front-end web applications.

  1. 1

    Hi,

    I followed along…this is one of the clearest tutorials for Ember I’ve seen. However…I’ve run into an issue on two completely different machines, and got the exacts same results.

    Everything runs perfectly – right up until running “ember serve” at which point the build hangs and just sits. And sits. And sits.

    Two separate machines, same result. Both Windows 7. One 64 bit, one 32 bit. Tried with Node 4.2.4 and 5.3, and both ember cli 1.13.13 and 2.2.0beta.3, used the NPM install bower, and then the bower install. Also flushed everything and re-installed.

    Did everything as per the instructions…and resulted in constant hang.

    I would dearly love to use this tool – any thoughts? Is this a version issue? Is one of the items off (as in too new and the others too old)? Bower? Node? Ember cli? NPM? Computer version? Firewall? A build error?

    I don’t know enough for what to look for here. I would love to finish your fantastic tutorial. Any help or suggestions would be appreciated. Thank you.

    0
    • 2
    • 3

      Unfortunately, yesterday jQuery released a new version which is not working with Ember.js. Based on the default settings the latest version of jQuery will be downloaded (in this case 1.12.0).

      Solution: delete a caret in bower.json.
      Originally you have this line in your bower.json:

      “jquery”: “^1.11.3”,

      Please delete that ^ (caret), it will fix the jQuery version to 1.11.3.

      You should have this in your bower.json finally:

      “jquery”: “1.11.3”,

      Delete the bower_components folder and run bower install again. It will install the 1.11.3 version of jQuery.

      Hope your app will work properly.

      If you would like to build a more complex web app later, we maintain a free tutorial here: http://www.yoember.com

      0
    • 4

      Check this out:
      http://ember-cli.com/user-guide/#windows

      The best solution is to not use Windows though ;)

      -3
      • 5

        The best solution is to not use Windows though ;)

        …but then what’s the point? (I know it was said in jest :) ).

        The thing that gets me is when Ember had just the starter kit…it worked dandy…now all this extra cruft is causing issues to get up and started. Bleah.

        Thank you @Zoltan. Will give it a shot.

        0
        • 6

          Marty M, hope your app is working. If you launch your development server with `ember s`, and if you still see an empty white page only in your browser, open the development console in Chrome and share your error message with us. We have an extremely active community, you can get help quickly.

          Discuss forum page: http://discuss.emberjs.com/

          Don’t hesitate to join the community Slack channel here: https://ember-community-slackin.herokuapp.com/
          (You can ping me any time there with @zoltan)

          -1
  2. 7

    Actually I wouldn’t recommend using Ember-CLI for now. It’s great to start with but at some point you’ll want to customise a certain task. In our case we want to run our tests in node instead of the browser/phantomjs because they’ll run faster in node.

    Now you’re sitting in front of a 6000 lines long npm module where you have absolutely no idea what’s happening.

    I know the guys from ember tried to make the starting process as neat as possible which is fine to test stuff out, but if you want to create a sustainable business on ember I wouldn’t start with ember-cli again.

    -5
  3. 8

↑ Back to top