Repository: ember-cli/ember-cli
Pull request #7864 (2018-06-03 19:20:28)

Refactor packager
This was missing in https://github.com/ember-cli/ember-cli/commit/1d243e6ef74cd37ab01d2c149c16b68618baa486

Should we consider adding 'testem' to `fingerprint.exclude`  in broccoli-asset-rev default instead of here?


Patch:
diff --git a/lib/broccoli/default-packager.js b/lib/broccoli/default-packager.js
index ffbb6bfb9..46a8276ae 100644
--- a/lib/broccoli/default-packager.js
+++ b/lib/broccoli/default-packager.js
@@ -832,7 +832,7 @@ module.exports = class DefaultPackager {
         srcDir: 'tests',
       });
 
-      testTree = addonProcessTree(this.project, 'preprocessTree', 'test', testTree);
+      testTree = callAddonsPreprocessTreeHook(this.project, 'test', testTree);
 
       testTree = new Funnel(testTree, {
         destDir: `${this.name}/tests`,
@@ -843,7 +843,7 @@ module.exports = class DefaultPackager {
         registry: this.registry,
       });
 
-      this._cachedTests = addonProcessTree(this.project, 'postprocessTree', 'test', preprocessedTests);
+      this._cachedTests = callAddonsPostprocessTreeHook(this.project, 'test', preprocessedTests);
     }
 
     return this._cachedTests;
@@ -1122,10 +1122,6 @@ module.exports = class DefaultPackager {
       annotation: 'Funnel (testem)',
     });
 
