Skip to content

Commit f9b5b8b

Browse files
committed
feat(build): add --verbose and --progress flags
Currently builds output a lot of information, some of which can hide errors, by default. This PR cuts down on the information shown and adds a `--verbose` flag to restore previous build output. A `--progress` flag is also present to turn off progress logging in CI environments. Fix angular#1836 Fix angular#2012
1 parent 86021a0 commit f9b5b8b

File tree

8 files changed

+88
-49
lines changed

8 files changed

+88
-49
lines changed

packages/angular-cli/commands/build.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ export interface BuildOptions {
1111
supressSizes: boolean;
1212
baseHref?: string;
1313
aot?: boolean;
14+
verbose?: boolean;
15+
progress?: boolean;
1416
}
1517

1618
const BuildCommand = Command.extend({
@@ -31,7 +33,9 @@ const BuildCommand = Command.extend({
3133
{ name: 'watcher', type: String },
3234
{ name: 'suppress-sizes', type: Boolean, default: false },
3335
{ name: 'base-href', type: String, default: null, aliases: ['bh'] },
34-
{ name: 'aot', type: Boolean, default: false }
36+
{ name: 'aot', type: Boolean, default: false },
37+
{ name: 'verbose', type: Boolean, default: false },
38+
{ name: 'progress', type: Boolean, default: true }
3539
],
3640

3741
run: function (commandOptions: BuildOptions) {

packages/angular-cli/commands/serve.ts

+4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ export interface ServeTaskOptions {
2626
sslKey?: string;
2727
sslCert?: string;
2828
aot?: boolean;
29+
verbose?: boolean;
30+
progress?: boolean;
2931
open?: boolean;
3032
}
3133

@@ -81,6 +83,8 @@ const ServeCommand = Command.extend({
8183
{ name: 'ssl-key', type: String, default: 'ssl/server.key' },
8284
{ name: 'ssl-cert', type: String, default: 'ssl/server.crt' },
8385
{ name: 'aot', type: Boolean, default: false },
86+
{ name: 'verbose', type: Boolean, default: false },
87+
{ name: 'progress', type: Boolean, default: true },
8488
{
8589
name: 'open',
8690
type: Boolean,

packages/angular-cli/models/webpack-build-production.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ declare module 'webpack' {
1313
}
1414
}
1515

16-
export const getWebpackProdConfigPartial = function(projectRoot: string, appConfig: any) {
16+
export const getWebpackProdConfigPartial = function(projectRoot: string,
17+
appConfig: any,
18+
verbose: any) {
1719
return {
1820
devtool: 'source-map',
1921
output: {
@@ -29,7 +31,7 @@ export const getWebpackProdConfigPartial = function(projectRoot: string, appConf
2931
}),
3032
new webpack.optimize.UglifyJsPlugin(<any>{
3133
mangle: { screw_ie8 : true },
32-
compress: { screw_ie8: true },
34+
compress: { screw_ie8: true, warnings: verbose },
3335
sourceMap: true
3436
}),
3537
new CompressionPlugin({

packages/angular-cli/models/webpack-build-utils.ts

+11-7
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,22 @@ export const ngAppResolve = (resolvePath: string): string => {
66

77
export const webpackOutputOptions = {
88
colors: true,
9+
hash: true,
10+
timings: true,
911
chunks: true,
12+
chunkModules: false,
13+
children: false, // listing all children is very noisy in AOT and hides warnings/errors
1014
modules: false,
1115
reasons: false,
12-
chunkModules: false
16+
warnings: true,
17+
assets: false, // listing all assets is very noisy when using assets directories
18+
version: false
1319
};
1420

15-
export const webpackDevServerOutputOptions = {
21+
export const verboseWebpackOutputOptions = {
22+
children: true,
1623
assets: true,
17-
colors: true,
1824
version: true,
19-
hash: true,
20-
timings: true,
21-
chunks: false,
22-
chunkModules: false
25+
reasons: true,
26+
chunkModules: false // TODO: set to true when console to file output is fixed
2327
};

packages/angular-cli/models/webpack-config.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ export class NgCliWebpackConfig {
2323
public environment: string,
2424
outputDir?: string,
2525
baseHref?: string,
26-
isAoT = false
26+
isAoT = false,
27+
verbose = false
2728
) {
2829
const config: CliConfig = CliConfig.fromProject();
2930
const appConfig = config.config.apps[0];
@@ -36,7 +37,7 @@ export class NgCliWebpackConfig {
3637
appConfig,
3738
baseHref
3839
);
39-
let targetConfigPartial = this.getTargetConfig(this.ngCliProject.root, appConfig);
40+
let targetConfigPartial = this.getTargetConfig(this.ngCliProject.root, appConfig, verbose);
4041
const typescriptConfigPartial = isAoT
4142
? getWebpackAotConfigPartial(this.ngCliProject.root, appConfig)
4243
: getWebpackNonAotConfigPartial(this.ngCliProject.root, appConfig);
@@ -58,12 +59,12 @@ export class NgCliWebpackConfig {
5859
);
5960
}
6061

61-
getTargetConfig(projectRoot: string, appConfig: any): any {
62+
getTargetConfig(projectRoot: string, appConfig: any, verbose: boolean): any {
6263
switch (this.target) {
6364
case 'development':
6465
return getWebpackDevConfigPartial(projectRoot, appConfig);
6566
case 'production':
66-
return getWebpackProdConfigPartial(projectRoot, appConfig);
67+
return getWebpackProdConfigPartial(projectRoot, appConfig, verbose);
6768
default:
6869
throw new Error("Invalid build target. Only 'development' and 'production' are available.");
6970
}

packages/angular-cli/tasks/build-webpack-watch.ts

+14-6
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const Task = require('ember-cli/lib/models/task');
44
import * as webpack from 'webpack';
55
const ProgressPlugin = require('webpack/lib/ProgressPlugin');
66
import { NgCliWebpackConfig } from '../models/webpack-config';
7-
import { webpackOutputOptions } from '../models/';
7+
import { webpackOutputOptions, verboseWebpackOutputOptions } from '../models/';
88
import { BuildOptions } from '../commands/build';
99
import { CliConfig } from '../models/config';
1010

@@ -24,13 +24,21 @@ export default Task.extend({
2424
runTaskOptions.environment,
2525
outputDir,
2626
runTaskOptions.baseHref,
27-
runTaskOptions.aot
27+
runTaskOptions.aot,
28+
runTaskOptions.verbose
2829
).config;
2930
const webpackCompiler: any = webpack(config);
3031

31-
webpackCompiler.apply(new ProgressPlugin({
32-
profile: true
33-
}));
32+
const statsOptions = runTaskOptions.verbose
33+
? Object.assign(webpackOutputOptions, verboseWebpackOutputOptions)
34+
: webpackOutputOptions;
35+
36+
if (runTaskOptions.progress) {
37+
webpackCompiler.apply(new ProgressPlugin({
38+
profile: runTaskOptions.verbose,
39+
colors: true
40+
}));
41+
}
3442

3543
return new Promise((resolve, reject) => {
3644
webpackCompiler.watch({}, (err: any, stats: any) => {
@@ -43,7 +51,7 @@ export default Task.extend({
4351

4452
if (stats.hash !== lastHash) {
4553
lastHash = stats.hash;
46-
process.stdout.write(stats.toString(webpackOutputOptions) + '\n');
54+
process.stdout.write(stats.toString(statsOptions) + '\n');
4755
}
4856
});
4957
});

packages/angular-cli/tasks/build-webpack.ts

+15-8
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import * as rimraf from 'rimraf';
22
import * as path from 'path';
3-
const Task = require('ember-cli/lib/models/task');
43
import * as webpack from 'webpack';
4+
const Task = require('ember-cli/lib/models/task');
5+
const ProgressPlugin = require('webpack/lib/ProgressPlugin');
56
import { BuildOptions } from '../commands/build';
67
import { NgCliWebpackConfig } from '../models/webpack-config';
7-
import { webpackOutputOptions } from '../models/';
8+
import { webpackOutputOptions, verboseWebpackOutputOptions } from '../models/';
89
import { CliConfig } from '../models/config';
910

1011
// Configure build and output;
@@ -23,19 +24,25 @@ export default <any>Task.extend({
2324
runTaskOptions.environment,
2425
outputDir,
2526
runTaskOptions.baseHref,
26-
runTaskOptions.aot
27+
runTaskOptions.aot,
28+
runTaskOptions.verbose
2729
).config;
2830

2931
// fail on build error
3032
config.bail = true;
3133

3234
const webpackCompiler: any = webpack(config);
3335

34-
const ProgressPlugin = require('webpack/lib/ProgressPlugin');
36+
const statsOptions = runTaskOptions.verbose
37+
? Object.assign(webpackOutputOptions, verboseWebpackOutputOptions)
38+
: webpackOutputOptions;
3539

36-
webpackCompiler.apply(new ProgressPlugin({
37-
profile: true
38-
}));
40+
if (runTaskOptions.progress) {
41+
webpackCompiler.apply(new ProgressPlugin({
42+
profile: runTaskOptions.verbose,
43+
colors: true
44+
}));
45+
}
3946

4047
return new Promise((resolve, reject) => {
4148
webpackCompiler.run((err: any, stats: any) => {
@@ -51,7 +58,7 @@ export default <any>Task.extend({
5158

5259
if (stats.hash !== lastHash) {
5360
lastHash = stats.hash;
54-
process.stdout.write(stats.toString(webpackOutputOptions) + '\n');
61+
process.stdout.write(stats.toString(statsOptions) + '\n');
5562
}
5663
resolve();
5764
});

packages/angular-cli/tasks/serve-webpack.ts

+30-21
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const Task = require('ember-cli/lib/models/task');
66
import * as webpack from 'webpack';
77
const WebpackDevServer = require('webpack-dev-server');
88
const ProgressPlugin = require('webpack/lib/ProgressPlugin');
9-
import { webpackDevServerOutputOptions } from '../models/';
9+
import { webpackOutputOptions, verboseWebpackOutputOptions } from '../models/';
1010
import { NgCliWebpackConfig } from '../models/webpack-config';
1111
import { ServeTaskOptions } from '../commands/serve';
1212
import { CliConfig } from '../models/config';
@@ -15,35 +15,42 @@ import * as url from 'url';
1515
const opn = require('opn');
1616

1717
export default Task.extend({
18-
run: function(commandOptions: ServeTaskOptions) {
18+
run: function(serveTaskOptions: ServeTaskOptions) {
1919
const ui = this.ui;
2020

2121
let webpackCompiler: any;
2222

2323
let config = new NgCliWebpackConfig(
2424
this.project,
25-
commandOptions.target,
26-
commandOptions.environment,
25+
serveTaskOptions.target,
26+
serveTaskOptions.environment,
2727
undefined,
2828
undefined,
29-
commandOptions.aot
29+
serveTaskOptions.aot,
30+
serveTaskOptions.verbose
3031
).config;
3132

3233
// This allows for live reload of page when changes are made to repo.
3334
// https://webpack.github.io/docs/webpack-dev-server.html#inline-mode
3435
config.entry.main.unshift(
35-
`webpack-dev-server/client?http://${commandOptions.host}:${commandOptions.port}/`
36+
`webpack-dev-server/client?http://${serveTaskOptions.host}:${serveTaskOptions.port}/`
3637
);
3738
webpackCompiler = webpack(config);
3839

39-
webpackCompiler.apply(new ProgressPlugin({
40-
profile: true,
41-
colors: true
42-
}));
40+
const statsOptions = serveTaskOptions.verbose
41+
? Object.assign(webpackOutputOptions, verboseWebpackOutputOptions)
42+
: webpackOutputOptions;
43+
44+
if (serveTaskOptions.progress) {
45+
webpackCompiler.apply(new ProgressPlugin({
46+
profile: serveTaskOptions.verbose,
47+
colors: true
48+
}));
49+
}
4350

4451
let proxyConfig = {};
45-
if (commandOptions.proxyConfig) {
46-
const proxyPath = path.resolve(this.project.root, commandOptions.proxyConfig);
52+
if (serveTaskOptions.proxyConfig) {
53+
const proxyPath = path.resolve(this.project.root, serveTaskOptions.proxyConfig);
4754
if (fs.existsSync(proxyPath)) {
4855
proxyConfig = require(proxyPath);
4956
} else {
@@ -54,12 +61,12 @@ export default Task.extend({
5461

5562
let sslKey: string = null;
5663
let sslCert: string = null;
57-
if (commandOptions.ssl) {
58-
const keyPath = path.resolve(this.project.root, commandOptions.sslKey);
64+
if (serveTaskOptions.ssl) {
65+
const keyPath = path.resolve(this.project.root, serveTaskOptions.sslKey);
5966
if (fs.existsSync(keyPath)) {
6067
sslKey = fs.readFileSync(keyPath, 'utf-8');
6168
}
62-
const certPath = path.resolve(this.project.root, commandOptions.sslCert);
69+
const certPath = path.resolve(this.project.root, serveTaskOptions.sslCert);
6370
if (fs.existsSync(certPath)) {
6471
sslCert = fs.readFileSync(certPath, 'utf-8');
6572
}
@@ -73,14 +80,14 @@ export default Task.extend({
7380
historyApiFallback: {
7481
disableDotRule: true,
7582
},
76-
stats: webpackDevServerOutputOptions,
83+
stats: statsOptions,
7784
inline: true,
7885
proxy: proxyConfig,
79-
compress: commandOptions.target === 'production',
86+
compress: serveTaskOptions.target === 'production',
8087
watchOptions: {
8188
poll: CliConfig.fromProject().config.defaults.poll
8289
},
83-
https: commandOptions.ssl
90+
https: serveTaskOptions.ssl
8491
};
8592

8693
if (sslKey != null && sslCert != null) {
@@ -91,19 +98,21 @@ export default Task.extend({
9198
ui.writeLine(chalk.green(oneLine`
9299
**
93100
NG Live Development Server is running on
94-
http${commandOptions.ssl ? 's' : ''}://${commandOptions.host}:${commandOptions.port}.
101+
http${serveTaskOptions.ssl ? 's' : ''}://${serveTaskOptions.host}:${serveTaskOptions.port}.
95102
**
96103
`));
97104

98105
const server = new WebpackDevServer(webpackCompiler, webpackDevServerConfiguration);
99106
return new Promise((resolve, reject) => {
100-
server.listen(commandOptions.port, `${commandOptions.host}`, function(err: any, stats: any) {
107+
server.listen(serveTaskOptions.port,
108+
`${serveTaskOptions.host}`,
109+
function(err: any, stats: any) {
101110
if (err) {
102111
console.error(err.stack || err);
103112
if (err.details) { console.error(err.details); }
104113
reject(err.details);
105114
} else {
106-
const { open, host, port } = commandOptions;
115+
const { open, host, port } = serveTaskOptions;
107116
if (open) {
108117
opn(url.format({ protocol: 'http', hostname: host, port: port.toString() }));
109118
}

0 commit comments

Comments
 (0)