Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(webpack-cli): stats #1299

Merged
merged 7 commits into from
Mar 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ install:
- lerna bootstrap
- yarn global add codecov
- yarn global add eslint
- yarn prepsuite
script:
- yarn travis:lint
- yarn test:ci
Expand Down
3 changes: 3 additions & 0 deletions packages/webpack-cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Options
-h, --hot Enables Hot Module Replacement
-s, --sourcemap string Determine source maps to use
--prefetch string Prefetch this request
--pretty Prints a fancy output
-j, --json Prints result as JSON
--standard Prints standard output
-d, --dev Run development build
Expand All @@ -58,6 +59,8 @@ Options
--no-mode Sets mode="none" which disables any default behavior
--version Get current version
--node-args string[] NodeJS flags
--stats type It instructs webpack on how to treat the stats
--verbose It tells webpack to output all the information
```

## Defaults
Expand Down
18 changes: 18 additions & 0 deletions packages/webpack-cli/__tests__/StatsGroup.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const StatsGroup = require('../lib/groups/StatsGroup');

describe('StatsGroup', function() {
{
StatsGroup.validOptions().map(option => {
it(`should handle ${option} option`, () => {
const statsGroup = new StatsGroup([
{
stats: option,
},
]);

const result = statsGroup.run();
expect(result.options.stats).toEqual(option);
});
});
}
});
27 changes: 21 additions & 6 deletions packages/webpack-cli/lib/groups/StatsGroup.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,36 @@
const GroupHelper = require('../utils/GroupHelper');

const { logger } = require('@webpack-cli/logger');
/**
* StatsGroup gathers information about the stats options
*/
class StatsGroup extends GroupHelper {
static validOptions() {
return ['minimal', 'none', 'normal', 'verbose', 'errors-warnings', 'errors-only'];
}

constructor(options) {
super(options);
}

resolveOptions() {
Object.keys(this.args).forEach(arg => {
if (['quiet', 'verbose', 'json', 'silent', 'standard'].includes(arg)) {
this.opts.outputOptions[arg] = this.args[arg];
if (this.args.verbose && this.args.stats) {
logger.warn('Conflict between "verbose" and "stats" options. Using verbose.');
this.opts.option.stats = {
verbose: true,
};
} else {
if (this.args.verbose) {
this.opts.option.stats = {
verbose: true,
};
} else {
this.opts.options[arg] = this.args[arg];
this.opts.options.stats = this.args.stats;
}
});
}

if (this.args.pretty) {
this.opts.outputOptions.pretty = true;
}
}

run() {
Expand Down
6 changes: 3 additions & 3 deletions packages/webpack-cli/lib/utils/Compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,7 @@ class Compiler {
}

generateOutput(outputOptions, stats, statsErrors, processingMessageBuffer) {
if (outputOptions.standard) {
this.output.generateRawOutput(stats);
} else {
if (outputOptions.pretty) {
const statsObj = stats.toJson(outputOptions);
if (statsObj.children && Array.isArray(statsObj.children) && this.compilerOptions && Array.isArray(this.compilerOptions)) {
statsObj.children.forEach(child => {
Expand All @@ -89,6 +87,8 @@ class Compiler {
return;
}
this.output.generateFancyOutput(statsObj, statsErrors, processingMessageBuffer);
} else {
this.output.generateRawOutput(stats, this.compilerOptions);
}
process.stdout.write('\n');
if (outputOptions.watch) {
Expand Down
4 changes: 2 additions & 2 deletions packages/webpack-cli/lib/utils/CompilerOutput.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ class CompilerOutput {
return statsObj;
}

generateRawOutput(stats) {
process.stdout.write(stats.toString());
generateRawOutput(stats, options) {
process.stdout.write(stats.toString(options.stats));
}

generateJsonOutput() {}
Expand Down
33 changes: 28 additions & 5 deletions packages/webpack-cli/lib/utils/cli-flags.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
const { logger } = require('@webpack-cli/logger');
const StatsGroup = require('../groups/StatsGroup');

const HELP_GROUP = 'help';
const CONFIG_GROUP = 'config';
const BASIC_GROUP = 'basic';
Expand Down Expand Up @@ -243,25 +245,25 @@ module.exports = {
},
{
name: 'prefetch',
usage: '--prefetch <request>',
usage: 'webpack --prefetch <request>',
type: String,
group: ADVANCED_GROUP,
description: 'Prefetch this request',
link: 'https://webpack.js.org/plugins/prefetch-plugin/',
},
{
name: 'json',
usage: '--json',
usage: 'webpack --json',
type: Boolean,
alias: 'j',
description: 'Prints result as JSON',
group: DISPLAY_GROUP,
},
{
name: 'standard',
usage: '--standard',
name: 'pretty',
usage: 'webpack --pretty',
type: Boolean,
description: 'Prints standard output',
description: 'Prints a fancy output',
group: DISPLAY_GROUP,
},
{
Expand Down Expand Up @@ -322,6 +324,27 @@ module.exports = {
group: BASIC_GROUP,
description: 'NodeJS flags',
},
{
name: 'stats',
usage: 'webpack --stats verbose',
type: value => {
if (StatsGroup.validOptions().includes(value)) {
return value;
}
logger.warn('No value recognised for "stats" option');
return 'normal';
},
group: DISPLAY_GROUP,
description: 'It instructs webpack on how to treat the stats',
link: 'https://webpack.js.org/configuration/stats/#stats',
},
{
name: 'verbose',
usage: 'webpack --verbose',
type: Boolean,
group: DISPLAY_GROUP,
description: 'It tells webpack to output all the information',
},
/* {
name: "analyze",
type: Boolean,
Expand Down
10 changes: 10 additions & 0 deletions test/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": ["eslint:recommended", "plugin:node/recommended", "plugin:prettier/recommended"],
"env": {
"node": true,
"es6": true,
"jest": true
},
"plugins": ["node", "prettier"],
"parserOptions": { "ecmaVersion": 2020, "sourceType": "module" }
}
11 changes: 2 additions & 9 deletions test/config-lookup/dotfolder-array/dotfolder-array.test.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
'use strict';
const { stat } = require('fs');
const { resolve, sep } = require('path');
const { run, extractSummary } = require('../../utils/test-utils');
const { resolve } = require('path');
const { run } = require('../../utils/test-utils');

describe('dotfolder array config lookup', () => {
it('should find a webpack array configuration in a dotfolder', done => {
const { stdout, stderr } = run(__dirname, [], false);
expect(stderr).not.toBeUndefined();
expect(stdout).not.toBeUndefined();

const summary = extractSummary(stdout);
const outputDir = 'config-lookup/dotfolder-array/dist';
const outDirectoryFromCompiler = summary['Output Directory'].split(sep);
const outDirToMatch = outDirectoryFromCompiler
.slice(outDirectoryFromCompiler.length - 3, outDirectoryFromCompiler.length)
.join('/');
expect(outDirToMatch).toContain(outputDir);
stat(resolve(__dirname, './dist/dist-commonjs.js'), (err, stats) => {
expect(err).toBe(null);
expect(stats.isFile()).toBe(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,15 @@
const { stat } = require('fs');
const { resolve } = require('path');

const { run, extractSummary } = require('../../utils/test-utils');
const { run } = require('../../utils/test-utils');

describe('dotfolder single config lookup', () => {
it('should find a webpack configuration in a dotfolder', done => {
const { stdout, stderr } = run(__dirname, [], false);
expect(stderr).not.toBeUndefined();
expect(stdout).not.toBeUndefined();

const summary = extractSummary(stdout);
const outputDir = 'config-lookup/dotfolder-single/dist';

expect(summary['Output Directory']).toContain(outputDir);
expect(stderr).not.toContain('Module not found');
expect(stdout).not.toContain('Module not found');
stat(resolve(__dirname, './dist/main.js'), (err, stats) => {
expect(err).toBe(null);
expect(stats.isFile()).toBe(true);
Expand Down
11 changes: 2 additions & 9 deletions test/config/basic/basic-config.test.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
'use strict';
const { stat } = require('fs');
const { resolve, sep } = require('path');
const { run, extractSummary } = require('../../utils/test-utils');
const { resolve } = require('path');
const { run } = require('../../utils/test-utils');

describe('basic config file', () => {
it('is able to understand and parse a very basic configuration file', done => {
const { stdout, stderr } = run(__dirname, ['-c', resolve(__dirname, 'webpack.config.js'), '--output', './binary/a.bundle.js']);
expect(stderr).toContain('Duplicate flags found, defaulting to last set value');
expect(stdout).not.toBe(undefined);
const summary = extractSummary(stdout);
const outputDir = 'basic/binary';
const outDirectoryFromCompiler = summary['Output Directory'].split(sep);
const outDirToMatch = outDirectoryFromCompiler
.slice(outDirectoryFromCompiler.length - 2, outDirectoryFromCompiler.length)
.join('/');
expect(outDirToMatch).toContain(outputDir);
stat(resolve(__dirname, './binary/a.bundle.js'), (err, stats) => {
expect(err).toBe(null);
expect(stats.isFile()).toBe(true);
Expand Down
14 changes: 4 additions & 10 deletions test/config/empty/empty-config.test.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
'use strict';
const { resolve, sep } = require('path');
const { run, extractSummary } = require('../../utils/test-utils');
const { resolve } = require('path');
const { run } = require('../../utils/test-utils');

describe('config flag with empty config file', () => {
it('should throw error with no configuration or index file', () => {
const { stdout, stderr } = run(__dirname, ['-c', resolve(__dirname, 'webpack.config.js')]);
const summary = extractSummary(stdout);
const outputDir = 'empty/bin';
const outDirectoryFromCompiler = summary['Output Directory'].split(sep);
const outDirToMatch = outDirectoryFromCompiler
.slice(outDirectoryFromCompiler.length - 2, outDirectoryFromCompiler.length)
.join('/');
expect(outDirToMatch).toContain(outputDir);
expect(stderr).toBeTruthy();
expect(stderr).toBeFalsy();
expect(stdout).toBeTruthy();
});
});
13 changes: 3 additions & 10 deletions test/config/type/array/array-config.test.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
'use strict';
const { stat } = require('fs');
const { resolve, sep } = require('path');
const { run, extractSummary } = require('../../../utils/test-utils');
const { resolve } = require('path');
const { run } = require('../../../utils/test-utils');

describe('array configuration', () => {
it('is able to understand a configuration file in array format', done => {
const { stdout } = run(__dirname, ['-c', resolve(__dirname, 'webpack.config.js')], false);
const summary = extractSummary(stdout);
const outputDir = 'type/array/dist';
const outDirectoryFromCompiler = summary['Output Directory'].split(sep);
const outDirToMatch = outDirectoryFromCompiler
.slice(outDirectoryFromCompiler.length - 3, outDirectoryFromCompiler.length)
.join('/');
expect(outDirToMatch).toContain(outputDir);
run(__dirname, ['-c', resolve(__dirname, 'webpack.config.js')], false);
stat(resolve(__dirname, './dist/dist-commonjs.js'), (err, stats) => {
expect(err).toBe(null);
expect(stats.isFile()).toBe(true);
Expand Down
13 changes: 3 additions & 10 deletions test/config/type/function/function-config.test.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
'use strict';
const { stat } = require('fs');
const { resolve, sep } = require('path');
const { run, extractSummary } = require('../../../utils/test-utils');
const { resolve } = require('path');
const { run } = require('../../../utils/test-utils');

describe('function configuration', () => {
it('is able to understand a configuration file as a function', done => {
const { stdout } = run(__dirname, ['-c', resolve(__dirname, 'webpack.config.js')], false);
const summary = extractSummary(stdout);
const outputDir = 'type/function/binary';
const outDirectoryFromCompiler = summary['Output Directory'].split(sep);
const outDirToMatch = outDirectoryFromCompiler
.slice(outDirectoryFromCompiler.length - 3, outDirectoryFromCompiler.length)
.join('/');
expect(outDirToMatch).toContain(outputDir);
run(__dirname, ['-c', resolve(__dirname, 'webpack.config.js')], false);
stat(resolve(__dirname, './binary/functor.js'), (err, stats) => {
expect(err).toBe(null);
expect(stats.isFile()).toBe(true);
Expand Down
21 changes: 5 additions & 16 deletions test/defaults/output-defaults.test.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
'use strict';
const { stat } = require('fs');
const { resolve } = require('path');
const { run, extractSummary } = require('../utils/test-utils');
const { run } = require('../utils/test-utils');

describe('output flag defaults', () => {
it('should create default file for a given directory', done => {
const { stdout } = run(__dirname, ['--entry', './a.js', '--output', './binary'], false);
const summary = extractSummary(stdout);
const outputDir = 'defaults/binary';

expect(summary['Output Directory']).toContain(outputDir);
run(__dirname, ['--entry', './a.js', '--output', './binary'], false);

stat(resolve(__dirname, './binary/main.js'), (err, stats) => {
expect(err).toBe(null);
Expand All @@ -18,27 +14,20 @@ describe('output flag defaults', () => {
});
});
it('set default output directory on empty flag', done => {
const { stdout, stderr } = run(__dirname, ['--entry', './a.js', '--output'], false);
const { stdout } = run(__dirname, ['--entry', './a.js', '--output'], false);
// Should print a warning about config fallback since we did not supply --defaults
expect(stderr).toContain('option has not been set, webpack will fallback to');
const summary = extractSummary(stdout);

const outputDir = 'defaults/dist';
expect(stdout).toContain('option has not been set, webpack will fallback to');

expect(summary['Output Directory']).toContain(outputDir);
stat(resolve(__dirname, './dist/main.js'), (err, stats) => {
expect(err).toBe(null);
expect(stats.isFile()).toBe(true);
done();
});
});
it('should not throw when --defaults flag is passed', done => {
const { stdout, stderr } = run(__dirname, ['--defaults'], false);
const summary = extractSummary(stdout);
const outputDir = 'defaults/dist';
const { stderr } = run(__dirname, ['--defaults'], false);
// When using --defaults it should not print warnings about config fallback
expect(stderr).toBeFalsy();
expect(summary['Output Directory']).toContain(outputDir);
stat(resolve(__dirname, './dist/main.js'), (err, stats) => {
expect(err).toBe(null);
expect(stats.isFile()).toBe(true);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
'use strict';
const { stat } = require('fs');
const { resolve } = require('path');
const { run, extractSummary } = require('../../utils/test-utils');
const { run } = require('../../utils/test-utils');

describe('output flag defaults without config', () => {
it('should throw if the entry file is not present', done => {
const { stdout, stderr } = run(__dirname, ['--defaults'], false);
const summary = extractSummary(stdout);
const outputDir = 'without-config-and-entry/dist';
// eslint-disable-next-line quotes
expect(stderr).toContain("Error: Can't resolve './index.js' in");
expect(summary['Output Directory']).toContain(outputDir);
const { stdout } = run(__dirname, ['--defaults'], false);

expect(stdout).toContain("Error: Can't resolve './index.js' in");
stat(resolve(__dirname, './dist/main.js'), (err, stats) => {
expect(err).toBeTruthy();
expect(stats).toBe(undefined);
Expand Down
Loading