Skip to content

Commit

Permalink
add delayed transpilation
Browse files Browse the repository at this point in the history
  • Loading branch information
Kelly Selden committed Feb 18, 2018
1 parent 7359c18 commit 94063b2
Show file tree
Hide file tree
Showing 9 changed files with 286 additions and 75 deletions.
109 changes: 100 additions & 9 deletions lib/broccoli/ember-app.js
Expand Up @@ -23,7 +23,9 @@ let preprocessTemplates = p.preprocessTemplates;
let preprocessMinifyCss = p.preprocessMinifyCss;

const concat = require('broccoli-concat');

const BroccoliDebug = require('broccoli-debug');
const ModuleNormalizer = require('broccoli-module-normalizer');
const AmdFunnel = require('broccoli-amd-funnel');
const ConfigReplace = require('broccoli-config-replace');
const ConfigLoader = require('broccoli-config-loader');
const mergeTrees = require('./merge-trees');
Expand Down Expand Up @@ -170,6 +172,8 @@ class EmberApp {
if (!this._addonInstalled('loader.js') && !this.options._ignoreMissingLoader) {
throw new SilentError('The loader.js addon is missing from your project, please add it to `package.json`.');
}

this._debugTree = BroccoliDebug.buildDebugCallback('ember-app');
}

/**
Expand Down Expand Up @@ -603,6 +607,21 @@ class EmberApp {
this.project.initializeAddons();
}

_addonTreesFor(type) {
return this.project.addons.reduce((sum, addon) => {
if (addon.treeFor) {
let tree = addon.treeFor(type);
if (tree) {
sum.push({
name: addon.name,
tree,
});
}
}
return sum;
}, []);
}

/**
Returns a list of trees for a given type, returned by all addons.
Expand All @@ -612,13 +631,32 @@ class EmberApp {
@return {Array} List of trees
*/
addonTreesFor(type) {
return this.project.addons.reduce((sum, addon) => {
if (addon.treeFor) {
let val = addon.treeFor(type);
if (val) { sum.push(val); }
}
return sum;
}, []);
return this._addonTreesFor(type).map(addonBundle => addonBundle.tree);
}

_compileAddonTemplates(tree) {
tree = preprocessTemplates(tree, {
annotation: `_compileAddonTemplates`,
registry: this.registry,
});

return tree;
}

_compileAddonJs(tree) {
tree = preprocessJs(tree, '/', '/', {
annotation: `_compileAddonJs`,
registry: this.registry,
});

return tree;
}

_compileAddonTree(tree) {
tree = this._compileAddonTemplates(tree);
tree = this._compileAddonJs(tree);

return tree;
}

