From cf9f86e74384216dc4e8471e7e31c9b986897ff8 Mon Sep 17 00:00:00 2001
From: Hans Larsen <hans@hansl.ca>
Date: Tue, 7 Aug 2018 21:27:37 -0700
Subject: [PATCH] feat(@angular/cli): add tree shaking of ngDevMode if
 compiling in prod

Whether Ivy is on or not does not matter.
---
 .../models/webpack-configs/common.ts          | 34 ++++++++++++-------
 .../legacy-cli/e2e/tests/experimental/ivy.ts  | 13 ++++---
 2 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/common.ts b/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/common.ts
index 6e371e8256..cab614154b 100644
--- a/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/common.ts
+++ b/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/common.ts
@@ -205,6 +205,9 @@ export function getCommonConfig(wco: WebpackConfigOptions) {
     alias = rxPaths(nodeModules);
   } catch { }
 
+  const isIvyEnabled = wco.tsConfig.raw.angularCompilerOptions
+                    && wco.tsConfig.raw.angularCompilerOptions.enableIvy;
+
   const uglifyOptions = {
     ecma: wco.supportES2015 ? 6 : 5,
     warnings: !!buildOptions.verbose,
@@ -215,20 +218,27 @@ export function getCommonConfig(wco: WebpackConfigOptions) {
       webkit: true,
     },
 
-    // On server, we don't want to compress anything.
-    ...(buildOptions.platform == 'server' ? {} : {
-      compress: {
-        pure_getters: buildOptions.buildOptimizer,
-        // PURE comments work best with 3 passes.
-        // See https://github.com/webpack/webpack/issues/2899#issuecomment-317425926.
-        passes: buildOptions.buildOptimizer ? 3 : 1,
-        // Workaround known uglify-es issue
-        // See https://github.com/mishoo/UglifyJS2/issues/2949#issuecomment-368070307
-        inline: wco.supportES2015 ? 1 : 3,
-      }
+    // On server, we don't want to compress anything. We still set the ngDevMode = false for it
+    // to remove dev code.
+    compress: (buildOptions.platform == 'server' ? {
+      global_defs: {
+        ngDevMode: false,
+      },
+    } : {
+      pure_getters: buildOptions.buildOptimizer,
+      // PURE comments work best with 3 passes.
+      // See https://github.com/webpack/webpack/issues/2899#issuecomment-317425926.
+      passes: buildOptions.buildOptimizer ? 3 : 1,
+      // Workaround known uglify-es issue
+      // See https://github.com/mishoo/UglifyJS2/issues/2949#issuecomment-368070307
+      inline: wco.supportES2015 ? 1 : 3,
+
+      global_defs: {
+        ngDevMode: false,
+      },
     }),
     // We also want to avoid mangling on server.
-    ...(buildOptions.platform == 'server' ? { mangle: false } : {})
+    ...(buildOptions.platform == 'server' ? { mangle: false } : {}),
   };
 
   return {
diff --git a/tests/legacy-cli/e2e/tests/experimental/ivy.ts b/tests/legacy-cli/e2e/tests/experimental/ivy.ts
index 324984a8c8..794b6c7b65 100644
--- a/tests/legacy-cli/e2e/tests/experimental/ivy.ts
+++ b/tests/legacy-cli/e2e/tests/experimental/ivy.ts
@@ -13,7 +13,7 @@ export default async function() {
   try {
     await createProject('ivy-project', '--experimental-ivy');
 
-    await ngServe('--aot');
+    await ngServe('--prod');
 
     // Verify the index.html
     const body = await request('http://localhost:4200/');
@@ -22,12 +22,17 @@ export default async function() {
     }
 
     // Verify it's Ivy.
-    const main = await request('http://localhost:4200/main.js');
-    if (!main.match(/ngComponentDef/)) {
+    const mainUrlMatch = body.match(/src="(main\.[a-z0-9]{0,32}\.js)"/);
+    const mainUrl = mainUrlMatch && mainUrlMatch[1];
+    const main = await request('http://localhost:4200/' + mainUrl);
+
+    if (!main.match(/ngComponentDef\s*=/)) {
       throw new Error('Ivy could not be found.');
     }
+    if (main.match(/ngDevMode/)) {
+      throw new Error('NgDevMode was not tree shaken away.');
+    }
   } finally {
     await killAllProcesses();
   }
 }
-