Ember
A Compendium of Hooks in EmberCLI
Below you'll find information relevant to creating addons in EmberCLI. Addons are a powerful abstraction in EmberCLI. These addons help enable the extension of Ember applications built with the framework. EmberCLI has several generators that make creating addons simple, but knowing where to put your addon specific customizations can be difficult. This post will attempt to list all known addon hooks as of EmberCLI version 0.1.4
.
Table of Contents:
- config
- bluprintsPath
- includedCommands
- serverMiddleware
- postBuild
- preBuild
- included
- postProcess
- treeFor
For each hook we'll cover the following (if applicable):
- Received arguments
- Source
- Default implementation
- Uses
- Examples
Compendium is largely based of a talk by @rwjblue which can be found here
Config
Augments the applications configuration settings. Object returned from this hook is merged with the application's configuration object. Application's configuration always take precedence.
Received arguments:
- env - name of current environment (ie "developement")
- baseConfig - Initial application config
Source: lib/models/addon.js:312
Default implementation:
Addon.prototype.config = function (env, baseConfig) {
var configPath = path.join(this.root, 'config', 'environment.js');
if (fs.existsSync(configPath)) {
var configGenerator = require(configPath);
return configGenerator(env, baseConfig);
}
};
Uses:
- Modifying configuration options (see list of defaults here)
- For example
minifyJS
storeConfigInMeta
es3Safe
- et, al
Examples:
- Setting
storeConfigInMeta
to false in ember-cli-rails-addon
blueprintsPath
Tells the application where your blueprints exist.
Received arguments: None
Source: lib/models/addon.js:304
Default implementation:
Addon.prototype.blueprintsPath = function() {
var blueprintPath = path.join(this.root, 'blueprints');
if (fs.existsSync(blueprintPath)) {
return blueprintPath;
}
};
Uses:
- Let application know where blueprints exists.
Examples:
includedCommands
Allows the specification of custom addon commands. Expects you to return an object whose key is the name of the command and value is the command instance.
Received arguments: None
Source: lib/models/project.js:234
Default implementation: None
Uses:
- Include custom commands into consuming application
Examples:
// https://github.com/rwjblue/ember-cli-divshot/blob/v0.1.6/index.js
includedCommands: function() {
return {
'divshot': require('./lib/commands/divshot')
}
}
serverMiddleware
Designed to manipulate requests in development mode.
Received arguments: - options (eg express_instance, project, watcher, environment)
Source: lib/tasks/server/express-server.js:63
Default implementation: None
Uses:
- Tacking on headers to each request
- Modifying the request object
Note: that this should only be used in development, and if you need the same behavior in production you'll need to configure your server.
Examples:
postBuild
Gives access to the result of the tree, and the location of the output.
Received arguments:
- Result object from broccoli build
result.directory
- final output path
Source: lib/models/builder.js:111
Default implementation: None
Uses:
- Slow tree listing
- May be used to manipulate your project after build has happened
- Opportunity to symlink or copy files elsewhere.
Examples:
- ember-cli-rails-addon
- In this case we are using this in tandem with a rails middleware to remove a lock file. This allows our ruby gem to block incoming requests until after the build happens reliably.
preBuild
Hook called before build takes place.
Received arguments:
Source: lib/models/builder.js:114
Default implementation: None
Uses:
Examples:
- ember-cli-rails-addon
- In this case we are using this in tandem with a rails middleware to create a lock file. [See postBuild]
included
Usually used to import assets into the application.
Received arguments:
EmberApp
instance see ember-app.js
Source: lib/broccoi/ember-app.js:216
Default implementation: None
Uses:
- including vendor files
- setting configuration options
Note: Any options set in the consuming application will override the addon.
Examples:
// https://github.com/yapplabs/ember-colpick/blob/master/index.js
included: function colpick_included(app) {
this._super.included(app);
var colpickPath = path.join(app.bowerDirectory, 'colpick');
this.app.import(path.join(colpickPath, 'js', 'colpick.js'));
this.app.import(path.join(colpickPath, 'css', 'colpick.css'));
}
postProcess
Received arguments:
- post processing type (eg all)
- receives tree after build
Source: lib/broccoli/ember-app.js:251
Default implementation: None
Uses:
- fingerprint assets
- running processes after build but before toTree
Examples:
treeFor
Return value is merged with application tree of same type
Received arguments:
- returns given type of tree (eg app, vendor, bower)
Source: lib/broccoli/ember-app.js:240
Default implementation:
Addon.prototype.treeFor = function treeFor(name) {
this._requireBuildPackages();
var tree;
var trees = [];
if (tree = this._treeFor(name)) {
trees.push(tree);
}
if (this.isDevelopingAddon() && this.app.hinting && name === 'app') {
trees.push(this.jshintAddonTree());
}
return this.mergeTrees(trees.filter(Boolean));
};
Uses:
- manipulating trees at build time
Examples:
treeFor (cont...)
Instead of overriding treeFor
and acting only if the tree you receive matches the one you need EmberCLI has custom hooks for the following Broccoli trees
- treeForApp
- treeForStyles
- treeForTemplates
- treeForAddon
- treeForVendor
- treeForTestSupport
- treeForPublic
See more here