external dependencies in ember addons

It is reasonable to assume that an ember addon might require an external dependency in its quest to provide whatever service it provides.

Because developing an addon is a bit of a chicken and egg thing(you're developing an addon and also using it in the dummy app, but the dummy app technically never installs the addon), as of v2.3.0 the process of including an external dependency in an ember addon needs a little attention to detail.

The extra work is because there are two ember apps in the picture here. Two ember apps you're jumping through these dependency hoops for, once that becomes clear all pieces should fall into place.

Here's what I've learned:

  1. ember addons are not ember apps. While it sounds trite, a lot of ember addon developers have been accustomed to the conventions used in ember apps. Occasionally, they differ. This is one of those occasions.

  2. npm or bower? Short answer: bower. ember-cli includes a method called addBowerPackageToProject that makes importing bower packages to the consuming application a very convenient. So, install your dependencies using bower.

  3. why doesn't bower.json take care of this? ember-cli runs an npm install and a bower install whenever an addon is installed via ember install <addon-name>. All it does is downloads the appropriate dependencies in the package.json and bower.json files, in order to make the consuming application be aware of any dependency, one must include it.
  4. For the dummy application: Add an 'included' hook in the addon's index.js file found at the root of your project. More details on ember-cli hooks. app is an app instance of the dummy app. This is similar to the app.import done in ember-cli-build.js for ember apps.
/* jshint node: true */
'use strict';

module.exports = {  
  name: 'gh-badge',
  included: function(app) {
    app.import(app.bowerDirectory + '<path to dependency>.js');

5. For the consuming application: The above doesn't work for any application that tries to use the addon after and ember install. You have to generate a blueprint. A blueprint runs additional code after the addon is installed. It has to be named the same as the addon. To generate a blueprint do an ember generate blueprint <addon-name> This will create a folder called blueprints/<addon-name> This will contain an index.js file. Add the afterInstall method as below. This code runs after the ember addon gets installed.

/*jshint node:true*/
module.exports = {  
  normalizeEntityName: function() {},

  afterInstall: function(options) {
  // Perform extra work here.
    return this.addBowerPackageToProject('<bower-dependency-name>');

Your ember addon should now be able to download dependencies and include them in both the dummy app for you to develop with and also for any consuming application that downloads you addon using ember install

What about my dependencies?

  • Static files(images, fonts) go in public
  • Styles have been dealt with in a previous post
  • Static files end up in /dist/assets/<addon-name> directory in the consuming application.
  • vendor is for all other dependencies.
  • All your css and js ends up in dist/assets/vendor.js and dist/assets/vendor.css in the consuming application

N.B: Use npm-link to test how a consuming application will use the addon. The dummy app is great for developing the addon. But to be sure that all dependencies are getting included as desired, create an actual ember app.

All of this in some other directory than the addon.
1. run npm-link in the addon's root. This will make the addon available as an npm package locally, so you can install it from another app without publishing it.
2. Go to some other directory outside the ember addon. Create an ember app by doing ember new
3. In this new test app, install your addon by running npm link <addon-name>
4. This will install the addon, download the addon's external dependencies and make them available in the test app.
5. Use your addon in application.hbs, so that you don't bother with creating routes etc
6. If everything is configured properly, your addon should behave as expected.
7. To deploy the dummy app, use ember-cli-github-pages

You can now publish your addon and make the ember community an even better place.