Skip to content

Commit 506062c

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 bf9c8f1 commit 506062c

12 files changed

+102
-53
lines changed

packages/angular-cli/commands/build.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ export interface BuildOptions {
1313
aot?: boolean;
1414
sourcemap?: boolean;
1515
vendorChunk?: boolean;
16+
verbose?: boolean;
17+
progress?: boolean;
1618
}
1719

1820
const BuildCommand = Command.extend({
@@ -35,7 +37,9 @@ const BuildCommand = Command.extend({
3537
{ name: 'base-href', type: String, default: null, aliases: ['bh'] },
3638
{ name: 'aot', type: Boolean, default: false },
3739
{ name: 'sourcemap', type: Boolean, default: true, aliases: ['sm'] },
38-
{ name: 'vendor-chunk', type: Boolean, default: true }
40+
{ name: 'vendor-chunk', type: Boolean, default: true },
41+
{ name: 'verbose', type: Boolean, default: false },
42+
{ name: 'progress', type: Boolean, default: true }
3943
],
4044

4145
run: function (commandOptions: BuildOptions) {

packages/angular-cli/commands/serve.ts

+4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ export interface ServeTaskOptions {
2727
sslCert?: string;
2828
aot?: boolean;
2929
sourcemap?: boolean;
30+
verbose?: boolean;
31+
progress?: boolean;
3032
open?: boolean;
3133
vendorChunk?: boolean;
3234
}
@@ -85,6 +87,8 @@ const ServeCommand = Command.extend({
8587
{ name: 'aot', type: Boolean, default: false },
8688
{ name: 'sourcemap', type: Boolean, default: true, aliases: ['sm'] },
8789
{ name: 'vendor-chunk', type: Boolean, default: true },
90+
{ name: 'verbose', type: Boolean, default: false },
91+
{ name: 'progress', type: Boolean, default: true },
8892
{
8993
name: 'open',
9094
type: Boolean,

packages/angular-cli/commands/test.ts

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export interface TestOptions {
1414
reporters?: string;
1515
build?: boolean;
1616
sourcemap?: boolean;
17+
progress?: boolean;
1718
}
1819

1920

@@ -23,6 +24,7 @@ const NgCliTestCommand = TestCommand.extend({
2324
{ name: 'code-coverage', type: Boolean, default: false, aliases: ['cc'] },
2425
{ name: 'lint', type: Boolean, default: false, aliases: ['l'] },
2526
{ name: 'single-run', type: Boolean, default: false, aliases: ['sr'] },
27+
{ name: 'progress', type: Boolean, default: true},
2628
{ name: 'browsers', type: String },
2729
{ name: 'colors', type: Boolean },
2830
{ name: 'log-level', type: String },

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

+5-2
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,15 @@ declare module 'webpack' {
1414
}
1515
}
1616

17-
export const getWebpackProdConfigPartial = function(projectRoot: string, appConfig: any) {
17+
export const getWebpackProdConfigPartial = function(projectRoot: string,
18+
appConfig: any,
19+
verbose: any) {
1820
const appRoot = path.resolve(projectRoot, appConfig.root);
1921
const styles = appConfig.styles
2022
? appConfig.styles.map((style: string) => path.resolve(appRoot, style))
2123
: [];
2224
const cssLoaders = ['css-loader?sourcemap&minimize', 'postcss-loader'];
25+
2326
return {
2427
output: {
2528
path: path.resolve(projectRoot, appConfig.outDir),
@@ -57,7 +60,7 @@ export const getWebpackProdConfigPartial = function(projectRoot: string, appConf
5760
}),
5861
new webpack.optimize.UglifyJsPlugin(<any>{
5962
mangle: { screw_ie8 : true },
60-
compress: { screw_ie8: true },
63+
compress: { screw_ie8: true, warnings: verbose },
6164
sourceMap: true
6265
}),
6366
new CompressionPlugin({

packages/angular-cli/models/webpack-build-test.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@ const webpackLoader = g['angularCliIsLocal']
1010
? g.angularCliPackages['@ngtools/webpack'].main
1111
: '@ngtools/webpack';
1212

13+
const ProgressPlugin = require('webpack/lib/ProgressPlugin');
1314

1415
const getWebpackTestConfig = function (projectRoot, environment, appConfig, testConfig) {
1516

1617
const appRoot = path.resolve(projectRoot, appConfig.root);
17-
const extraRules = [];
18-
const extraPlugins = [];
18+
var extraRules = [];
19+
var extraPlugins = [];
1920

2021
if (testConfig.codeCoverage) {
2122
extraRules.push({
@@ -49,6 +50,10 @@ const getWebpackTestConfig = function (projectRoot, environment, appConfig, test
4950
}))
5051
}
5152

53+
if (testConfig.progress) {
54+
extraPlugins.push(new ProgressPlugin({ colors: true }));
55+
}
56+
5257
return {
5358
devtool: testConfig.sourcemap ? 'inline-source-map' : 'eval',
5459
context: path.resolve(__dirname, './'),

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

+4-3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export class NgCliWebpackConfig {
2626
isAoT = false,
2727
sourcemap = true,
2828
vendorChunk = false,
29+
verbose = false
2930
) {
3031
const config: CliConfig = CliConfig.fromProject();
3132
const appConfig = config.config.apps[0];
@@ -40,7 +41,7 @@ export class NgCliWebpackConfig {
4041
sourcemap,
4142
vendorChunk
4243
);
43-
let targetConfigPartial = this.getTargetConfig(this.ngCliProject.root, appConfig);
44+
let targetConfigPartial = this.getTargetConfig(this.ngCliProject.root, appConfig, verbose);
4445
const typescriptConfigPartial = isAoT
4546
? getWebpackAotConfigPartial(this.ngCliProject.root, appConfig)
4647
: getWebpackNonAotConfigPartial(this.ngCliProject.root, appConfig);
@@ -62,12 +63,12 @@ export class NgCliWebpackConfig {
6263
);
6364
}
6465

65-
getTargetConfig(projectRoot: string, appConfig: any): any {
66+
getTargetConfig(projectRoot: string, appConfig: any, verbose: boolean): any {
6667
switch (this.target) {
6768
case 'development':
6869
return getWebpackDevConfigPartial(projectRoot, appConfig);
6970
case 'production':
70-
return getWebpackProdConfigPartial(projectRoot, appConfig);
71+
return getWebpackProdConfigPartial(projectRoot, appConfig, verbose);
7172
default:
7273
throw new Error("Invalid build target. Only 'development' and 'production' are available.");
7374
}

packages/angular-cli/plugins/karma.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ const init = (config) => {
1313
const testConfig = {
1414
codeCoverage: config.angularCli.codeCoverage || false,
1515
lint: config.angularCli.lint || false,
16-
sourcemap: config.angularCli.sourcemap
16+
sourcemap: config.angularCli.sourcemap,
17+
progress: config.angularCli.progress
1718
}
1819

1920
// add webpack config

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

@@ -26,13 +26,21 @@ export default Task.extend({
2626
runTaskOptions.baseHref,
2727
runTaskOptions.aot,
2828
runTaskOptions.sourcemap,
29-
runTaskOptions.vendorChunk
29+
runTaskOptions.vendorChunk,
30+
runTaskOptions.verbose,
3031
).config;
3132
const webpackCompiler: any = webpack(config);
3233

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

3745
return new Promise((resolve, reject) => {
3846
webpackCompiler.watch({}, (err: any, stats: any) => {
@@ -45,7 +53,7 @@ export default Task.extend({
4553

4654
if (stats.hash !== lastHash) {
4755
lastHash = stats.hash;
48-
process.stdout.write(stats.toString(webpackOutputOptions) + '\n');
56+
process.stdout.write(stats.toString(statsOptions) + '\n');
4957
}
5058
});
5159
});

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

+14-7
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ import * as rimraf from 'rimraf';
22
import * as path from 'path';
33
const Task = require('../ember-cli/lib/models/task');
44
import * as webpack from 'webpack';
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;
@@ -25,16 +26,22 @@ export default <any>Task.extend({
2526
runTaskOptions.baseHref,
2627
runTaskOptions.aot,
2728
runTaskOptions.sourcemap,
28-
runTaskOptions.vendorChunk
29+
runTaskOptions.vendorChunk,
30+
runTaskOptions.verbose
2931
).config;
3032

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

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

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

3946
return new Promise((resolve, reject) => {
4047
webpackCompiler.run((err: any, stats: any) => {
@@ -46,7 +53,7 @@ export default <any>Task.extend({
4653

4754
if (stats.hash !== lastHash) {
4855
lastHash = stats.hash;
49-
process.stdout.write(stats.toString(webpackOutputOptions) + '\n');
56+
process.stdout.write(stats.toString(statsOptions) + '\n');
5057
}
5158

5259
return stats.hasErrors() ? reject() : resolve();

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

+32-23
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,37 +15,44 @@ 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,
30-
commandOptions.sourcemap,
31-
commandOptions.vendorChunk
29+
serveTaskOptions.aot,
30+
serveTaskOptions.sourcemap,
31+
serveTaskOptions.vendorChunk,
32+
serveTaskOptions.verbose
3233
).config;
3334

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

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

4653
let proxyConfig = {};
47-
if (commandOptions.proxyConfig) {
48-
const proxyPath = path.resolve(this.project.root, commandOptions.proxyConfig);
54+
if (serveTaskOptions.proxyConfig) {
55+
const proxyPath = path.resolve(this.project.root, serveTaskOptions.proxyConfig);
4956
if (fs.existsSync(proxyPath)) {
5057
proxyConfig = require(proxyPath);
5158
} else {
@@ -56,12 +63,12 @@ export default Task.extend({
5663

5764
let sslKey: string = null;
5865
let sslCert: string = null;
59-
if (commandOptions.ssl) {
60-
const keyPath = path.resolve(this.project.root, commandOptions.sslKey);
66+
if (serveTaskOptions.ssl) {
67+
const keyPath = path.resolve(this.project.root, serveTaskOptions.sslKey);
6168
if (fs.existsSync(keyPath)) {
6269
sslKey = fs.readFileSync(keyPath, 'utf-8');
6370
}
64-
const certPath = path.resolve(this.project.root, commandOptions.sslCert);
71+
const certPath = path.resolve(this.project.root, serveTaskOptions.sslCert);
6572
if (fs.existsSync(certPath)) {
6673
sslCert = fs.readFileSync(certPath, 'utf-8');
6774
}
@@ -77,14 +84,14 @@ export default Task.extend({
7784
disableDotRule: true,
7885
htmlAcceptHeaders: ['text/html', 'application/xhtml+xml']
7986
},
80-
stats: webpackDevServerOutputOptions,
87+
stats: statsOptions,
8188
inline: true,
8289
proxy: proxyConfig,
83-
compress: commandOptions.target === 'production',
90+
compress: serveTaskOptions.target === 'production',
8491
watchOptions: {
8592
poll: CliConfig.fromProject().config.defaults.poll
8693
},
87-
https: commandOptions.ssl
94+
https: serveTaskOptions.ssl
8895
};
8996

9097
if (sslKey != null && sslCert != null) {
@@ -95,19 +102,21 @@ export default Task.extend({
95102
ui.writeLine(chalk.green(oneLine`
96103
**
97104
NG Live Development Server is running on
98-
http${commandOptions.ssl ? 's' : ''}://${commandOptions.host}:${commandOptions.port}.
105+
http${serveTaskOptions.ssl ? 's' : ''}://${serveTaskOptions.host}:${serveTaskOptions.port}.
99106
**
100107
`));
101108

102109
const server = new WebpackDevServer(webpackCompiler, webpackDevServerConfiguration);
103110
return new Promise((resolve, reject) => {
104-
server.listen(commandOptions.port, `${commandOptions.host}`, function(err: any, stats: any) {
111+
server.listen(serveTaskOptions.port,
112+
`${serveTaskOptions.host}`,
113+
function(err: any, stats: any) {
105114
if (err) {
106115
console.error(err.stack || err);
107116
if (err.details) { console.error(err.details); }
108117
reject(err.details);
109118
} else {
110-
const { open, host, port } = commandOptions;
119+
const { open, host, port } = serveTaskOptions;
111120
if (open) {
112121
opn(url.format({ protocol: 'http', hostname: host, port: port.toString() }));
113122
}

0 commit comments

Comments
 (0)