-    if (this.fingerprint && this.fingerprint.exclude) {
-      this.fingerprint.exclude.push('testem');
-    }
-
     let sourceTrees = [
       testemTree,
       testJs,
diff --git a/lib/broccoli/ember-app.js b/lib/broccoli/ember-app.js
index 915c03ff6..5d2ecd9dd 100644
--- a/lib/broccoli/ember-app.js
+++ b/lib/broccoli/ember-app.js
@@ -152,6 +152,7 @@ class EmberApp {
     this._defaultPackager = new DefaultPackager({
       env: this.env,
       name: this.name,
+      autoRun: this.options.autoRun,
       project: this.project,
       registry: this.registry,
       sourcemaps: this.options.sourcemaps,
@@ -159,14 +160,12 @@ class EmberApp {
       areTestsEnabled: this.tests,
       styleOutputFiles: this._styleOutputFiles,
       scriptOutputFiles: this._scriptOutputFiles,
-      autoRun: this.options.autoRun,
-      fingerprint: this.options.fingerprint,
-      customTransformsMap: this._customTransformsMap,
       storeConfigInMeta: this.options.storeConfigInMeta,
-      isModuleUnificationEnabled: experiments.MODULE_UNIFICATION && !!this.trees.src,
+      customTransformsMap: this._customTransformsMap,
       additionalAssetPaths: this.otherAssetPaths,
       vendorTestStaticStyles: this.vendorTestStaticStyles,
       legacyTestFilesToAppend: this.legacyTestFilesToAppend,
+      isModuleUnificationEnabled: experiments.MODULE_UNIFICATION && !!this.trees.src,
       distPaths: {
         appJsFile: this.options.outputPaths.app.js,
         appCssFile: this.options.outputPaths.app.css,
@@ -178,8 +177,6 @@ class EmberApp {
         testSupportCssFile: this.options.outputPaths.testSupport.css,
       },
     });
-
-    this._cachedAddonBundles = {};
   }
 
   /**
@@ -364,6 +361,12 @@ class EmberApp {
     if (!('sourceMaps' in this.options.babel)) {
       this.options.babel.sourceMaps = false;
     }
+
+    // Add testem.js to excludes for broccoli-asset-rev.
+    // This will allow tests to run against the production builds.
+    if (this.options.fingerprint && this.options.fingerprint.exclude) {
+      this.options.fingerprint.exclude.push('testem');
+    }
   }
 
   /**
@@ -1093,56 +1096,93 @@ class EmberApp {
     return this._cachedNodeModuleTrees;
   }
 
-  _addonBundles(type, _options) {
-    if (!this._cachedAddonBundles[type]) {
-      let options = Object.assign(
-        {
-          moduleNormalizerDisabled: this.options.moduleNormalizerDisabled,
-        },
-        _options
-      );
+  _addonTree(type, outputDir, _options) {
+    let options = Object.assign(
+      {
+        amdFunnelDisabled: this.options.amdFunnelDisabled,
+        moduleNormalizerDisabled: this.options.moduleNormalizerDisabled,
+        skipTemplates: false,
+      },
+      _options
+    );
+    let addonBundles = this._addonTreesFor(type);
 
-      let addonBundles = this._addonTreesFor(type);
-
-      for (let addonBundle of addonBundles) {
-        let { name, root } = addonBundle;
-
-        if (experiments.DELAYED_TRANSPILATION) {
-          if (!options.moduleNormalizerDisabled) {
-            // move legacy /modules/addon to /addon
-            let hasAlreadyPrintedModuleDeprecation;
-            addonBundle.tree = new ModuleNormalizer(addonBundle.tree, {
-              callback: () => {
-                if (!hasAlreadyPrintedModuleDeprecation) {
-                  this.project.ui.writeDeprecateLine(`Addon "${name}" (found at "${root}") 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 addonTrees = addonBundles.map(addonBundle => {
+      let name = addonBundle.name;
+      let tree = addonBundle.tree;
+      let root = addonBundle.root;
+
+      if (experiments.DELAYED_TRANSPILATION) {
+        if (!options.moduleNormalizerDisabled) {
+          // move legacy /modules/addon to /addon
+          let hasAlreadyPrintedModuleDeprecation;
+          tree = new ModuleNormalizer(tree, {
+            callback: () => {
+              if (!hasAlreadyPrintedModuleDeprecation) {
+                this.project.ui.writeDeprecateLine(`Addon "${name}" (found at "${root}") 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})`,
+          });
         }
       }
 
-      this._cachedAddonBundles[type] = addonBundles;
-    }
+      let precompiledSource = tree;
 
-    return this._cachedAddonBundles[type];
-  }
+      if (experiments.DELAYED_TRANSPILATION) {
+        if (!options.amdFunnelDisabled) {
+          // don't want to double compile the AMD modules
+          let hasAlreadyPrintedAmdDeprecation;
+          precompiledSource = new AmdFunnel(precompiledSource, {
+            callback: () => {
+              if (!hasAlreadyPrintedAmdDeprecation) {
+                this.project.ui.writeDeprecateLine(`Addon "${name}" (found at "${root}") 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})`,
+          });
+        }
+      }
 
-  /*
-   * @private
-   * @method @createAddonTree
-  */
-  createAddonTree(type, outputDir, options) {
-    let addonBundles = this._addonBundles(type, options);
+      return [tree, precompiledSource];
+    });
 
-    let tree = mergeTrees(addonBundles.map(({ tree }) => tree), {
+    let precompiledSource = addonTrees.map(pair => pair[1]);
+    addonTrees = addonTrees.map(pair => pair[0]);
+
+    if (!experiments.DELAYED_TRANSPILATION) {
+      precompiledSource = addonTrees;
+    }
+
+    precompiledSource = mergeTrees(precompiledSource, {
       overwrite: true,
       annotation: `TreeMerger (${type})`,
     });
 
-    return new Funnel(tree, {
+    let combinedAddonTree;
+
+    if (experiments.DELAYED_TRANSPILATION) {
+      precompiledSource = this._debugTree(precompiledSource, `precompiledAddonTree:${type}`);
+
+      let compiledSource = this._compileAddonTree(precompiledSource, options.skipTemplates);
+
+      compiledSource = this._debugTree(compiledSource, `postcompiledAddonTree:${type}`);
+
+      if (options.amdFunnelDisabled) {
+        combinedAddonTree = compiledSource;
+      } else {
+        combinedAddonTree = mergeTrees(addonTrees.concat(compiledSource), {
+          overwrite: true,
+          annotation: `AmdFunnel TreeMerger (${type})`,
+        });
+      }
+    } else {
+      combinedAddonTree = precompiledSource;
+    }
+
+    return new Funnel(combinedAddonTree, {
       destDir: outputDir,
       annotation: `Funnel: ${outputDir} ${type}`,
     });
@@ -1150,7 +1190,7 @@ class EmberApp {
 
   addonTree() {
     if (!this._cachedAddonTree) {
-      this._cachedAddonTree = this.createAddonTree('addon', 'addon-tree-output');
+      this._cachedAddonTree = this._addonTree('addon', 'addon-tree-output');
     }
 
     return this._cachedAddonTree;
@@ -1158,7 +1198,9 @@ class EmberApp {
 
   addonTestSupportTree() {
     if (!this._cachedAddonTestSupportTree) {
-      this._cachedAddonTestSupportTree = this.createAddonTree('addon-test-support', 'addon-test-support');
+      this._cachedAddonTestSupportTree = this._addonTree('addon-test-support', 'addon-test-support', {
+        skipTemplates: true,
+      });
     }
 
     return this._cachedAddonTestSupportTree;
@@ -1166,7 +1208,8 @@ class EmberApp {
 
   addonSrcTree() {
     if (!this._cachedAddonSrcTree) {
-      this._cachedAddonSrcTree = this.createAddonTree('src', 'addon-tree-output', {
+      this._cachedAddonSrcTree = this._addonTree('src', 'addon-tree-output', {
+        amdFunnelDisabled: true,
         moduleNormalizerDisabled: true,
       });
     }
@@ -1582,91 +1625,7 @@ class EmberApp {
     return this._legacyPackager(fullTree);
   }
 
-  _legacyAddonCompile(type, outputDir, _options) {
-    let options = Object.assign(
-      {
-        // moduleNormalizerDisabled: this.options.moduleNormalizerDisabled,
-        amdFunnelDisabled: this.options.amdFunnelDisabled,
-        skipTemplates: false,
-      },
-      _options
-    );
-
-    let addonBundles = this._cachedAddonBundles[type];
-
-    let addonTrees = addonBundles.map(addonBundle => {
-      let { name, tree, root } = addonBundle;
-
-      let precompiledSource = tree;
-
-      if (!options.amdFunnelDisabled) {
-        // don't want to double compile the AMD modules
-        let hasAlreadyPrintedAmdDeprecation;
-        precompiledSource = new AmdFunnel(precompiledSource, {
-          callback: () => {
-            if (!hasAlreadyPrintedAmdDeprecation) {
-              this.project.ui.writeDeprecateLine(`Addon "${name}" (found at "${root}") 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})`,
-        });
-      }
-
-      return [tree, precompiledSource];
-    });
-
-    let precompiledSource = addonTrees.map(pair => pair[1]);
-    addonTrees = addonTrees.map(pair => pair[0]);
-
-    precompiledSource = mergeTrees(precompiledSource, {
-      overwrite: true,
-      annotation: `TreeMerger (${type})`,
-    });
-
-    precompiledSource = this._debugTree(precompiledSource, `precompiledAddonTree:${type}`);
-
-    let compiledSource = this._compileAddonTree(precompiledSource, options.skipTemplates);
-
-    compiledSource = this._debugTree(compiledSource, `postcompiledAddonTree:${type}`);
-
-    let combinedAddonTree;
-
-    if (options.amdFunnelDisabled) {
-      combinedAddonTree = compiledSource;
-    } else {
-      combinedAddonTree = mergeTrees(addonTrees.concat(compiledSource), {
-        overwrite: true,
-        annotation: `AmdFunnel TreeMerger (${type})`,
-      });
-    }
-
-    return new Funnel(combinedAddonTree, {
-      destDir: outputDir,
-      annotation: `Funnel: ${outputDir} ${type}`,
-    });
-  }
-
   _legacyPackager(fullTree) {
-    if (experiments.DELAYED_TRANSPILATION) {
-      fullTree = mergeTrees(
-        [
-          fullTree,
-          this._legacyAddonCompile('addon', 'addon-tree-output'),
-          this._legacyAddonCompile('addon-test-support', 'tests/addon-test-support', {
-            skipTemplates: true,
-          }),
-          this._legacyAddonCompile('src', 'addon-tree-output', {
-            // moduleNormalizerDisabled: true,
-            amdFunnelDisabled: true,
-          }),
-        ],
-        {
-          overwrite: true,
-        }
-      );
-    }
-
     let javascriptTree = this._defaultPackager.packageJavascript(fullTree);
     let stylesTree = this._defaultPackager.packageStyles(fullTree);
     let appIndex = this._defaultPackager.processIndex(fullTree);


Test patch:
diff --git a/tests/unit/broccoli/default-packager/tests-test.js b/tests/unit/broccoli/default-packager/tests-test.js
index 4eebec92e..6748b83c0 100644
--- a/tests/unit/broccoli/default-packager/tests-test.js
+++ b/tests/unit/broccoli/default-packager/tests-test.js
@@ -140,10 +140,6 @@ describe('Default Packager: Tests', function() {
       vendorTestStaticStyles: [],
       legacyTestFilesToAppend: [],
 
-      fingerprint: {
-        exclude: [],
-      },
-
       registry: setupRegistryFor('js', tree => tree),
     });
 
@@ -174,10 +170,6 @@ describe('Default Packager: Tests', function() {
       vendorTestStaticStyles: [],
       legacyTestFilesToAppend: [],
 
-      fingerprint: {
-        exclude: [],
-      },
-
       registry: setupRegistryFor('js', tree => tree),
     });
 
@@ -229,10 +221,6 @@ describe('Default Packager: Tests', function() {
       vendorTestStaticStyles: [],
       legacyTestFilesToAppend: [],
 
-      fingerprint: {
-        exclude: [],
-      },
-
       registry: setupRegistryFor('js', function(tree) {
         return new Funnel(tree, {
           getDestinationPath(relativePath) {
@@ -349,10 +337,6 @@ describe('Default Packager: Tests', function() {
       vendorTestStaticStyles: [],
       legacyTestFilesToAppend: [],
 
-      fingerprint: {
-        exclude: [],
-      },
-
       registry: setupRegistryFor('js', tree => tree),
     });
 
@@ -399,10 +383,6 @@ describe('Default Packager: Tests', function() {
       vendorTestStaticStyles: [],
       legacyTestFilesToAppend: [],
 
-      fingerprint: {
-        exclude: [],
-      },
-
       registry: setupRegistryFor('js', tree => tree),
     });
 
@@ -440,10 +420,6 @@ describe('Default Packager: Tests', function() {
         'vendor/custom/b.js',
       ],
 
-      fingerprint: {
-        exclude: [],
-      },
-
       registry: setupRegistryFor('js', tree => tree),
     });
 
@@ -561,10 +537,6 @@ describe('Default Packager: Tests', function() {
           vendorTestStaticStyles: [],
           legacyTestFilesToAppend: [],
 
-          fingerprint: {
-            exclude: [],
-          },
-
           registry: setupRegistryFor('js', tree => tree),
         });
 
diff --git a/tests/unit/broccoli/ember-app-test.js b/tests/unit/broccoli/ember-app-test.js
index 025ed5cb4..ea8cbfb97 100644
--- a/tests/unit/broccoli/ember-app-test.js
+++ b/tests/unit/broccoli/ember-app-test.js
@@ -173,7 +173,6 @@ describe('EmberApp', function() {
         app.getTests = td.function();
         app.getExternalTree = td.function();
         app.getSrc = td.function();
-        app._legacyAddonCompile = td.function();
         app._defaultPackager = {
           packagePublic: td.function(),
           packageJavascript: td.function(),
@@ -671,6 +670,19 @@ describe('EmberApp', function() {
         expect(app.options.babel.sourceMaps).to.equal('inline');
       });
     });
+
+    describe('options.fingerprint.exclude', function() {
+      it('excludeds testem in fingerprint exclude', function() {
+        let app = new EmberApp({
+          project,
+          fingerprint: {
+            exclude: [],
+          },
+        });
+
+        expect(app.options.fingerprint.exclude).to.include('testem');
+      });
+    });
   });
 
   describe('addons', function() {
diff --git a/tests/unit/broccoli/ember-app/app-and-dependencies-test.js b/tests/unit/broccoli/ember-app/app-and-dependencies-test.js
index da6d809a4..5a80bb370 100644
--- a/tests/unit/broccoli/ember-app/app-and-dependencies-test.js
+++ b/tests/unit/broccoli/ember-app/app-and-dependencies-test.js
@@ -175,7 +175,6 @@ describe('EmberApp#appAndDependencies', function() {
       });
 
       app.addonTree();
-      app._legacyAddonCompile('addon', 'addon-tree-output');
 
       output = yield buildOutput(tree);
       let actualFiles = getFiles(output.path());
@@ -231,9 +230,7 @@ describe('EmberApp#appAndDependencies', function() {
         },
       });
 
-      app.addonTree();
-
-      yield buildOutput(app._legacyAddonCompile('addon', 'addon-tree-output'));
+      yield buildOutput(app.addonTree());
 
       expect(count).to.equal(2);
     }));
@@ -252,9 +249,7 @@ describe('EmberApp#appAndDependencies', function() {
       });
 
       yield co(function *() {
-        app.addonTree();
-
-        output = yield buildOutput(app._legacyAddonCompile('addon', 'addon-tree-output'));
+        output = yield buildOutput(app.addonTree());
       }).catch(e => {
         exceptionMessage = e.message;
       }).then(() => {