diff --git a/bin/webpack.js b/bin/webpack.js index 90933fd6d..e422a16b6 100755 --- a/bin/webpack.js +++ b/bin/webpack.js @@ -171,14 +171,18 @@ function processOptions(options) { return; } - var firstOptions = Array.isArray(options) ? (options[0] || {}) : options; + var firstOptions = [].concat(options)[0]; + var statsPresetToOptions = require("../lib/Stats.js").presetToOptions; - if(typeof options.stats === "boolean" || typeof options.stats === "string") { - var statsPresetToOptions = require("../lib/Stats.js").presetToOptions; - options.stats = statsPresetToOptions(options.stats); + var outputOptions = options.stats; + if(typeof outputOptions === "boolean" || typeof outputOptions === "string") + outputOptions = statsPresetToOptions(outputOptions); + else + outputOptions = {}; + outputOptions = Object.create(outputOptions); + if(Array.isArray(options) && !outputOptions.children) { + outputOptions.children = options.map(o => o.stats); } - - var outputOptions = Object.create(options.stats || firstOptions.stats || {}); if(typeof outputOptions.context === "undefined") outputOptions.context = firstOptions.context; diff --git a/lib/MultiStats.js b/lib/MultiStats.js index f2040c82f..b5c0b0152 100644 --- a/lib/MultiStats.js +++ b/lib/MultiStats.js @@ -28,11 +28,23 @@ MultiStats.prototype.hasWarnings = function() { }; MultiStats.prototype.toJson = function(options, forToString) { - var jsons = this.stats.map(function(stat) { - var obj = stat.toJson(options, forToString); + if(typeof options === "boolean" || typeof options === "string") { + options = Stats.presetToOptions(options); + } else if(!options) { + options = {}; + } + var jsons = this.stats.map((stat, idx) => { + var childOptions = Stats.getChildOptions(options, idx); + var obj = stat.toJson(childOptions, forToString); obj.name = stat.compilation && stat.compilation.name; return obj; }); + var showVersion = typeof options.version === "undefined" ? jsons.every(j => j.version) : options.version !== false; + var showHash = typeof options.hash === "undefined" ? jsons.every(j => j.hash) : options.hash !== false; + jsons.forEach(j => { + if(showVersion) + delete j.version; + }); var obj = { errors: jsons.reduce(function(arr, j) { return arr.concat(j.errors.map(function(msg) { @@ -45,11 +57,11 @@ MultiStats.prototype.toJson = function(options, forToString) { })); }, []) }; - if(!options || options.version !== false) + if(showVersion) obj.version = require("../package.json").version; - if(!options || options.hash !== false) + if(showHash) obj.hash = this.hash; - if(!options || options.children !== false) + if(options.children !== false) obj.children = jsons; return obj; }; diff --git a/lib/Stats.js b/lib/Stats.js index 2d597e2c4..fc62ede9f 100644 --- a/lib/Stats.js +++ b/lib/Stats.js @@ -330,8 +330,9 @@ class Stats { obj.modules.sort(sortByField(sortModules)); } if(showChildren) { - obj.children = compilation.children.map(child => { - const obj = new Stats(child).toJson(options, forToString); + obj.children = compilation.children.map((child, idx) => { + const childOptions = Stats.getChildOptions(options, idx); + const obj = new Stats(child).toJson(childOptions, forToString); delete obj.hash; delete obj.version; obj.name = child.name; @@ -766,17 +767,20 @@ class Stats { } if(obj.children) { obj.children.forEach(child => { - if(child.name) { - colors.normal("Child "); - colors.bold(child.name); - colors.normal(":"); - } else { - colors.normal("Child"); + let childString = Stats.jsonToString(child, useColors); + if(childString) { + if(child.name) { + colors.normal("Child "); + colors.bold(child.name); + colors.normal(":"); + } else { + colors.normal("Child"); + } + newline(); + buf.push(" "); + buf.push(childString.replace(/\n/g, "\n ")); + newline(); } - newline(); - buf.push(" "); - buf.push(Stats.jsonToString(child, useColors).replace(/\n/g, "\n ")); - newline(); }); } if(obj.needAdditionalPass) { @@ -810,7 +814,8 @@ class Stats { errors: false, errorDetails: false, warnings: false, - publicPath: false + publicPath: false, + performance: false }; } else { return { @@ -827,9 +832,29 @@ class Stats { depth: pn === "verbose", usedExports: pn === "verbose", providedExports: pn === "verbose", - colors: true + colors: true, + performance: true }; } + + } + + static getChildOptions(options, idx) { + let innerOptions; + if(Array.isArray(options.children)) { + if(idx < options.children.length) + innerOptions = options.children[idx]; + } else if(typeof options.children === "object" && options.children) { + innerOptions = options.children; + } + if(typeof innerOptions === "boolean" || typeof innerOptions === "string") + innerOptions = Stats.presetToOptions(innerOptions); + if(!innerOptions) + return options; + let childOptions = Object.assign({}, options); + delete childOptions.children; // do not inherit children + childOptions = Object.assign(childOptions, innerOptions); + return childOptions; } } diff --git a/package.json b/package.json index 3a965907a..02c56c580 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "author": "Tobias Koppers @sokra", "description": "Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.", "dependencies": { - "acorn": "^4.0.3", + "acorn": "^4.0.4", "acorn-dynamic-import": "^2.0.0", "ajv": "^4.7.0", "ajv-keywords": "^1.1.1", @@ -61,7 +61,7 @@ "url-loader": "~0.5.0", "val-loader": "~0.5.0", "vm-browserify": "~0.0.0", - "webpack-dev-middleware": "^1.0.0", + "webpack-dev-middleware": "^1.9.0", "worker-loader": "~0.7.0" }, "engines": { diff --git a/test/MultiStats.test.js b/test/MultiStats.test.js index 70497712b..9f023352b 100644 --- a/test/MultiStats.test.js +++ b/test/MultiStats.test.js @@ -11,10 +11,12 @@ var createStat = function(overides) { }, hasErrors: () => false, hasWarnings: () => false, - toJson: () => ({ + toJson: () => Object.assign({ + hash: "foo", + version: "version", warnings: [], errors: [] - }) + }, overides) }, overides); }; @@ -173,13 +175,14 @@ describe("MultiStats", function() { }) ]; myMultiStats = new MultiStats(stats); - result = myMultiStats.toJson(); + result = myMultiStats.toJson({ + version: false, + hash: false + }); }); it("returns plain object representation", function() { result.should.deepEqual({ - hash: "abc123xyz890", - version: "1.2.3", errors: [ "(abc123-compilation) abc123-error" ], @@ -235,9 +238,9 @@ describe("MultiStats", function() { "Hash: abc123xyz890\n" + "Version: webpack 1.2.3\n" + "Child abc123-compilation:\n" + - " \n" + + " Hash: abc123\n" + "Child xyz890-compilation:\n" + - " " + " Hash: xyz890" ); }); }); diff --git a/test/Stats.test.js b/test/Stats.test.js index 46fdb94fc..2b3ef656a 100644 --- a/test/Stats.test.js +++ b/test/Stats.test.js @@ -59,12 +59,14 @@ describe("Stats", function() { colors: false }; var hasColorSetting = false; - if(typeof options.stats !== "undefined") { toStringOptions = options.stats; hasColorSetting = typeof options.stats.colors !== "undefined"; } + if(Array.isArray(options) && !toStringOptions.children) { + toStringOptions.children = options.map(o => o.stats); + } var actual = stats.toString(toStringOptions); (typeof actual).should.be.eql("string"); @@ -166,7 +168,8 @@ describe("Stats", function() { depth: false, usedExports: false, providedExports: false, - colors: true + colors: true, + performance: true }); }); it("truthy values behave as 'normal'", function() { @@ -197,7 +200,8 @@ describe("Stats", function() { errors: false, errorDetails: false, warnings: false, - publicPath: false + publicPath: false, + performance: false }); }); it("falsy values behave as 'none'", function() { diff --git a/test/binCases/stats/multi-config/index.js b/test/binCases/stats/multi-config/index.js new file mode 100644 index 000000000..e7134e700 --- /dev/null +++ b/test/binCases/stats/multi-config/index.js @@ -0,0 +1 @@ +module.exports = "foo"; diff --git a/test/binCases/stats/multi-config/index2.js b/test/binCases/stats/multi-config/index2.js new file mode 100644 index 000000000..a7f281456 --- /dev/null +++ b/test/binCases/stats/multi-config/index2.js @@ -0,0 +1 @@ +module.exports = "bar"; diff --git a/test/binCases/stats/multi-config/test.js b/test/binCases/stats/multi-config/test.js new file mode 100644 index 000000000..9515f2f77 --- /dev/null +++ b/test/binCases/stats/multi-config/test.js @@ -0,0 +1,7 @@ +"use strict"; + +module.exports = function testAssertions(code, stdout, stderr) { + code.should.be.eql(0); + stdout.should.be.ok(); + stderr.should.be.empty(); +}; diff --git a/test/binCases/stats/multi-config/webpack.config.js b/test/binCases/stats/multi-config/webpack.config.js new file mode 100644 index 000000000..f522c7813 --- /dev/null +++ b/test/binCases/stats/multi-config/webpack.config.js @@ -0,0 +1,12 @@ +var path = require("path"); + +module.exports = [ + { + entry: path.resolve(__dirname, "./index"), + stats: "errors-only" + }, + { + entry: path.resolve(__dirname, "./index2"), + stats: "errors-only" + } +]; diff --git a/test/binCases/stats/single-config/test.js b/test/binCases/stats/single-config/test.js index 81c45bf0b..bf3770deb 100644 --- a/test/binCases/stats/single-config/test.js +++ b/test/binCases/stats/single-config/test.js @@ -1,7 +1,7 @@ "use strict"; module.exports = function testAssertions(code, stdout, stderr) { - code.should.be.oneOf(0, 1); + code.should.be.eql(0); stdout.should.be.ok(); stdout[0].should.containEql("Hash: "); diff --git a/test/statsCases/define-plugin/webpack.config.js b/test/statsCases/define-plugin/webpack.config.js index fb3801bea..a277a193a 100644 --- a/test/statsCases/define-plugin/webpack.config.js +++ b/test/statsCases/define-plugin/webpack.config.js @@ -2,7 +2,6 @@ var webpack = require("../../../"); module.exports = [ { entry: "./index", - stats: "errors-only", plugins: [ new webpack.DefinePlugin({ VALUE: "123" @@ -11,7 +10,6 @@ module.exports = [ }, { entry: "./index", - stats: "errors-only", plugins: [ new webpack.DefinePlugin({ VALUE: "321" diff --git a/test/statsCases/preset-mixed-array/expected.txt b/test/statsCases/preset-mixed-array/expected.txt new file mode 100644 index 000000000..3665b12d1 --- /dev/null +++ b/test/statsCases/preset-mixed-array/expected.txt @@ -0,0 +1,4 @@ +Child minimal: + chunk {0} main.js (main) 8 bytes [entry] [rendered] +Child verbose: + Entrypoint main = main.js \ No newline at end of file diff --git a/test/statsCases/preset-mixed-array/index.js b/test/statsCases/preset-mixed-array/index.js new file mode 100644 index 000000000..588375e3b --- /dev/null +++ b/test/statsCases/preset-mixed-array/index.js @@ -0,0 +1 @@ +// huh? diff --git a/test/statsCases/preset-mixed-array/webpack.config.js b/test/statsCases/preset-mixed-array/webpack.config.js new file mode 100644 index 000000000..96978975a --- /dev/null +++ b/test/statsCases/preset-mixed-array/webpack.config.js @@ -0,0 +1,23 @@ +module.exports = [ + { + name: "minimal", + entry: "./index", + stats: "minimal" + }, + { + name: "none", + entry: "./index", + stats: false + }, + { + name: "verbose", + entry: "./index", + stats: { + entrypoints: true, + hash: false, + timings: false, + chunks: false, + assets: false + } + } +] diff --git a/test/statsCases/preset-none-array/expected.txt b/test/statsCases/preset-none-array/expected.txt new file mode 100644 index 000000000..e69de29bb diff --git a/test/statsCases/preset-none-array/index.js b/test/statsCases/preset-none-array/index.js new file mode 100644 index 000000000..e69de29bb diff --git a/test/statsCases/preset-none-array/webpack.config.js b/test/statsCases/preset-none-array/webpack.config.js new file mode 100644 index 000000000..0924f24c4 --- /dev/null +++ b/test/statsCases/preset-none-array/webpack.config.js @@ -0,0 +1,10 @@ +module.exports = [ + { + entry: "./index", + stats: "none" + }, + { + entry: "./index", + stats: "none" + } +]