/**
Expand Down Expand Up @@ -1081,7 +1119,60 @@ class EmberApp {
}

_addonTree(type, outputDir) {
let addonTrees = this.addonTreesFor(type);
let addonBundles = this._addonTreesFor(type);

let addonTrees = addonBundles.map(addonBundle => {
let name = addonBundle.name;
let tree = addonBundle.tree;

tree = this._debugTree(tree, `precompiledAddonTree:${type}:${name}`);

if (!this.options.moduleNormalizerDisabled) {
// move legacy /modules/addon to /addon
let hasAlreadyPrintedModuleDeprecation;
tree = new ModuleNormalizer(tree, {
callback: () => {
if (!hasAlreadyPrintedModuleDeprecation) {
this.project.ui.writeDeprecateLine(`Addon "${name}" is manually placing files in the legacy "modules" folder. Support for this will be removed in a future version.`);
hasAlreadyPrintedModuleDeprecation = true;
}
},
annotation: `ModuleNormalizer (${type} ${name})`,
});
}

let precompiledSource;
if (!this.options.amdFunnelDisabled) {
// don't want to double compile the AMD modules
let hasAlreadyPrintedAmdDeprecation;
precompiledSource = new AmdFunnel(tree, {
callback: () => {
if (!hasAlreadyPrintedAmdDeprecation) {
this.project.ui.writeDeprecateLine(`Addon "${name}" is manually generating AMD modules. Code should be ES6 modules only. Support for this will be removed in a future version.`);
hasAlreadyPrintedAmdDeprecation = true;
}
},
annotation: `AmdFunnel (${type} ${name})`,
});
} else {
precompiledSource = tree;
}

let compiledSource = this._compileAddonTree(precompiledSource);

if (this.options.amdFunnelDisabled) {
tree = compiledSource;
} else {
tree = mergeTrees([tree, compiledSource], {
overwrite: true,
annotation: `AmdFunnel TreeMerger (${type} ${name})`,
});
}

tree = this._debugTree(tree, `postcompiledAddonTree:${type}:${name}`);

return tree;
});

let combinedAddonTree = mergeTrees(addonTrees, {
overwrite: true,
Expand Down
26 changes: 15 additions & 11 deletions lib/models/addon.js
Expand Up @@ -223,8 +223,13 @@ let addonProto = {

let emberCLIBabelConfigKey = this._emberCLIBabelConfigKey();
this.__originalOptions[emberCLIBabelConfigKey] = this.options[emberCLIBabelConfigKey] = defaultsDeep(this.options[emberCLIBabelConfigKey], {
compileModules: true,
compileModules: false,
disablePresetEnv: true,
disableDebugTooling: true,
disableEmberModulesAPIPolyfill: true,
});

this.registry.remove('template', 'ember-cli-htmlbars');
},

/*
Expand Down Expand Up @@ -1009,18 +1014,17 @@ let addonProto = {
this._requireBuildPackages();

if (this.shouldCompileTemplates()) {
if (!registryHasPreprocessor(this.registry, 'template')) {
throw new SilentError(`Addon templates were detected, but there are no template compilers registered for \`${this.name}\`. ` +
`Please make sure your template precompiler (commonly \`ember-cli-htmlbars\`) is listed in \`dependencies\` ` +
`(NOT \`devDependencies\`) in \`${this.name}\`'s \`package.json\`.`);
}

let preprocessedTemplateTree = this._addonPreprocessTree('template', this._addonTemplateFiles(addonTree));

let processedTemplateTree = preprocessTemplates(preprocessedTemplateTree, {
annotation: `compileTemplates(${this.name})`,
registry: this.registry,
});
let processedTemplateTree;
if (registryHasPreprocessor(this.registry, 'template')) {
processedTemplateTree = preprocessTemplates(preprocessedTemplateTree, {
annotation: `compileTemplates(${this.name})`,
registry: this.registry,
});
} else {
processedTemplateTree = preprocessedTemplateTree;
}

let postprocessedTemplateTree = this._addonPostprocessTree('template', processedTemplateTree);

Expand Down
2 changes: 2 additions & 0 deletions package.json
Expand Up @@ -40,6 +40,7 @@
"babel-plugin-transform-es2015-modules-amd": "^6.24.0",
"bower-config": "^1.3.0",
"bower-endpoint-parser": "0.2.2",
"broccoli-amd-funnel": "ember-cli/broccoli-amd-funnel#short-circuit",
"broccoli-babel-transpiler": "^6.0.0",
"broccoli-brocfile-loader": "^0.18.0",
"broccoli-builder": "^0.18.8",
Expand All @@ -51,6 +52,7 @@
"broccoli-funnel-reducer": "^1.0.0",
"broccoli-merge-trees": "^2.0.0",
"broccoli-middleware": "^1.0.0",
"broccoli-module-normalizer": "kellyselden/broccoli-module-normalizer#merge-trees",
"broccoli-source": "^1.1.0",
"broccoli-stew": "^1.2.0",
"calculate-cache-key-for-tree": "^1.0.0",
Expand Down
42 changes: 26 additions & 16 deletions tests/unit/broccoli/ember-app-test.js
Expand Up @@ -12,6 +12,24 @@ const MockCLI = require('../../helpers/mock-cli');

let EmberApp = require('../../../lib/broccoli/ember-app');

function mockTemplateRegistry(app) {
let oldLoad = app.registry.load;
app.registry.load = function(type) {
if (type === 'template') {
return [
{
toTree() {
return {
description: 'template',
};
},
},
];
}
return oldLoad.apply(app.registry, arguments);
};
}

describe('EmberApp', function() {
let project, projectPath, app, addon;

Expand Down Expand Up @@ -542,6 +560,8 @@ describe('EmberApp', function() {
app = new EmberApp({
project,
});

mockTemplateRegistry(app);
});

it('has default vendor.css', function() {
Expand All @@ -561,6 +581,8 @@ describe('EmberApp', function() {

app.addonPostprocessTree = td.function();
td.when(app.addonPostprocessTree(), { ignoreExtraArgs: true }).thenReturn(['batman']);

mockTemplateRegistry(app);
});

it('from .styles()', function() {
Expand All @@ -570,22 +592,6 @@ describe('EmberApp', function() {
});

it('template type is called', function() {
let oldLoad = app.registry.load;
app.registry.load = function(type) {
if (type === 'template') {
return [
{
toTree() {
return {
description: 'template',
};
},
}];
} else {
return oldLoad.call(app.registry, type);
}
};

app._processedTemplatesTree();

let captor = td.matchers.captor();
Expand Down Expand Up @@ -632,6 +638,8 @@ describe('EmberApp', function() {
});

it('calls each addon postprocessTree hook', function() {
mockTemplateRegistry(app);

app.index = td.function();
app._processedTemplatesTree = td.function();

Expand Down Expand Up @@ -1069,6 +1077,8 @@ describe('EmberApp', function() {
app.appAndDependencies = function() {
return 'app-and-dependencies-tree';
};

mockTemplateRegistry(app);
});

it('prevents duplicate inclusion, maintains order: CSS', function() {
Expand Down

0 comments on commit 94063b2

Please sign in to comment.