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: allow users to store stats as json to a file #1835

Merged
merged 4 commits into from Oct 3, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note JSON.stringify doesn't end with a newline.

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();
});
snitin315 marked this conversation as resolved.
Show resolved Hide resolved
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();
rishabh3112 marked this conversation as resolved.
Show resolved Hide resolved
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();
});
});