Ember CLI uses Bower for dependency management.
The Bower configuration file, bower.json, is located at the root of your Ember
CLI project, and lists the dependencies for your project. Changes to your
dependencies should be managed through this file, rather than manually
installing packages individually.
Executing bower install will install all of the dependencies listed in
bower.json in one step.
Ember CLI is configured to have git ignore your bower_components directory by
default. Using the Bower configuration file allows collaborators to fork your
repo and get their dependencies installed locally by executing bower install
themselves.
Ember CLI watches bower.json for changes. Thus it reloads your app if you
install new dependencies via bower install --save <dependencies>.
Further documentation about Bower is available at their official documentation page.
In your Brocfile.js specify a dependency before calling app.toTree(). You
can only import assets that are within the bower_components or vendor
directories. The following example scenarios illustrate how this works.
Provide the asset path as the first and only argument:
1 app.import('bower_components/moment/moment.js');From here you would use the package as specified by it’s documentation, usually a global variable. In this case it would be:
1 import Ember from 'ember';
2 /* global moment */
3 // No import for moment, it's a global called `moment`
4
5 // ...
6 var day = moment('Dec 25, 1995');Note: Don’t forget to make JSHint happy by adding a /* global MY_GLOBAL */ to your module, or
by defining it within the predefs section of your .jshintrc file.
Provide the asset path as the first argument, and the list of modules and exports as the second:
1 app.import('bower_components/ic-ajax/dist/named-amd/main.js', {
2 exports: {
3 'ic-ajax': [
4 'default',
5 'defineFixture',
6 'lookupFixture',
7 'raw',
8 'request',
9 ]
10 }
11 });To use this asset in your app, import it.
For example, with ic-ajax, when to use ic.ajax.raw:
1 import { raw as icAjaxRaw } from 'ic-ajax';
2 //...
3 icAjaxRaw( /* ... */ );If you need to use different assets in different environments, specify an object as the first parameter. That object’s key should be the environment name, and the value should be the asset to use in that environment.
1 app.import({
2 development: 'bower_components/ember/ember.js',
3 production: 'bower_components/ember/ember.prod.js'
4 });If you need to import an asset in one environment but not import it or any alternatives in other environments then you can wrap app.import in an if statement.
1 if (app.env === 'development') {
2 app.import('vendor/ember-renderspeed/ember-renderspeed.js');
3 }This is somewhat non-standard and discouraged, but suppose that due to a requirement in your application that you need to use the full version of
Handlebars even in the production environment. You would simply provide the path to the EmberApp constructor:
1 var app = new EmberApp({
2 vendorFiles: {
3 'handlebars.js': {
4 production: 'bower_components/handlebars/handlebars.js'
5 }
6 }
7 });You may have additional libraries that should only be included when running tests (such as qunit-bdd or sinon). These can be merged into your assets in your Brocfile.js:
1 var EmberApp = require('ember-cli/lib/broccoli/ember-app');
2 var pickFiles = require('broccoli-static-compiler');
3
4 var app = new EmberApp();
5
6 var qunitBdd = pickFiles('bower_components/qunit-bdd/lib', {
7 srcDir: '/',
8 files: ['qunit-bdd.js'],
9 destDir: '/assets'
10 });
11
12 module.exports = app.toTree(qunitBdd);Notes:
- Be sure to add the appropriate script tag for your test library.
- The first argument to pickFiles is a tree. This means that doing pickFiles('bower_components', ...) will cause all files in /bower_components to be watched. If you get a Error: watch EMFILE during build, this could be the culprit. Consider using a more specific path as tree or use pickFiles(unwatchedTree('bower_components'),...) from broccoli-unwatched-tree.
...
<script src="assets/qunit.js"></script>
<script src="assets/qunit-bdd.js"></script>
...Provide the asset path as the first argument:
1 app.import('bower_components/foundation/css/foundation.css');All style assets added this way will be concatenated and output as /assets/vendor.css.
The vendor trees that are provided upon instantiation are available to your dynamic style files. Take the following example (in app/styles/app.scss):
1 @import "bower_components/foundation/scss/normalize.scss";All other assets like images or fonts can also be added via import(). By default, they
will be copied to dist/ as they are.
1 app.import('bower_components/font-awesome/fonts/fontawesome-webfont.ttf');This example would create the font file in dist/font-awesome/fonts/fontawesome-webfont.ttf.
You can also optionally tell import() to place the file at a different path.
The following example will copy the file to dist/assets/fontawesome-webfont.ttf.
1 app.import('bower_components/font-awesome/fonts/fontawesome-webfont.ttf', {
2 destDir: 'assets'
3 });With the broccoli-static-compiler package, (parts of) a bower-installed package can be used as assets as-is. First ensure that the Broccoli package needed to build are installed:
npm install --save-dev broccoli-static-compilerAdd this import to the top of Brocfile.js, just below the EmberApp require:
1 var pickFiles = require('broccoli-static-compiler');At the bottom of Brocfile.js we merge assets from a bower dependency with the main app tree:
1 // Remove this line:
2 // module.exports = app.toTree()
3
4 // Copy only the relevant files. For example the WOFF-files and stylesheets for a webfont:
5 var extraAssets = pickFiles('bower_components/a-lovely-webfont', {
6 srcDir: '/',
7 files: ['**/*.woff', '**/stylesheet.css'],
8 destDir: '/assets/fonts'
9 });
10
11 // Providing additional trees to the `toTree` method will result in those
12 // trees being merged in the final output.
13 module.exports = app.toTree(extraAssets);In the above example the assets from the fictive bower dependency called a-lovely-webfont can now
be found under /assets/fonts/, and might be linked to from index.html like so:
<link rel="stylesheet" href="assets/fonts/lovelyfont_bold/stylesheet.css">