Skip to content

Commit

Permalink
feat: allow users to store stats as json to a file (#1835)
Browse files Browse the repository at this point in the history
  • Loading branch information
snitin315 committed Oct 3, 2020
1 parent 6f49e96 commit 3907517
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 27 deletions.
44 changes: 22 additions & 22 deletions packages/webpack-cli/README.md
Expand Up @@ -36,28 +36,28 @@ yarn add webpack-cli --dev
### webpack 4

```
--entry string[] The entry point(s) of your application.
-c, --config string[] Provide path to webpack configuration file(s)
--config-name string[] Name of the configuration to use
-m, --merge Merge several configurations using webpack-merge
--progress Print compilation progress during build
--color Enables colors on console
--no-color Disable colors on console
--env string Environment passed to the configuration when it is a function
--name string Name of the configuration. Used when loading multiple configurations
--help Outputs list of supported flags
-o, --output string Output location of the file generated by webpack
-t, --target string Sets the build target
-w, --watch Watch for files changes
-h, --hot Enables Hot Module Replacement
--no-hot Disables Hot Module Replacement
-d, --devtool string Controls if and how source maps are generated.
--prefetch string Prefetch this request
-j, --json Prints result as JSON
--mode string Defines the mode to pass to webpack
-v, --version Get current version
--stats string It instructs webpack on how to treat the stats
--no-stats Disables stats output
--entry string[] The entry point(s) of your application.
-c, --config string[] Provide path to webpack configuration file(s)
--config-name string[] Name of the configuration to use
-m, --merge Merge several configurations using webpack-merge
--progress Print compilation progress during build
--color Enables colors on console
--no-color Disable colors on console
--env string Environment passed to the configuration when it is a function
--name string Name of the configuration. Used when loading multiple configurations
--help Outputs list of supported flags
-o, --output string Output location of the file generated by webpack
-t, --target string Sets the build target
-w, --watch Watch for files changes
-h, --hot Enables Hot Module Replacement
--no-hot Disables Hot Module Replacement
-d, --devtool string Controls if and how source maps are generated.
--prefetch string Prefetch this request
-j, --json string, boolean Prints result as JSON or store it in a file
--mode string Defines the mode to pass to webpack
-v, --version Get current version
--stats string, boolean It instructs webpack on how to treat the stats
--no-stats Disables stats output
```

### webpack 5
Expand Down
2 changes: 1 addition & 1 deletion packages/webpack-cli/lib/groups/resolveStats.js
Expand Up @@ -14,7 +14,7 @@ const resolveStats = (args) => {
finalOptions.options.stats = stats;
}
if (json) {
finalOptions.outputOptions.json = true;
finalOptions.outputOptions.json = json;
}
return finalOptions;
};
Expand Down
12 changes: 11 additions & 1 deletion packages/webpack-cli/lib/utils/Compiler.js
@@ -1,6 +1,7 @@
const { packageExists } = require('@webpack-cli/package-utils');
const webpack = packageExists('webpack') ? require('webpack') : undefined;
const logger = require('./logger');
const { writeFileSync } = require('fs');
const bailAndWatchWarning = require('./warnings/bailAndWatchWarning');
const { CompilerOutput } = require('./CompilerOutput');

Expand Down Expand Up @@ -58,7 +59,7 @@ class Compiler {
if (!outputOptions.watch && (stats.hasErrors() || stats.hasWarnings())) {
process.exitCode = 1;
}
if (outputOptions.json) {
if (outputOptions.json === true) {
process.stdout.write(JSON.stringify(stats.toJson(outputOptions), null, 2) + '\n');
} else if (stats.hash !== lastHash) {
lastHash = stats.hash;
Expand All @@ -69,6 +70,15 @@ class Compiler {
statsErrors.push({ name: statErr.message, loc: errLoc });
});
}
const JSONStats = JSON.stringify(stats.toJson(outputOptions), null, 2);
if (typeof outputOptions.json === 'string') {
try {
writeFileSync(outputOptions.json, JSONStats);
logger.info(`stats are successfully stored as json to ${outputOptions.json}`);
} catch (err) {
logger.error(err);
}
}
return this.generateOutput(outputOptions, stats, statsErrors);
}
}
Expand Down
4 changes: 2 additions & 2 deletions packages/webpack-cli/lib/utils/cli-flags.js
Expand Up @@ -174,9 +174,9 @@ const core = [
{
name: 'json',
usage: '--json',
type: Boolean,
type: [String, Boolean],
alias: 'j',
description: 'Prints result as JSON',
description: 'Prints result as JSON or store it in a file',
},
{
name: 'mode',
Expand Down
2 changes: 1 addition & 1 deletion scripts/cleanupTest.js
Expand Up @@ -3,7 +3,7 @@ const rimraf = require('rimraf');
const { join } = require('path');
const collectTestFolders = require('./utils');

const outputDirectories = ['bin', 'binary', 'dist', 'test', 'test-assets', 'test-plugin', 'test-loader'];
const outputDirectories = ['bin', 'binary', 'dist', 'test', 'test-assets', 'test-plugin', 'test-loader', 'stats.json'];

function folderStrategy(stats, file) {
return stats.isDirectory() && outputDirectories.includes(file);
Expand Down
27 changes: 27 additions & 0 deletions test/json/json.test.js
@@ -1,5 +1,7 @@
'use strict';
const { run } = require('../utils/test-utils');
const { stat, readFile } = require('fs');
const { resolve } = require('path');

describe('json flag', () => {
it('should return valid json', () => {
Expand All @@ -10,9 +12,31 @@ describe('json flag', () => {
return JSON.parse(stdout);
};
// check the JSON is valid.
expect(JSON.parse(stdout)['hash']).toBeTruthy();
expect(JSON.parse(stdout)['version']).toBeTruthy();
expect(JSON.parse(stdout)['time']).toBeTruthy();
expect(parseJson).not.toThrow();
});

it('should store json to a file', (done) => {
const { stdout } = run(__dirname, ['--json', 'stats.json']);

expect(stdout).toContain('stats are successfully stored as json to stats.json');
stat(resolve(__dirname, './stats.json'), (err, stats) => {
expect(err).toBe(null);
expect(stats.isFile()).toBe(true);
done();
});
readFile(resolve(__dirname, 'stats.json'), 'utf-8', (err, data) => {
expect(err).toBe(null);
expect(JSON.parse(data)['hash']).toBeTruthy();
expect(JSON.parse(data)['version']).toBeTruthy();
expect(JSON.parse(data)['time']).toBeTruthy();
expect(() => JSON.parse(data)).not.toThrow();
done();
});
});

it('should return valid json with -j alias', () => {
const { stdout } = run(__dirname, ['-j']);

Expand All @@ -21,6 +45,9 @@ describe('json flag', () => {
return JSON.parse(stdout);
};
// check the JSON is valid.
expect(JSON.parse(stdout)['hash']).toBeTruthy();
expect(JSON.parse(stdout)['version']).toBeTruthy();
expect(JSON.parse(stdout)['time']).toBeTruthy();
expect(parseJson).not.toThrow();
});
});

0 comments on commit 3907517

Please sign in to comment.