From 0864edf58aa58e09f594ebd706090c2c2c668f7b Mon Sep 17 00:00:00 2001 From: Hans Larsen Date: Tue, 6 Dec 2016 16:49:16 -0800 Subject: [PATCH] fix(webpack): fix some problems with errors not reported. When analyzing the program or generating code AoT, the plugin was sometimes missing errors. On build, nothing was outputted. Now it will show the error encountered before leaving the process. On serve, hte problem is in webpack-dev-server which does not give us a way to report the error. It seems like webpack-dev-server is not compatible with async plugins, which the @ngtools/webpack is. This is a problem with webpack-dev-server itself. --- packages/@ngtools/webpack/src/plugin.ts | 51 +++++++++++---------- packages/angular-cli/tasks/build-webpack.ts | 17 ++++++- packages/angular-cli/tasks/serve-webpack.ts | 4 +- 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/packages/@ngtools/webpack/src/plugin.ts b/packages/@ngtools/webpack/src/plugin.ts index 2fb79cffad8c..4ac9b891de69 100644 --- a/packages/@ngtools/webpack/src/plugin.ts +++ b/packages/@ngtools/webpack/src/plugin.ts @@ -196,9 +196,11 @@ export class AotPlugin implements Tapable { }); // Virtual file system. - compiler.resolvers.normal.plugin('resolve', (request: any, cb?: () => void) => { + compiler.resolvers.normal.plugin('resolve', (request: any, cb?: (err?: any) => void) => { if (request.request.match(/\.ts$/)) { - this.done.then(() => cb()); + this.done + .then(() => cb()) + .catch((err) => cb(err)); } else { cb(); } @@ -212,9 +214,8 @@ export class AotPlugin implements Tapable { private _make(compilation: any, cb: (err?: any, request?: any) => void) { this._compilation = compilation; - if (this._compilation._ngToolsWebpackPluginInstance) { - cb(new Error('An @ngtools/webpack plugin already exist for this compilation.')); + return cb(new Error('An @ngtools/webpack plugin already exist for this compilation.')); } this._compilation._ngToolsWebpackPluginInstance = this; @@ -227,28 +228,28 @@ export class AotPlugin implements Tapable { basePath: this.basePath }; - let promise = Promise.resolve(); - if (!this._skipCodeGeneration) { - // Create the Code Generator. - const codeGenerator = ngCompiler.CodeGenerator.create( - this._angularCompilerOptions, - i18nOptions, - this._program, - this._compilerHost, - new ngCompiler.NodeReflectorHostContext(this._compilerHost), - this._resourceLoader - ); - - // We need to temporarily patch the CodeGenerator until either it's patched or allows us - // to pass in our own ReflectorHost. - // TODO: remove this. - patchReflectorHost(codeGenerator); - promise = promise.then(() => codeGenerator.codegen({ - transitiveModules: true - })); - } + this._donePromise = Promise.resolve() + .then(() => { + if (this._skipCodeGeneration) { + return; + } - this._donePromise = promise + // Create the Code Generator. + const codeGenerator = ngCompiler.CodeGenerator.create( + this._angularCompilerOptions, + i18nOptions, + this._program, + this._compilerHost, + new ngCompiler.NodeReflectorHostContext(this._compilerHost), + this._resourceLoader + ); + + // We need to temporarily patch the CodeGenerator until either it's patched or allows us + // to pass in our own ReflectorHost. + // TODO: remove this. + patchReflectorHost(codeGenerator); + return codeGenerator.codegen({ transitiveModules: true }); + }) .then(() => { // Create a new Program, based on the old one. This will trigger a resolution of all // transitive modules, which include files that might just have been generated. diff --git a/packages/angular-cli/tasks/build-webpack.ts b/packages/angular-cli/tasks/build-webpack.ts index 770a9befe6e0..d17af6c72964 100644 --- a/packages/angular-cli/tasks/build-webpack.ts +++ b/packages/angular-cli/tasks/build-webpack.ts @@ -7,6 +7,7 @@ import { NgCliWebpackConfig } from '../models/webpack-config'; import { getWebpackStatsConfig } from '../models/'; import { CliConfig } from '../models/config'; + // Configure build and output; let lastHash: any = null; @@ -36,7 +37,9 @@ export default Task.extend({ return new Promise((resolve, reject) => { webpackCompiler.run((err: any, stats: any) => { - if (err) { return reject(err); } + if (err) { + return reject(err); + } // Don't keep cache // TODO: Make conditional if using --watch @@ -47,8 +50,18 @@ export default Task.extend({ process.stdout.write(stats.toString(statsConfig) + '\n'); } - return stats.hasErrors() ? reject() : resolve(); + if (stats.hasErrors()) { + reject(); + } else { + resolve(); + } }); + }) + .catch((err: Error) => { + if (err) { + this.ui.writeError('\nAn error occured during the build:\n' + ((err && err.stack) || err)); + } + throw err; }); } }); diff --git a/packages/angular-cli/tasks/serve-webpack.ts b/packages/angular-cli/tasks/serve-webpack.ts index 99061cc3c8df..c5d8ff615bd0 100644 --- a/packages/angular-cli/tasks/serve-webpack.ts +++ b/packages/angular-cli/tasks/serve-webpack.ts @@ -115,9 +115,7 @@ export default Task.extend({ const server = new WebpackDevServer(webpackCompiler, webpackDevServerConfiguration); return new Promise((resolve, reject) => { - server.listen(serveTaskOptions.port, - `${serveTaskOptions.host}`, - function(err: any, stats: any) { + server.listen(serveTaskOptions.port, `${serveTaskOptions.host}`, (err: any, stats: any) => { if (err) { console.error(err.stack || err); if (err.details) { console.error(err.details); }