My problem is I am unable to get the contentFor method in an addon to run when this addon is used in a dependency of another addon (confusing I know).
My organization has an in-house ember addon that we use to distribute common styles, images and components for our ember applications. I'll refer to that addon as org-components
. We have decided to adopt material design, and so we have chosen to use ember-paper along with our existing addon.
In order to reduce the number of dependancies people would need to reference in the ingesting applications, we would prefer to include ember-paper
as a dependency of org-components
(not a devDependency
).
Thus our dependency chain goes like so:
ember-paper -> org-components -> ember-engine
ember-paper
has a contentFor
method defined in ~/index.js
that will inject a couple of stylesheets for Material icons and fonts in the head and paper-wormhole
divs into body-footer
for use by the select menu dropdowns and toast messages. For reasons I do not know, the contentFor
method does not execute when ember-paper
is included as a dependency as shown above.
When I include both components as separate dependancies, then the contentFor
method is executed and things work as expected:
ember-paper -> ember-engine
org-components -> ember-engine
So I am looking to understand why I am unable to leverage the ember-paper
addon when it is used as a dependency of our existing addon. What is preventing the contentFor build step from being executed? Is their a best practice I should keep in mind while trying to solve this problem?
I eventually was able to discover a solution to this problem, thanks to the always helpful Robert Jackson from the Ember Team.
After pleading for help in the Ember Slack community, Robert made me aware that the existing contentFor
functionality in ember-engines was not extended yet to handle this use-case. He acknowledged that it was an oversight and that they would most likely be adding the functionality in the future, but for the time being he provided me with a workaround to add into /lib/engine-addon.js
.
options.contentFor = function(type, config) {
let deprecatedHooks = ['app-prefix', 'app-suffix', 'vendor-prefix', 'vendor-suffix'];
if (deprecatedHooks.indexOf(type) > -1) {
// ember-engines does not support the deprecated contentFor hooks
return '';
}
let content = [];
if (type === 'head') {
let engineConfig = this.engineConfig(config.environment, {});
let escapedConfig = escape(JSON.stringify(engineConfig));
content = content.push(
`<meta name="${options.name}/config/environment" content="${escapedConfig}" />`
);
}
content = this.addons.reduce((content, addon) => {
let addonContent = addon.contentFor ? addon.contentFor(type, config, content) : null;
if (addonContent) {
return content.concat(addonContent);
}
return content;
}, content);
return content.join('\n');
};
Also available as a Gist
I have not kept up with the dev roadmap for ember-engines or whether this has been added into a later version than what we are currently using. As noted the folks in the Ember Slack are very helpful and will point you in the right direction if you have those questions.