Table of Contents:
- blueprintsPath
- includedCommands
- serverMiddleware
- postBuild
- preBuild
- outputReady
- buildError
- included
- shouldIncludeChildAddon
- setupPreprocessorRegistry
- postprocessTree
- lintTree
- contentFor
- 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.
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 "development")
- baseConfig - Initial application config
Source: lib/models/addon.js:485
Default implementation:
Addon.prototype.config = function (env, baseConfig) {
var configPath = path.join(this.root, 'config', 'environment.js');
if (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
- For example
Examples:
- Setting
storeConfigInMeta
to false in ember-cli-rails-addon
Tells the application where your blueprints exist.
Received arguments: None
Source: lib/models/addon.js:457
Default implementation:
Addon.prototype.blueprintsPath = function() {
var blueprintPath = path.join(this.root, 'blueprints');
if (existsSync(blueprintPath)) {
return blueprintPath;
}
};
Uses:
- Let application know where blueprints exists.
Examples:
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:388
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')
};
}
Designed to manipulate requests in development mode.
Received arguments:
- options (eg express_instance, project, watcher, environment)
Source: lib/tasks/server/express-server.js:64
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:
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:117
Default implementation: None
Uses:
- Slow tree listing
- May be used to manipulate your project after build has happened
Hook called before build takes place.
Received arguments:
Source: lib/models/builder.js:112
Default implementation: None
Uses:
Hook called after the build has been processed and the files have been copied to the output directory
Received arguments:
- Result object from broccoli build
result.directory
- final output path
Default implementation: None
Examples:
- Opportunity to symlink or copy files elsewhere.
- 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.
buildError hook will be called on when an error occurs during the preBuild, postBuild or outputReady hooks for addons, or when builder#build fails
Received arguments:
- The error that was caught during the processes listed above
Source: lib/models/builder.js:119
Default implementation: None
Uses:
- Custom error handling during build process
Examples:
Usually used to import assets into the application.
Received arguments:
EmberApp
instance see ember-app.js
Source: lib/broccoli/ember-app.js:268
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.apply(this, arguments);
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'));
}
Can be used to exclude addons from being added as a child addon.
Received arguments:
Addon
instance see addon.js
Source: lib/models/addon.js:638
Default implementation: return true
Uses:
- abstract away multiple addons while only including one into the built assets
Examples:
shouldIncludeChildAddon: function select_shouldIncludeChildAddon(childAddon) {
if(childAddon.name === 'ember-cli-some-legacy-select-component') {
return this.options.legacyMode;
} else if(childAddon.name === 'ember-cli-awesome-new-select-component') {
return !this.options.legacyMode;
} else {
return this._super.shouldIncludeChildAddon.apply(this, arguments);
}
}
Used to add preprocessors to the preprocessor registry. This is often used by addons like ember-cli-htmlbars
and ember-cli-coffeescript to add a template
or js
preprocessor to the registry.
Received arguments
type
either"self"
or"parent"
registry
the registry to be set up
Source: lib/preprocessors:7
Default implementation: None
Uses:
- Adding preprocessors to the registry.
Examples:
// https://github.com/ember-cli/ember-cli-htmlbars/blob/master/ember-addon-main.js
setupPreprocessorRegistry: function(type, registry) {
var addonContext = this;
registry.add('template', {
name: 'ember-cli-htmlbars',
ext: 'hbs',
toTree: function(tree) {
return htmlbarsCompile(tree, addonContext.htmlbarsOptions());
}
});
}
Received arguments:
- post processing type (eg all)
- receives tree after build
- receives tree for a given type after preprocessors (like HTMLBars or babel) run.
available types:
- js
- template
- all
- css
- test
Source: lib/broccoli/ember-app.js:313
Default implementation: None
Received arguments:
- type of tree (eg template, js)
- receives tree for a given type before preprocessors (like HTMLBars or babel) run.
available types:
- js
- template
- css
- test
Default implementation: None
Uses:
- removing / adding files from the build.
Examples:
Return value is merged into the tests tree. This lets you inject linter output as test results.
Received arguments:
- tree type ('app', 'tests', 'templates', or 'addon')
- tree of files (JavaScript files for
app
,tests
, andaddon
types)
Source: lib/broccoli/ember-app.js:335
Default implementation: None
Uses:
- JSHint
- any other form of automated test generation that turns code into tests
Examples:
Allow addons to implement contentFor method to add string output into the associated {{content-for 'foo'}} section in index.html
Received arguments:
- type
- config
- content
Source: lib/broccoli/ember-app.js:1167
Default implementation: None
Uses:
- For instance, to inject analytics code into index.html
Examples:
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:296
Default implementation:
var mergeTrees = require('broccoli-merge-trees');
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 mergeTrees(trees.filter(Boolean));
};
Uses:
- manipulating trees at build time
Examples:
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
- treeForAddonTemplates
- treeForAddon
- treeForVendor
- treeForTestSupport
- treeForPublic
- treeForAddonTestSupport
When overriding a hook, if you want to preserve it's original functionality, call the same method on _super
with the function arguments.
Examples:
treeForAddon: function(tree) {
var checker = new VersionChecker(this);
var isOldEmber = checker.for('ember', 'bower').lt('1.13.0');
if (isOldEmber) {
tree = new Funnel(tree, { exclude: [ /instance-initializers/ ] });
}
return this._super.treeForAddon.call(this, tree);
}
Allows to mark the addon as developing, triggering live-reload in the project the addon is linked to
Received arguments: None
Default implementation: None
Uses:
- Working on projects with internal addons
Examples:
// addon index.js
isDevelopingAddon: function() {
return true;
}
See more here.