From dca8e62b60bc5f946025c44070a154450e30cc92 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Tue, 17 Jan 2017 22:26:38 +0100 Subject: [PATCH 01/40] don't shorten node_modules to ~ it's confusing --- lib/RequestShortener.js | 2 -- test/Compiler.test.js | 2 +- test/statsCases/separate-css-bundle/expected.txt | 8 ++++---- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/RequestShortener.js b/lib/RequestShortener.js index 0904c9024..a9aabc071 100644 --- a/lib/RequestShortener.js +++ b/lib/RequestShortener.js @@ -34,7 +34,6 @@ class RequestShortener { this.buildinsRegExp = buildinsRegExp; } - this.nodeModulesRegExp = /\/node_modules\//g; this.indexJsRegExp = /\/index.js(!|\?|\(query\))/g; } @@ -49,7 +48,6 @@ class RequestShortener { request = request.replace(this.parentDirectoryRegExp, "!.."); if(!this.buildinsAsModule && this.buildinsRegExp) request = request.replace(this.buildinsRegExp, "!(webpack)"); - request = request.replace(this.nodeModulesRegExp, "/~/"); request = request.replace(this.indexJsRegExp, "$1"); return request.replace(/^!|!$/, ""); } diff --git a/test/Compiler.test.js b/test/Compiler.test.js index 5589f077c..ab48fce99 100644 --- a/test/Compiler.test.js +++ b/test/Compiler.test.js @@ -99,7 +99,7 @@ describe("Compiler", function() { bundle.should.containEql("./main1.js"); bundle.should.containEql("./a.js"); bundle.should.containEql("./b.js"); - bundle.should.containEql("./~/m1/a.js"); + bundle.should.containEql("./node_modules/m1/a.js"); bundle.should.containEql("This is a"); bundle.should.containEql("This is b"); bundle.should.containEql("This is m1/a"); diff --git a/test/statsCases/separate-css-bundle/expected.txt b/test/statsCases/separate-css-bundle/expected.txt index c7d5d01b2..7cb0dc3e1 100644 --- a/test/statsCases/separate-css-bundle/expected.txt +++ b/test/statsCases/separate-css-bundle/expected.txt @@ -10,8 +10,8 @@ Child [1] (webpack)/test/statsCases/separate-css-bundle/a/index.js 23 bytes {0} [built] Child extract-text-webpack-plugin: chunk {0} extract-text-webpack-plugin-output-filename 1.65 kB [entry] [rendered] - [0] (webpack)/~/css-loader!(webpack)/test/statsCases/separate-css-bundle/a/file.css 192 bytes {0} [built] - [1] (webpack)/~/css-loader/lib/css-base.js 1.46 kB {0} [built] + [0] (webpack)/node_modules/css-loader!(webpack)/test/statsCases/separate-css-bundle/a/file.css 192 bytes {0} [built] + [1] (webpack)/node_modules/css-loader/lib/css-base.js 1.46 kB {0} [built] Child Hash: f4d2d844a00ebd8ee85a Time: Xms @@ -23,5 +23,5 @@ Child [1] (webpack)/test/statsCases/separate-css-bundle/b/index.js 23 bytes {0} [built] Child extract-text-webpack-plugin: chunk {0} extract-text-webpack-plugin-output-filename 1.65 kB [entry] [rendered] - [0] (webpack)/~/css-loader!(webpack)/test/statsCases/separate-css-bundle/b/file.css 194 bytes {0} [built] - [1] (webpack)/~/css-loader/lib/css-base.js 1.46 kB {0} [built] \ No newline at end of file + [0] (webpack)/node_modules/css-loader!(webpack)/test/statsCases/separate-css-bundle/b/file.css 194 bytes {0} [built] + [1] (webpack)/node_modules/css-loader/lib/css-base.js 1.46 kB {0} [built] \ No newline at end of file From e8bc9c2b3b121d97d9040d76856a4f33f75d56a3 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Tue, 18 Apr 2017 22:30:18 +0200 Subject: [PATCH 02/40] use a Set for Module.chunks --- lib/Compilation.js | 2 +- lib/Module.js | 90 +++++++++++++++++++---- lib/ModuleFilenameHelpers.js | 2 +- lib/Stats.js | 2 +- lib/optimize/OccurrenceOrderPlugin.js | 21 +++--- lib/optimize/RemoveParentModulesPlugin.js | 31 +------- 6 files changed, 95 insertions(+), 53 deletions(-) diff --git a/lib/Compilation.js b/lib/Compilation.js index 541f11592..4927a1e37 100644 --- a/lib/Compilation.js +++ b/lib/Compilation.js @@ -507,7 +507,7 @@ class Compilation extends Tapable { if(err) return callback(err); deps.forEach(d => { if(d.module && d.module.removeReason(module, d)) { - module.chunks.forEach(chunk => { + module.forEachChunk(chunk => { if(!d.module.hasReasonForChunk(chunk)) { if(d.module.removeChunk(chunk)) { this.removeChunkFromDependencies(d.module, chunk); diff --git a/lib/Module.js b/lib/Module.js index 788e3277b..2ffe2c4f4 100644 --- a/lib/Module.js +++ b/lib/Module.js @@ -4,6 +4,7 @@ */ "use strict"; +const util = require("util"); const DependenciesBlock = require("./DependenciesBlock"); const ModuleReason = require("./ModuleReason"); const Template = require("./Template"); @@ -36,7 +37,9 @@ class Module extends DependenciesBlock { this.used = null; this.usedExports = null; this.providedExports = null; - this.chunks = []; + this._chunks = new Set(); + this._chunksIsSorted = true; + this._chunksDebugIdent = undefined; this.warnings = []; this.dependenciesWarnings = []; this.errors = []; @@ -55,7 +58,9 @@ class Module extends DependenciesBlock { this.used = null; this.usedExports = null; this.providedExports = null; - this.chunks.length = 0; + this._chunks.clear(); + this._chunksDebugIdent = undefined; + this._chunksIsSorted = false; super.disconnect(); } @@ -65,26 +70,74 @@ class Module extends DependenciesBlock { this.index = null; this.index2 = null; this.depth = null; - this.chunks.length = 0; + this._chunks.clear(); + this._chunksDebugIdent = undefined; + this._chunksIsSorted = false; super.unseal(); } addChunk(chunk) { - let idx = this.chunks.indexOf(chunk); - if(idx < 0) - this.chunks.push(chunk); + this._chunks.add(chunk); + this._chunksDebugIdent = undefined; + this._chunksIsSorted = false; } removeChunk(chunk) { - let idx = this.chunks.indexOf(chunk); - if(idx >= 0) { - this.chunks.splice(idx, 1); + if(this._chunks.delete(chunk)) { + this._chunksDebugIdent = undefined; chunk.removeModule(this); return true; } return false; } + isInChunk(chunk) { + return this._chunks.has(chunk); + } + + getChunkIdsIdent() { + if(this._chunksDebugIdent !== undefined) return this._chunksDebugIdent; + this._ensureChunksSorted(); + const chunks = this._chunks; + const list = []; + for(let chunk of chunks) { + const debugId = chunk.debugId; + + if(typeof debugId !== "number") { + return this._chunksDebugIdent = null; + } + + list.push(debugId); + } + + return this._chunksDebugIdent = list.join(","); + } + + forEachChunk(fn) { + this._chunks.forEach(fn); + } + + mapChunks(fn) { + const chunks = this._chunks; + const size = chunks.size; + const array = new Array(size); + let idx = 0; + for(let chunk of chunks) { + array[idx++] = fn(chunk, idx, chunks); + } + return array; + } + + getNumberOfChunks() { + return this._chunks.size; + } + + _ensureChunksSorted() { + if(this._chunksIsSorted) return; + this._chunks = new Set(Array.from(this._chunks).sort(byId)); + this._chunksIsSorted = true; + } + addReason(module, dependency) { this.reasons.push(new ModuleReason(module, dependency)); } @@ -105,7 +158,7 @@ class Module extends DependenciesBlock { if(r.chunks) { if(r.chunks.indexOf(chunk) >= 0) return true; - } else if(r.module.chunks.indexOf(chunk) >= 0) + } else if(r.module._chunks.has(chunk)) return true; } return false; @@ -114,9 +167,9 @@ class Module extends DependenciesBlock { rewriteChunkInReasons(oldChunk, newChunks) { this.reasons.forEach(r => { if(!r.chunks) { - if(r.module.chunks.indexOf(oldChunk) < 0) + if(!r.module._chunks.has(oldChunk)) return; - r.chunks = r.module.chunks; + r.chunks = Array.from(r.module._chunks); } r.chunks = r.chunks.reduce((arr, c) => { addToSet(arr, c !== oldChunk ? [c] : newChunks); @@ -160,7 +213,7 @@ class Module extends DependenciesBlock { sortItems() { super.sortItems(); - this.chunks.sort(byId); + this._ensureChunksSorted(); this.reasons.sort((a, b) => byId(a.module, b.module)); } @@ -178,6 +231,17 @@ Object.defineProperty(Module.prototype, "entry", { throw new Error("Module.entry was removed. Use Chunk.entryModule"); } }); + +Object.defineProperty(Module.prototype, "chunks", { + configurable: false, + get: util.deprecate(() => { + return Array.from(this._chunks); + }, "Module.chunks: Use Module.forEachChunk/mapChunks/getNumberOfChunks/isInChunk/addChunk/removeChunk instead"), + set() { + throw new Error("Readonly. Use Module.addChunk/removeChunk to modify chunks."); + } +}); + Module.prototype.identifier = null; Module.prototype.readableIdentifier = null; Module.prototype.build = null; diff --git a/lib/ModuleFilenameHelpers.js b/lib/ModuleFilenameHelpers.js index 9fe569847..59010dee5 100644 --- a/lib/ModuleFilenameHelpers.js +++ b/lib/ModuleFilenameHelpers.js @@ -112,7 +112,7 @@ ModuleFilenameHelpers.createFooter = function createFooter(module, requestShorte "// WEBPACK FOOTER", `// ${module.readableIdentifier(requestShortener)}`, `// module id = ${module.id}`, - `// module chunks = ${module.chunks.map(c => c.id).join(" ")}` + `// module chunks = ${module.mapChunks(c => c.id).join(" ")}` ].join("\n"); } }; diff --git a/lib/Stats.js b/lib/Stats.js index 8bf3a0e9c..4ad1df273 100644 --- a/lib/Stats.js +++ b/lib/Stats.js @@ -279,7 +279,7 @@ class Stats { built: !!module.built, optional: !!module.optional, prefetched: !!module.prefetched, - chunks: module.chunks.map(chunk => chunk.id), + chunks: module.mapChunks(chunk => chunk.id), assets: Object.keys(module.assets || {}), issuer: module.issuer && module.issuer.identifier(), issuerId: module.issuer && module.issuer.id, diff --git a/lib/optimize/OccurrenceOrderPlugin.js b/lib/optimize/OccurrenceOrderPlugin.js index dc86b11e3..f545e27b8 100644 --- a/lib/optimize/OccurrenceOrderPlugin.js +++ b/lib/optimize/OccurrenceOrderPlugin.js @@ -16,12 +16,12 @@ class OccurrenceOrderPlugin { compiler.plugin("compilation", (compilation) => { compilation.plugin("optimize-module-order", (modules) => { function entryChunks(m) { - return m.chunks.map((c) => { + let total = 0; + m.forEachChunk(c => { const sum = (c.isInitial() ? 1 : 0) + (c.entryModule === m ? 1 : 0); - return sum; - }).reduce((a, b) => { - return a + b; - }, 0); + total += sum; + }); + return total; } function occursInEntry(m) { @@ -37,14 +37,17 @@ class OccurrenceOrderPlugin { function occurs(m) { if(typeof m.__OccurenceOrderPlugin_occurs === "number") return m.__OccurenceOrderPlugin_occurs; + let numberEntry = 0; + m.forEachChunk(c => { + if(c.entryModule === m) + numberEntry++; + }); const result = m.reasons.map((r) => { if(!r.module) return 0; - return r.module.chunks.length; + return r.module.getNumberOfChunks(); }).reduce((a, b) => { return a + b; - }, 0) + m.chunks.length + m.chunks.filter((c) => { - return c.entryModule === m; - }).length; + }, 0) + m.getNumberOfChunks() + numberEntry; return m.__OccurenceOrderPlugin_occurs = result; } modules.sort((a, b) => { diff --git a/lib/optimize/RemoveParentModulesPlugin.js b/lib/optimize/RemoveParentModulesPlugin.js index af4b42dfb..8467b8590 100644 --- a/lib/optimize/RemoveParentModulesPlugin.js +++ b/lib/optimize/RemoveParentModulesPlugin.js @@ -4,18 +4,8 @@ */ "use strict"; -function chunkContainsModule(chunk, module) { - const chunks = module.chunks; - const modules = chunk.modules; - if(chunks.length < modules.length) { - return chunks.indexOf(chunk) >= 0; - } else { - return modules.indexOf(module) >= 0; - } -} - function hasModule(chunk, module, checkedChunks) { - if(chunkContainsModule(chunk, module)) return [chunk]; + if(module.isInChunk(chunk)) return [chunk]; if(chunk.parents.length === 0) return false; return allHaveModule(chunk.parents.filter((c) => { return checkedChunks.indexOf(c) < 0; @@ -41,21 +31,6 @@ function allHaveModule(someChunks, module, checkedChunks) { return chunks; } -function debugIds(chunks) { - var list = []; - for(var i = 0; i < chunks.length; i++) { - var debugId = chunks[i].debugId; - - if(typeof debugId !== "number") { - return "no"; - } - - list.push(debugId); - } - - list.sort(); - return list.join(","); -} class RemoveParentModulesPlugin { apply(compiler) { @@ -71,9 +46,9 @@ class RemoveParentModulesPlugin { for(var i = 0; i < modules.length; i++) { var module = modules[i]; - var dId = debugIds(module.chunks); + var dId = module.getChunkIdsIdent(); var parentChunksWithModule; - if((dId in cache) && dId !== "no") { + if(dId !== null && (dId in cache)) { parentChunksWithModule = cache[dId]; } else { parentChunksWithModule = cache[dId] = allHaveModule(chunk.parents, module); From 7ca1297e11c95fff2f543d8e76621194f04b13fc Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Tue, 18 Apr 2017 23:28:16 +0200 Subject: [PATCH 03/40] Use a Set in RemoveParentModulesPlugin for performance --- lib/optimize/RemoveParentModulesPlugin.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/optimize/RemoveParentModulesPlugin.js b/lib/optimize/RemoveParentModulesPlugin.js index 8467b8590..28fe5a78e 100644 --- a/lib/optimize/RemoveParentModulesPlugin.js +++ b/lib/optimize/RemoveParentModulesPlugin.js @@ -8,24 +8,22 @@ function hasModule(chunk, module, checkedChunks) { if(module.isInChunk(chunk)) return [chunk]; if(chunk.parents.length === 0) return false; return allHaveModule(chunk.parents.filter((c) => { - return checkedChunks.indexOf(c) < 0; + return !checkedChunks.has(c); }), module, checkedChunks); } function allHaveModule(someChunks, module, checkedChunks) { - if(!checkedChunks) checkedChunks = []; - var chunks = []; + if(!checkedChunks) checkedChunks = new Set(); + var chunks = new Set(); for(var i = 0; i < someChunks.length; i++) { - checkedChunks.push(someChunks[i]); + checkedChunks.add(someChunks[i]); var subChunks = hasModule(someChunks[i], module, checkedChunks); if(!subChunks) return false; for(var index = 0; index < subChunks.length; index++) { var item = subChunks[index]; - if(!chunks.length || chunks.indexOf(item) < 0) { - chunks.push(item); - } + chunks.add(item); } } return chunks; @@ -48,13 +46,15 @@ class RemoveParentModulesPlugin { var dId = module.getChunkIdsIdent(); var parentChunksWithModule; - if(dId !== null && (dId in cache)) { + if(dId === null) { + parentChunksWithModule = allHaveModule(chunk.parents, module); + } else if(dId in cache) { parentChunksWithModule = cache[dId]; } else { parentChunksWithModule = cache[dId] = allHaveModule(chunk.parents, module); } if(parentChunksWithModule) { - module.rewriteChunkInReasons(chunk, parentChunksWithModule); + module.rewriteChunkInReasons(chunk, Array.from(parentChunksWithModule)); chunk.removeModule(module); } } From aac0389ba840e8f45f55853d49782605ce7f3a1c Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 19 Apr 2017 07:57:21 +0200 Subject: [PATCH 04/40] Sort by debug id and id --- lib/Compilation.js | 4 ++-- lib/Module.js | 26 ++++++++++++++++++++------ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/lib/Compilation.js b/lib/Compilation.js index 4927a1e37..18bdf4402 100644 --- a/lib/Compilation.js +++ b/lib/Compilation.js @@ -1013,7 +1013,7 @@ class Compilation extends Tapable { const modules = this.modules; for(let indexModule = 0; indexModule < modules.length; indexModule++) { - modules[indexModule].sortItems(); + modules[indexModule].sortItems(false); } const chunks = this.chunks; @@ -1027,7 +1027,7 @@ class Compilation extends Tapable { const modules = this.modules; for(let indexModule = 0; indexModule < modules.length; indexModule++) { - modules[indexModule].sortItems(); + modules[indexModule].sortItems(true); } const chunks = this.chunks; diff --git a/lib/Module.js b/lib/Module.js index 2ffe2c4f4..dfb350524 100644 --- a/lib/Module.js +++ b/lib/Module.js @@ -20,6 +20,10 @@ function byId(a, b) { return a.id - b.id; } +function byDebugId(a, b) { + return a.debugId - b.debugId; +} + let debugId = 1000; class Module extends DependenciesBlock { @@ -39,6 +43,7 @@ class Module extends DependenciesBlock { this.providedExports = null; this._chunks = new Set(); this._chunksIsSorted = true; + this._chunksIsSortedByDebugId = true; this._chunksDebugIdent = undefined; this.warnings = []; this.dependenciesWarnings = []; @@ -60,7 +65,7 @@ class Module extends DependenciesBlock { this.providedExports = null; this._chunks.clear(); this._chunksDebugIdent = undefined; - this._chunksIsSorted = false; + this._chunksIsSorted = this._chunksIsSortedByDebugId = false; super.disconnect(); } @@ -72,14 +77,14 @@ class Module extends DependenciesBlock { this.depth = null; this._chunks.clear(); this._chunksDebugIdent = undefined; - this._chunksIsSorted = false; + this._chunksIsSorted = this._chunksIsSortedByDebugId = false; super.unseal(); } addChunk(chunk) { this._chunks.add(chunk); this._chunksDebugIdent = undefined; - this._chunksIsSorted = false; + this._chunksIsSorted = this._chunksIsSortedByDebugId = false; } removeChunk(chunk) { @@ -97,7 +102,7 @@ class Module extends DependenciesBlock { getChunkIdsIdent() { if(this._chunksDebugIdent !== undefined) return this._chunksDebugIdent; - this._ensureChunksSorted(); + this._ensureChunksSortedByDebugId(); const chunks = this._chunks; const list = []; for(let chunk of chunks) { @@ -135,9 +140,17 @@ class Module extends DependenciesBlock { _ensureChunksSorted() { if(this._chunksIsSorted) return; this._chunks = new Set(Array.from(this._chunks).sort(byId)); + this._chunksIsSortedByDebugId = false; this._chunksIsSorted = true; } + _ensureChunksSortedByDebugId() { + if(this._chunksIsSortedByDebugId) return; + this._chunks = new Set(Array.from(this._chunks).sort(byDebugId)); + this._chunksIsSorted = false; + this._chunksIsSortedByDebugId = true; + } + addReason(module, dependency) { this.reasons.push(new ModuleReason(module, dependency)); } @@ -211,9 +224,10 @@ class Module extends DependenciesBlock { super.updateHash(hash); } - sortItems() { + sortItems(sortChunks) { super.sortItems(); - this._ensureChunksSorted(); + if(sortChunks) + this._ensureChunksSorted(); this.reasons.sort((a, b) => byId(a.module, b.module)); } From 616777b520a52707816118f624c5b153ab51cd3c Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Fri, 21 Apr 2017 18:47:59 +0200 Subject: [PATCH 05/40] fix spacing issue --- lib/optimize/RemoveParentModulesPlugin.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/optimize/RemoveParentModulesPlugin.js b/lib/optimize/RemoveParentModulesPlugin.js index 28fe5a78e..a6f46c5ba 100644 --- a/lib/optimize/RemoveParentModulesPlugin.js +++ b/lib/optimize/RemoveParentModulesPlugin.js @@ -29,7 +29,6 @@ function allHaveModule(someChunks, module, checkedChunks) { return chunks; } - class RemoveParentModulesPlugin { apply(compiler) { compiler.plugin("compilation", (compilation) => { From df44599731b4b1d185b20ccd36e9d37d817ad8c2 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sat, 22 Apr 2017 19:04:11 +0200 Subject: [PATCH 06/40] optimize variable --- lib/Module.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/Module.js b/lib/Module.js index dfb350524..7f1e83f67 100644 --- a/lib/Module.js +++ b/lib/Module.js @@ -124,8 +124,7 @@ class Module extends DependenciesBlock { mapChunks(fn) { const chunks = this._chunks; - const size = chunks.size; - const array = new Array(size); + const array = new Array(chunks.size); let idx = 0; for(let chunk of chunks) { array[idx++] = fn(chunk, idx, chunks); From 101850c5a90dbc51f1a95813fe1fece42bc1b9dc Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Thu, 13 Apr 2017 13:43:51 +0200 Subject: [PATCH 07/40] assign correct records and cache to child compilations This is a breaking change because plugins or loader could rely on this incorrect behavior When using child compilations plugins and loaders should use a unique compiler name or use a consistent order fixes #2777 --- lib/Compilation.js | 7 +++++-- lib/Compiler.js | 23 ++++++++++++++++++++--- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/lib/Compilation.js b/lib/Compilation.js index bdc4f0368..2cc53f3bd 100644 --- a/lib/Compilation.js +++ b/lib/Compilation.js @@ -80,6 +80,7 @@ class Compilation extends Tapable { this.children = []; this.dependencyFactories = new Map(); this.dependencyTemplates = new Map(); + this.childrenCounters = {}; } getStats() { @@ -1218,8 +1219,10 @@ class Compilation extends Tapable { return this.mainTemplate.applyPluginsWaterfall("asset-path", filename, data); } - createChildCompiler(name, outputOptions) { - return this.compiler.createChildCompiler(this, name, outputOptions); + createChildCompiler(name, outputOptions, plugins) { + var idx = (this.childrenCounters[name] || 0); + this.childrenCounters[name] = idx + 1; + return this.compiler.createChildCompiler(this, name, idx, outputOptions, plugins); } checkConstraints() { diff --git a/lib/Compiler.js b/lib/Compiler.js index 8e1f95de0..d825edd73 100644 --- a/lib/Compiler.js +++ b/lib/Compiler.js @@ -10,6 +10,8 @@ var Stats = require("./Stats"); var NormalModuleFactory = require("./NormalModuleFactory"); var ContextModuleFactory = require("./ContextModuleFactory"); +var makePathsRelative = require("./util/identifier").makePathsRelative; + function Watching(compiler, watchOptions, handler) { this.startTime = null; this.invalid = false; @@ -407,7 +409,7 @@ Compiler.prototype.readRecords = function readRecords(callback) { }); }; -Compiler.prototype.createChildCompiler = function(compilation, compilerName, outputOptions, plugins) { +Compiler.prototype.createChildCompiler = function(compilation, compilerName, compilerIndex, outputOptions, plugins) { var childCompiler = new Compiler(); if(Array.isArray(plugins)) { plugins.forEach(plugin => childCompiler.apply(plugin)); @@ -423,8 +425,23 @@ Compiler.prototype.createChildCompiler = function(compilation, compilerName, out childCompiler.resolvers = this.resolvers; childCompiler.fileTimestamps = this.fileTimestamps; childCompiler.contextTimestamps = this.contextTimestamps; - if(!this.records[compilerName]) this.records[compilerName] = []; - this.records[compilerName].push(childCompiler.records = {}); + + var relativeCompilerName = makePathsRelative(this.context, compilerName); + if(!this.records[relativeCompilerName]) this.records[relativeCompilerName] = []; + if(this.records[relativeCompilerName][compilerIndex]) + childCompiler.records = this.records[relativeCompilerName][compilerIndex]; + else + this.records[relativeCompilerName].push(childCompiler.records = {}); + + if(this.cache) { + if(!this.cache.children) this.cache.children = {}; + if(!this.cache.children[compilerName]) this.cache.children[compilerName] = []; + if(this.cache.children[compilerName][compilerIndex]) + childCompiler.cache = this.cache.children[compilerName][compilerIndex]; + else + this.cache.children[compilerName].push(childCompiler.cache = {}); + } + childCompiler.options = Object.create(this.options); childCompiler.options.output = Object.create(childCompiler.options.output); for(name in outputOptions) { From e1bac32c19a655dbedcecda90193033a1399b87c Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Fri, 21 Apr 2017 10:05:56 +0200 Subject: [PATCH 08/40] Use a Set to store modules in a chunk --- lib/AsyncDependenciesBlock.js | 12 +- lib/Chunk.js | 111 +++++++++++++++--- lib/FlagInitialModulesAsUsedPlugin.js | 2 +- lib/HotModuleReplacementPlugin.js | 6 +- lib/HotUpdateChunkTemplate.js | 11 +- lib/LibManifestPlugin.js | 15 ++- lib/Stats.js | 8 +- lib/Template.js | 6 +- lib/UmdMainTemplatePlugin.js | 2 +- lib/optimize/AggressiveSplittingPlugin.js | 40 +++---- lib/optimize/CommonsChunkPlugin.js | 2 +- lib/optimize/EnsureChunkConditionsPlugin.js | 2 +- lib/optimize/FlagIncludedChunksPlugin.js | 8 +- lib/optimize/MergeDuplicateChunksPlugin.js | 2 +- lib/optimize/OccurrenceOrderPlugin.js | 15 +-- lib/optimize/RemoveParentModulesPlugin.js | 14 +-- test/Chunk.test.js | 2 +- .../expected.txt | 8 +- .../webpack.config.js | 6 +- 19 files changed, 156 insertions(+), 116 deletions(-) diff --git a/lib/AsyncDependenciesBlock.js b/lib/AsyncDependenciesBlock.js index d21218895..e8ff2daae 100644 --- a/lib/AsyncDependenciesBlock.js +++ b/lib/AsyncDependenciesBlock.js @@ -37,17 +37,7 @@ module.exports = class AsyncDependenciesBlock extends DependenciesBlock { sortItems() { super.sortItems(); if(this.chunks) { - this.chunks.sort((a, b) => { - let i = 0; - while(true) { // eslint-disable-line no-constant-condition - if(!a.modules[i] && !b.modules[i]) return 0; - if(!a.modules[i]) return -1; - if(!b.modules[i]) return 1; - if(a.modules[i].id > b.modules[i].id) return 1; - if(a.modules[i].id < b.modules[i].id) return -1; - i++; - } - }); + this.chunks.sort((a, b) => a.compareTo(b)); } } }; diff --git a/lib/Chunk.js b/lib/Chunk.js index 5bfb2910e..93feb4116 100644 --- a/lib/Chunk.js +++ b/lib/Chunk.js @@ -4,6 +4,7 @@ */ "use strict"; +const util = require("util"); const compareLocations = require("./compareLocations"); let debugId = 1000; @@ -20,7 +21,8 @@ class Chunk { this.ids = null; this.debugId = debugId++; this.name = name; - this.modules = []; + this._modules = new Set(); + this._modulesIsSorted = true; this.entrypoints = []; this.chunks = []; this.parents = []; @@ -88,7 +90,12 @@ class Chunk { } addModule(module) { - return this.addToCollection(this.modules, module); + if(!this._modules.has(module)) { + this._modules.add(module); + this._modulesIsSorted = false; + return true; + } + return false; } addBlock(block) { @@ -96,9 +103,7 @@ class Chunk { } removeModule(module) { - const idx = this.modules.indexOf(module); - if(idx >= 0) { - this.modules.splice(idx, 1); + if(this._modules.delete(module)) { module.removeChunk(this); return true; } @@ -133,9 +138,72 @@ class Chunk { }); } + setModules(modules) { + this._modules = new Set(modules); + this._modulesIsSorted = false; + } + + getNumberOfModules() { + return this._modules.size; + } + + get modulesIterable() { + return this._modules; + } + + forEachModule(fn) { + this._modules.forEach(fn); + } + + mapModules(fn) { + const modules = this._modules; + const array = new Array(modules.size); + let idx = 0; + for(let module of modules) { + array[idx++] = fn(module, idx, modules); + } + return array; + } + + _ensureModulesSorted() { + if(this._modulesIsSorted) return; + this._modules = new Set(Array.from(this._modules).sort((a, b) => { + if(a.identifier() > b.identifier()) return 1; + if(a.identifier() < b.identifier()) return -1; + return 0; + })); + this._modulesIsSorted = true; + } + + compareTo(otherChunk) { + this._ensureModulesSorted(); + otherChunk._ensureModulesSorted(); + if(this._modules.size > otherChunk._modules.size) return -1; + if(this._modules.size < otherChunk._modules.size) return 1; + const a = this._modules[Symbol.iterator](); + const b = otherChunk._modules[Symbol.iterator](); + while(true) { // eslint-disable-line + const aItem = a.next(); + const bItem = b.next(); + if(aItem.done) return 0; + const aModuleIdentifier = aItem.value.identifier(); + const bModuleIdentifier = bItem.value.identifier(); + if(aModuleIdentifier > bModuleIdentifier) return -1; + if(aModuleIdentifier < bModuleIdentifier) return 1; + } + } + + containsModule(module) { + return this._modules.has(module); + } + + getModules() { + return Array.from(this._modules); + } + remove(reason) { // cleanup modules - this.modules.slice().forEach(module => { + Array.from(this._modules).forEach(module => { module.removeChunk(this); }); @@ -219,9 +287,9 @@ class Chunk { return false; } - const otherChunkModules = otherChunk.modules.slice(); + const otherChunkModules = Array.from(otherChunk._modules); otherChunkModules.forEach(module => otherChunk.moveModule(module, this)); - otherChunk.modules.length = 0; + otherChunk._modules.clear(); otherChunk.parents.forEach(parentChunk => parentChunk.replaceChunk(otherChunk, this)); otherChunk.parents.length = 0; @@ -276,14 +344,14 @@ class Chunk { } isEmpty() { - return this.modules.length === 0; + return this._modules.size === 0; } updateHash(hash) { hash.update(`${this.id} `); hash.update(this.ids ? this.ids.join(",") : ""); hash.update(`${this.name || ""} `); - this.modules.forEach(m => m.updateHash(hash)); + this._modules.forEach(m => m.updateHash(hash)); } canBeIntegrated(otherChunk) { @@ -307,8 +375,8 @@ class Chunk { modulesSize() { let count = 0; - for(let i = 0; i < this.modules.length; i++) { - count += this.modules[i].size(); + for(let module of this._modules) { + count += module.size(); } return count; } @@ -325,9 +393,8 @@ class Chunk { let integratedModulesSize = this.modulesSize(); // only count modules that do not exist in this chunk! - for(let i = 0; i < otherChunk.modules.length; i++) { - const otherModule = otherChunk.modules[i]; - if(this.modules.indexOf(otherModule) === -1) { + for(let otherModule of otherChunk._modules) { + if(!this._modules.has(otherModule)) { integratedModulesSize += otherModule.size(); } } @@ -356,7 +423,7 @@ class Chunk { } sortItems() { - this.modules.sort(byId); + this._modules = new Set(Array.from(this._modules).sort(byId)); this.origins.sort((a, b) => { const aIdent = a.module.identifier(); const bIdent = b.module.identifier(); @@ -373,7 +440,7 @@ class Chunk { } toString() { - return `Chunk[${this.modules.join()}]`; + return `Chunk[${Array.from(this._modules).join()}]`; } checkConstraints() { @@ -393,4 +460,14 @@ class Chunk { } } +Object.defineProperty(Chunk.prototype, "modules", { + configurable: false, + get: util.deprecate(function() { + return Array.from(this._modules); + }, "Chunk.modules is deprecated. Use Chunk.getNumberOfModules/mapModules/forEachModule/containsModule instead."), + set: util.deprecate(function(value) { + this.setModules(value); + }, "Chunk.modules is deprecated. Use Chunk.addModule/removeModule instead.") +}); + module.exports = Chunk; diff --git a/lib/FlagInitialModulesAsUsedPlugin.js b/lib/FlagInitialModulesAsUsedPlugin.js index 64d084270..ae81f8b9b 100644 --- a/lib/FlagInitialModulesAsUsedPlugin.js +++ b/lib/FlagInitialModulesAsUsedPlugin.js @@ -12,7 +12,7 @@ class FlagInitialModulesAsUsedPlugin { if(!chunk.isInitial()) { return; } - chunk.modules.forEach((module) => { + chunk.forEachModule((module) => { module.usedExports = true; }); }); diff --git a/lib/HotModuleReplacementPlugin.js b/lib/HotModuleReplacementPlugin.js index 48de6fedf..5cfdcd380 100644 --- a/lib/HotModuleReplacementPlugin.js +++ b/lib/HotModuleReplacementPlugin.js @@ -54,7 +54,7 @@ HotModuleReplacementPlugin.prototype.apply = function(compiler) { }); records.chunkModuleIds = {}; this.chunks.forEach(function(chunk) { - records.chunkModuleIds[chunk.id] = chunk.modules.map(function(m) { + records.chunkModuleIds[chunk.id] = chunk.mapModules(function(m) { return m.id; }); }); @@ -112,11 +112,11 @@ HotModuleReplacementPlugin.prototype.apply = function(compiler) { chunkId = isNaN(+chunkId) ? chunkId : +chunkId; var currentChunk = this.chunks.find(chunk => chunk.id === chunkId); if(currentChunk) { - var newModules = currentChunk.modules.filter(function(module) { + var newModules = currentChunk.mapModules(m => m).filter(function(module) { return module.hotUpdate; }); var allModules = {}; - currentChunk.modules.forEach(function(module) { + currentChunk.forEachModule(function(module) { allModules[module.id] = true; }); var removedModules = records.chunkModuleIds[chunkId].filter(function(id) { diff --git a/lib/HotUpdateChunkTemplate.js b/lib/HotUpdateChunkTemplate.js index e32e5cccb..84b366a08 100644 --- a/lib/HotUpdateChunkTemplate.js +++ b/lib/HotUpdateChunkTemplate.js @@ -5,6 +5,7 @@ "use strict"; const Template = require("./Template"); +const Chunk = require("./Chunk"); module.exports = class HotUpdateChunkTemplate extends Template { constructor(outputOptions) { @@ -12,11 +13,11 @@ module.exports = class HotUpdateChunkTemplate extends Template { } render(id, modules, removedModules, hash, moduleTemplate, dependencyTemplates) { - const modulesSource = this.renderChunkModules({ - id: id, - modules: modules, - removedModules: removedModules - }, moduleTemplate, dependencyTemplates); + const hotUpdateChunk = new Chunk(); + hotUpdateChunk.id = id; + hotUpdateChunk.setModules(modules); + hotUpdateChunk.removedModules = removedModules; + const modulesSource = this.renderChunkModules(hotUpdateChunk, moduleTemplate, dependencyTemplates); const core = this.applyPluginsWaterfall("modules", modulesSource, modules, removedModules, moduleTemplate, dependencyTemplates); const source = this.applyPluginsWaterfall("render", core, modules, removedModules, hash, id, moduleTemplate, dependencyTemplates); return source; diff --git a/lib/LibManifestPlugin.js b/lib/LibManifestPlugin.js index c72fd3e6d..577882519 100644 --- a/lib/LibManifestPlugin.js +++ b/lib/LibManifestPlugin.js @@ -30,19 +30,24 @@ class LibManifestPlugin { const manifest = { name, type: this.options.type, - content: chunk.modules.reduce((obj, module) => { + content: chunk.mapModules(module => { if(module.libIdent) { const ident = module.libIdent({ context: this.options.context || compiler.options.context }); if(ident) { - obj[ident] = { - id: module.id, - meta: module.meta, - exports: Array.isArray(module.providedExports) ? module.providedExports : undefined + return { + ident, + data: { + id: module.id, + meta: module.meta, + exports: Array.isArray(module.providedExports) ? module.providedExports : undefined + } }; } } + }).filter(Boolean).reduce((obj, item) => { + obj[item.ident] = item.data; return obj; }, {}) }; diff --git a/lib/Stats.js b/lib/Stats.js index 7e869a0cf..6b39b8461 100644 --- a/lib/Stats.js +++ b/lib/Stats.js @@ -328,19 +328,19 @@ class Stats { entry: chunk.hasRuntime(), recorded: chunk.recorded, extraAsync: !!chunk.extraAsync, - size: chunk.modules.reduce((size, module) => size + module.size(), 0), + size: chunk.mapModules(m => m.size()).reduce((size, moduleSize) => size + moduleSize, 0), names: chunk.name ? [chunk.name] : [], files: chunk.files.slice(), hash: chunk.renderedHash, parents: chunk.parents.map(c => c.id) }; if(showChunkModules) { - obj.modules = chunk.modules - .slice() + obj.modules = chunk + .mapModules(m => m) .sort(sortByField("depth")) .filter(createModuleFilter()) .map(fnModule); - obj.filteredModules = chunk.modules.length - obj.modules.length; + obj.filteredModules = chunk.getNumberOfModules() - obj.modules.length; obj.modules.sort(sortByField(sortModules)); } if(showChunkOrigins) { diff --git a/lib/Template.js b/lib/Template.js index 0c11f5934..d7ee6e85b 100644 --- a/lib/Template.js +++ b/lib/Template.js @@ -99,12 +99,12 @@ module.exports = class Template extends Tapable { renderChunkModules(chunk, moduleTemplate, dependencyTemplates, prefix) { if(!prefix) prefix = ""; var source = new ConcatSource(); - if(chunk.modules.length === 0) { + if(chunk.getNumberOfModules() === 0) { source.add("[]"); return source; } var removedModules = chunk.removedModules; - var allModules = chunk.modules.map(function(module) { + var allModules = chunk.mapModules(function(module) { return { id: module.id, source: moduleTemplate.render(module, dependencyTemplates, chunk) @@ -118,7 +118,7 @@ module.exports = class Template extends Tapable { }); }); } - var bounds = this.getModulesArrayBounds(chunk.modules); + var bounds = this.getModulesArrayBounds(allModules); if(bounds) { // Render a spare array diff --git a/lib/UmdMainTemplatePlugin.js b/lib/UmdMainTemplatePlugin.js index 54d88bff2..1c6ff1b9a 100644 --- a/lib/UmdMainTemplatePlugin.js +++ b/lib/UmdMainTemplatePlugin.js @@ -32,7 +32,7 @@ class UmdMainTemplatePlugin { apply(compilation) { const mainTemplate = compilation.mainTemplate; compilation.templatesPlugin("render-with-entry", function(source, chunk, hash) { - let externals = chunk.modules.filter(m => m.external); + let externals = chunk.mapModules(m => m).filter(m => m.external); const optionalExternals = []; let requiredExternals = []; if(this.optionalAmdExternalAsGlobal) { diff --git a/lib/optimize/AggressiveSplittingPlugin.js b/lib/optimize/AggressiveSplittingPlugin.js index 3c5006d6d..b74c859da 100644 --- a/lib/optimize/AggressiveSplittingPlugin.js +++ b/lib/optimize/AggressiveSplittingPlugin.js @@ -6,18 +6,6 @@ const identifierUtils = require("../util/identifier"); -function toIndexOf(list) { - return function(item) { - return list.indexOf(item); - }; -} - -function toChunkModuleIndices(modules) { - return function(idx) { - return modules[idx]; - }; -} - function moveModuleBetween(oldChunk, newChunk) { return function(module) { oldChunk.moveModule(module, newChunk); @@ -62,17 +50,19 @@ class AggressiveSplittingPlugin { const splitData = usedSplits[j]; for(let i = 0; i < chunks.length; i++) { const chunk = chunks[i]; - const chunkModuleNames = chunk.modules.map(m => identifierUtils.makePathsRelative(compiler.context, m.identifier())); - if(chunkModuleNames.length < splitData.modules.length) + if(chunk.getNumberOfModules() < splitData.modules.length) continue; - const moduleIndicies = splitData.modules.map(toIndexOf(chunkModuleNames)); - const hasAllModules = moduleIndicies.every((idx) => { - return idx >= 0; + + const nameToModuleMap = new Map(); + chunk.forEachModule(m => { + const name = identifierUtils.makePathsRelative(compiler.context, m.identifier()); + nameToModuleMap.set(name, m); }); - if(hasAllModules) { - if(chunkModuleNames.length > splitData.modules.length) { - const selectedModules = moduleIndicies.map(toChunkModuleIndices(chunk.modules)); + + const selectedModules = splitData.modules.map(name => nameToModuleMap.get(name)); + if(selectedModules.every(Boolean)) { + if(chunk.getNumberOfModules() > splitData.modules.length) { const newChunk = compilation.addChunk(); selectedModules.forEach(moveModuleBetween(chunk, newChunk)); chunk.split(newChunk); @@ -101,9 +91,9 @@ class AggressiveSplittingPlugin { for(let i = 0; i < chunks.length; i++) { const chunk = chunks[i]; const size = chunk.size(this.options); - if(size > maxSize && chunk.modules.length > 1) { + if(size > maxSize && chunk.getNumberOfModules() > 1) { const newChunk = compilation.addChunk(); - const modules = chunk.modules + const modules = chunk.mapModules(m => m) .filter(isNotAEntryModule(chunk.entryModule)) .sort((a, b) => { a = a.identifier(); @@ -131,13 +121,13 @@ class AggressiveSplittingPlugin { break; } } - if(newChunk.modules.length > 0) { + if(newChunk.getNumberOfModules() > 0) { chunk.split(newChunk); chunk.name = null; newChunk.origins = chunk.origins.map(copyWithReason); chunk.origins = chunk.origins.map(copyWithReason); compilation._aggressiveSplittingSplits = (compilation._aggressiveSplittingSplits || []).concat({ - modules: newChunk.modules.map(m => identifierUtils.makePathsRelative(compiler.context, m.identifier())) + modules: newChunk.mapModules(m => identifierUtils.makePathsRelative(compiler.context, m.identifier())) }); return true; } else { @@ -154,7 +144,7 @@ class AggressiveSplittingPlugin { if(chunk.hasEntryModule()) return; const size = chunk.size(this.options); const incorrectSize = size < minSize; - const modules = chunk.modules.map(m => identifierUtils.makePathsRelative(compiler.context, m.identifier())); + const modules = chunk.mapModules(m => identifierUtils.makePathsRelative(compiler.context, m.identifier())); if(typeof chunk._fromAggressiveSplittingIndex === "undefined") { if(incorrectSize) return; chunk.recorded = true; diff --git a/lib/optimize/CommonsChunkPlugin.js b/lib/optimize/CommonsChunkPlugin.js index 4a9bd38da..f599975b2 100644 --- a/lib/optimize/CommonsChunkPlugin.js +++ b/lib/optimize/CommonsChunkPlugin.js @@ -275,7 +275,7 @@ Take a look at the "name"/"names" or async/children option.`); // count how many chunks contain a module const commonModulesToCountMap = usedChunks.reduce((map, chunk) => { - for(let module of chunk.modules) { + for(let module of chunk.modulesIterable) { const count = map.has(module) ? map.get(module) : 0; map.set(module, count + 1); } diff --git a/lib/optimize/EnsureChunkConditionsPlugin.js b/lib/optimize/EnsureChunkConditionsPlugin.js index 590adc6e5..8c2f401d2 100644 --- a/lib/optimize/EnsureChunkConditionsPlugin.js +++ b/lib/optimize/EnsureChunkConditionsPlugin.js @@ -11,7 +11,7 @@ class EnsureChunkConditionsPlugin { compilation.plugin(["optimize-chunks-basic", "optimize-extracted-chunks-basic"], (chunks) => { let changed = false; chunks.forEach((chunk) => { - chunk.modules.slice().forEach((module) => { + chunk.forEachModule((module) => { if(!module.chunkCondition) return; if(!module.chunkCondition(chunk)) { const usedChunks = module._EnsureChunkConditionsPlugin_usedChunks = (module._EnsureChunkConditionsPlugin_usedChunks || []).concat(chunk); diff --git a/lib/optimize/FlagIncludedChunksPlugin.js b/lib/optimize/FlagIncludedChunksPlugin.js index 4fa9b1f9d..23f83b45b 100644 --- a/lib/optimize/FlagIncludedChunksPlugin.js +++ b/lib/optimize/FlagIncludedChunksPlugin.js @@ -17,13 +17,13 @@ class FlagIncludedChunksPlugin { // instead of swapping A and B just bail // as we loop twice the current A will be B and B then A - if(chunkA.modules.length < chunkB.modules.length) return; + if(chunkA.getNumberOfModules() < chunkB.getNumberOfModules()) return; - if(chunkB.modules.length === 0) return; + if(chunkB.getNumberOfModules() === 0) return; // is chunkB in chunkA? - for(let i = 0; i < chunkB.modules.length; i++) { - if(chunkA.modules.indexOf(chunkB.modules[i]) < 0) return; + for(let m of chunkB.modulesIterable) { + if(!chunkA.containsModule(m)) return; } chunkA.ids.push(chunkB.id); }); diff --git a/lib/optimize/MergeDuplicateChunksPlugin.js b/lib/optimize/MergeDuplicateChunksPlugin.js index 104cd6d6c..aaf0acc7d 100644 --- a/lib/optimize/MergeDuplicateChunksPlugin.js +++ b/lib/optimize/MergeDuplicateChunksPlugin.js @@ -5,7 +5,7 @@ "use strict"; function getChunkIdentifier(chunk) { - return chunk.modules.map((m) => { + return chunk.mapModules((m) => { return m.identifier(); }).sort().join(", "); } diff --git a/lib/optimize/OccurrenceOrderPlugin.js b/lib/optimize/OccurrenceOrderPlugin.js index dc86b11e3..316314809 100644 --- a/lib/optimize/OccurrenceOrderPlugin.js +++ b/lib/optimize/OccurrenceOrderPlugin.js @@ -80,13 +80,6 @@ class OccurrenceOrderPlugin { function occurs(c) { return c.blocks.length; } - chunks.forEach((c) => { - c.modules.sort((a, b) => { - if(a.identifier() > b.identifier()) return 1; - if(a.identifier() < b.identifier()) return -1; - return 0; - }); - }); chunks.sort((a, b) => { const aEntryOccurs = occursInEntry(a); const bEntryOccurs = occursInEntry(b); @@ -96,13 +89,7 @@ class OccurrenceOrderPlugin { const bOccurs = occurs(b); if(aOccurs > bOccurs) return -1; if(aOccurs < bOccurs) return 1; - if(a.modules.length > b.modules.length) return -1; - if(a.modules.length < b.modules.length) return 1; - for(let i = 0; i < a.modules.length; i++) { - if(a.modules[i].identifier() > b.modules[i].identifier()) return -1; - if(a.modules[i].identifier() < b.modules[i].identifier()) return 1; - } - return 0; + return a.compareTo(b); }); // TODO refactor to Map chunks.forEach((c) => { diff --git a/lib/optimize/RemoveParentModulesPlugin.js b/lib/optimize/RemoveParentModulesPlugin.js index af4b42dfb..1c25dcf9e 100644 --- a/lib/optimize/RemoveParentModulesPlugin.js +++ b/lib/optimize/RemoveParentModulesPlugin.js @@ -4,18 +4,8 @@ */ "use strict"; -function chunkContainsModule(chunk, module) { - const chunks = module.chunks; - const modules = chunk.modules; - if(chunks.length < modules.length) { - return chunks.indexOf(chunk) >= 0; - } else { - return modules.indexOf(module) >= 0; - } -} - function hasModule(chunk, module, checkedChunks) { - if(chunkContainsModule(chunk, module)) return [chunk]; + if(chunk.containsModule(module)) return [chunk]; if(chunk.parents.length === 0) return false; return allHaveModule(chunk.parents.filter((c) => { return checkedChunks.indexOf(c) < 0; @@ -67,7 +57,7 @@ class RemoveParentModulesPlugin { // TODO consider Map when performance has improved https://gist.github.com/sokra/b36098368da7b8f6792fd7c85fca6311 var cache = Object.create(null); - var modules = chunk.modules.slice(); + var modules = chunk.getModules(); for(var i = 0; i < modules.length; i++) { var module = modules[i]; diff --git a/test/Chunk.test.js b/test/Chunk.test.js index d096dbbfb..0105dae1e 100644 --- a/test/Chunk.test.js +++ b/test/Chunk.test.js @@ -102,7 +102,7 @@ describe("Chunk", () => { }); describe("and the chunk does contain this module", function() { beforeEach(function() { - ChunkInstance.modules = [module]; + ChunkInstance._modules = new Set([module]); }); it("calls module.removeChunk with itself and returns true", function() { ChunkInstance.removeModule(module).should.eql(true); diff --git a/test/statsCases/aggressive-splitting-on-demand/expected.txt b/test/statsCases/aggressive-splitting-on-demand/expected.txt index 288330f7a..89205984e 100644 --- a/test/statsCases/aggressive-splitting-on-demand/expected.txt +++ b/test/statsCases/aggressive-splitting-on-demand/expected.txt @@ -1,4 +1,4 @@ -Hash: 57bbddba5221b9ac4a33 +Hash: 3605a628ea012f7d12ca Time: Xms Asset Size Chunks Chunk Names fc930a2adf8206ea2dc5.js 1.94 kB 0 [emitted] @@ -6,10 +6,10 @@ cd45585186d59208602b.js 1.96 kB 1 [emitted] 6b94c231e016c5aaccdb.js 1.94 kB 2 [emitted] fd0985cee894c4f3f1a6.js 1.94 kB 3 [emitted] d9fc46873c8ea924b895.js 979 bytes 4 [emitted] -beecea47f9a8ded3c298.js 7.63 kB 6 [emitted] main +a773fee259e5a284dea9.js 7.63 kB 6 [emitted] main b08c507d4e1e05cbab45.js 985 bytes 9 [emitted] 5d50e858fe6e559aa47c.js 977 bytes 11 [emitted] -Entrypoint main = beecea47f9a8ded3c298.js +Entrypoint main = a773fee259e5a284dea9.js chunk {0} fc930a2adf8206ea2dc5.js 1.8 kB {6} > aggressive-splitted duplicate [9] (webpack)/test/statsCases/aggressive-splitting-on-demand/index.js 4:0-51 > aggressive-splitted duplicate [9] (webpack)/test/statsCases/aggressive-splitting-on-demand/index.js 5:0-44 @@ -36,7 +36,7 @@ chunk {4} d9fc46873c8ea924b895.js 899 bytes {6} > aggressive-splitted duplicate [9] (webpack)/test/statsCases/aggressive-splitting-on-demand/index.js 2:0-23 > aggressive-splitted duplicate [9] (webpack)/test/statsCases/aggressive-splitting-on-demand/index.js 3:0-30 [2] (webpack)/test/statsCases/aggressive-splitting-on-demand/c.js 899 bytes {4} [built] -chunk {6} beecea47f9a8ded3c298.js (main) 248 bytes [entry] +chunk {6} a773fee259e5a284dea9.js (main) 248 bytes [entry] > main [9] (webpack)/test/statsCases/aggressive-splitting-on-demand/index.js [9] (webpack)/test/statsCases/aggressive-splitting-on-demand/index.js 248 bytes {6} [built] chunk {9} b08c507d4e1e05cbab45.js 899 bytes {6} diff --git a/test/statsCases/named-chunks-plugin-async/webpack.config.js b/test/statsCases/named-chunks-plugin-async/webpack.config.js index 468dcf850..1b81d94fa 100644 --- a/test/statsCases/named-chunks-plugin-async/webpack.config.js +++ b/test/statsCases/named-chunks-plugin-async/webpack.config.js @@ -12,13 +12,13 @@ module.exports = { if(chunk.name) { return chunk.name; } - const modulesToName = (mods) => mods.map((mod) => { + const chunkModulesToName = (chunk) => chunk.mapModules((mod) => { const rs = new RequestShortener(mod.context); return rs.shorten(mod.request).replace(/[.\/\\]/g, "_"); }).join("-"); - if(chunk.modules.length > 0) { - return `chunk-containing-${modulesToName(chunk.modules)}`; + if(chunk.getNumberOfModules() > 0) { + return `chunk-containing-${chunkModulesToName(chunk)}`; } return null; From fba4e81f3a9ed7484b8e60e105df0ad83af490c1 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Tue, 16 May 2017 14:40:37 +0200 Subject: [PATCH 09/40] test next branch too --- .travis.yml | 1 + appveyor.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 90e4f1ef5..3bb6c9c8b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ language: node_js branches: only: - master + - next cache: directories: diff --git a/appveyor.yml b/appveyor.yml index 7375f52f8..0f66a23a0 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -4,6 +4,7 @@ branches: only: - master + - next init: - git config --global core.autocrlf input From 2bd2d2844cf656d7a653464e226d753394894e04 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sat, 20 May 2017 14:46:21 +0200 Subject: [PATCH 10/40] improve a few issues from review by @Kovensky --- lib/Chunk.js | 14 +++++--------- lib/Compilation.js | 4 ++-- lib/HotModuleReplacementPlugin.js | 2 +- lib/LibManifestPlugin.js | 2 +- lib/Module.js | 14 ++++---------- lib/Stats.js | 2 +- lib/UmdMainTemplatePlugin.js | 2 +- lib/optimize/AggressiveSplittingPlugin.js | 2 +- lib/optimize/CommonsChunkPlugin.js | 2 +- lib/optimize/FlagIncludedChunksPlugin.js | 2 +- 10 files changed, 18 insertions(+), 28 deletions(-) diff --git a/lib/Chunk.js b/lib/Chunk.js index 93feb4116..cd7f2fa84 100644 --- a/lib/Chunk.js +++ b/lib/Chunk.js @@ -156,13 +156,7 @@ class Chunk { } mapModules(fn) { - const modules = this._modules; - const array = new Array(modules.size); - let idx = 0; - for(let module of modules) { - array[idx++] = fn(module, idx, modules); - } - return array; + return Array.from(this._modules, fn); } _ensureModulesSorted() { @@ -203,6 +197,7 @@ class Chunk { remove(reason) { // cleanup modules + // Array.from is used here to create a clone, because removeChunk modifies this._modules Array.from(this._modules).forEach(module => { module.removeChunk(this); }); @@ -287,6 +282,7 @@ class Chunk { return false; } + // Array.from is used here to create a clone, because moveModule modifies otherChunk._modules const otherChunkModules = Array.from(otherChunk._modules); otherChunkModules.forEach(module => otherChunk.moveModule(module, this)); otherChunk._modules.clear(); @@ -375,7 +371,7 @@ class Chunk { modulesSize() { let count = 0; - for(let module of this._modules) { + for(const module of this._modules) { count += module.size(); } return count; @@ -393,7 +389,7 @@ class Chunk { let integratedModulesSize = this.modulesSize(); // only count modules that do not exist in this chunk! - for(let otherModule of otherChunk._modules) { + for(const otherModule of otherChunk._modules) { if(!this._modules.has(otherModule)) { integratedModulesSize += otherModule.size(); } diff --git a/lib/Compilation.js b/lib/Compilation.js index 3d563919f..dbc016612 100644 --- a/lib/Compilation.js +++ b/lib/Compilation.js @@ -569,12 +569,12 @@ class Compilation extends Tapable { while(self.applyPluginsBailResult1("optimize-modules-basic", self.modules) || self.applyPluginsBailResult1("optimize-modules", self.modules) || - self.applyPluginsBailResult1("optimize-modules-advanced", self.modules)); // eslint-disable-line no-extra-semi + self.applyPluginsBailResult1("optimize-modules-advanced", self.modules)) { /* empty */ } self.applyPlugins1("after-optimize-modules", self.modules); while(self.applyPluginsBailResult1("optimize-chunks-basic", self.chunks) || self.applyPluginsBailResult1("optimize-chunks", self.chunks) || - self.applyPluginsBailResult1("optimize-chunks-advanced", self.chunks)); // eslint-disable-line no-extra-semi + self.applyPluginsBailResult1("optimize-chunks-advanced", self.chunks)) { /* empty */ } self.applyPlugins1("after-optimize-chunks", self.chunks); self.applyPluginsAsyncSeries("optimize-tree", self.chunks, self.modules, function sealPart2(err) { diff --git a/lib/HotModuleReplacementPlugin.js b/lib/HotModuleReplacementPlugin.js index 5cfdcd380..3a9f731c3 100644 --- a/lib/HotModuleReplacementPlugin.js +++ b/lib/HotModuleReplacementPlugin.js @@ -112,7 +112,7 @@ HotModuleReplacementPlugin.prototype.apply = function(compiler) { chunkId = isNaN(+chunkId) ? chunkId : +chunkId; var currentChunk = this.chunks.find(chunk => chunk.id === chunkId); if(currentChunk) { - var newModules = currentChunk.mapModules(m => m).filter(function(module) { + var newModules = currentChunk.getModules().filter(function(module) { return module.hotUpdate; }); var allModules = {}; diff --git a/lib/LibManifestPlugin.js b/lib/LibManifestPlugin.js index 577882519..db6877978 100644 --- a/lib/LibManifestPlugin.js +++ b/lib/LibManifestPlugin.js @@ -49,7 +49,7 @@ class LibManifestPlugin { }).filter(Boolean).reduce((obj, item) => { obj[item.ident] = item.data; return obj; - }, {}) + }, Object.create(null)) }; const content = new Buffer(JSON.stringify(manifest), "utf8"); //eslint-disable-line compiler.outputFileSystem.mkdirp(path.dirname(targetPath), err => { diff --git a/lib/Module.js b/lib/Module.js index 7f1e83f67..dec871c55 100644 --- a/lib/Module.js +++ b/lib/Module.js @@ -10,7 +10,7 @@ const ModuleReason = require("./ModuleReason"); const Template = require("./Template"); function addToSet(set, items) { - for(let item of items) { + for(const item of items) { if(set.indexOf(item) < 0) set.push(item); } @@ -105,7 +105,7 @@ class Module extends DependenciesBlock { this._ensureChunksSortedByDebugId(); const chunks = this._chunks; const list = []; - for(let chunk of chunks) { + for(const chunk of chunks) { const debugId = chunk.debugId; if(typeof debugId !== "number") { @@ -123,13 +123,7 @@ class Module extends DependenciesBlock { } mapChunks(fn) { - const chunks = this._chunks; - const array = new Array(chunks.size); - let idx = 0; - for(let chunk of chunks) { - array[idx++] = fn(chunk, idx, chunks); - } - return array; + return Array.from(this._chunks, fn); } getNumberOfChunks() { @@ -166,7 +160,7 @@ class Module extends DependenciesBlock { } hasReasonForChunk(chunk) { - for(let r of this.reasons) { + for(const r of this.reasons) { if(r.chunks) { if(r.chunks.indexOf(chunk) >= 0) return true; diff --git a/lib/Stats.js b/lib/Stats.js index 3a266aa18..a2c7f415b 100644 --- a/lib/Stats.js +++ b/lib/Stats.js @@ -336,7 +336,7 @@ class Stats { }; if(showChunkModules) { obj.modules = chunk - .mapModules(m => m) + .getModules() .sort(sortByField("depth")) .filter(createModuleFilter()) .map(fnModule); diff --git a/lib/UmdMainTemplatePlugin.js b/lib/UmdMainTemplatePlugin.js index 1c6ff1b9a..55c21c31a 100644 --- a/lib/UmdMainTemplatePlugin.js +++ b/lib/UmdMainTemplatePlugin.js @@ -32,7 +32,7 @@ class UmdMainTemplatePlugin { apply(compilation) { const mainTemplate = compilation.mainTemplate; compilation.templatesPlugin("render-with-entry", function(source, chunk, hash) { - let externals = chunk.mapModules(m => m).filter(m => m.external); + let externals = chunk.getModules().filter(m => m.external); const optionalExternals = []; let requiredExternals = []; if(this.optionalAmdExternalAsGlobal) { diff --git a/lib/optimize/AggressiveSplittingPlugin.js b/lib/optimize/AggressiveSplittingPlugin.js index b74c859da..50fe99b58 100644 --- a/lib/optimize/AggressiveSplittingPlugin.js +++ b/lib/optimize/AggressiveSplittingPlugin.js @@ -93,7 +93,7 @@ class AggressiveSplittingPlugin { const size = chunk.size(this.options); if(size > maxSize && chunk.getNumberOfModules() > 1) { const newChunk = compilation.addChunk(); - const modules = chunk.mapModules(m => m) + const modules = chunk.getModules() .filter(isNotAEntryModule(chunk.entryModule)) .sort((a, b) => { a = a.identifier(); diff --git a/lib/optimize/CommonsChunkPlugin.js b/lib/optimize/CommonsChunkPlugin.js index f599975b2..b873fba93 100644 --- a/lib/optimize/CommonsChunkPlugin.js +++ b/lib/optimize/CommonsChunkPlugin.js @@ -275,7 +275,7 @@ Take a look at the "name"/"names" or async/children option.`); // count how many chunks contain a module const commonModulesToCountMap = usedChunks.reduce((map, chunk) => { - for(let module of chunk.modulesIterable) { + for(const module of chunk.modulesIterable) { const count = map.has(module) ? map.get(module) : 0; map.set(module, count + 1); } diff --git a/lib/optimize/FlagIncludedChunksPlugin.js b/lib/optimize/FlagIncludedChunksPlugin.js index 23f83b45b..f23eec6e5 100644 --- a/lib/optimize/FlagIncludedChunksPlugin.js +++ b/lib/optimize/FlagIncludedChunksPlugin.js @@ -22,7 +22,7 @@ class FlagIncludedChunksPlugin { if(chunkB.getNumberOfModules() === 0) return; // is chunkB in chunkA? - for(let m of chunkB.modulesIterable) { + for(const m of chunkB.modulesIterable) { if(!chunkA.containsModule(m)) return; } chunkA.ids.push(chunkB.id); From 9b2a9fa7864fd9c4c13435cefa8bf2b60f210913 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 10 May 2017 13:15:14 +0200 Subject: [PATCH 11/40] Scope Hoisting --- examples/scope-hoisting/README.md | 463 +++++++++++++++++ examples/scope-hoisting/build.js | 1 + examples/scope-hoisting/example.js | 6 + examples/scope-hoisting/graph.png | Bin 0 -> 16450 bytes examples/scope-hoisting/graph.svg | 23 + examples/scope-hoisting/graph2.png | Bin 0 -> 20112 bytes examples/scope-hoisting/graph2.svg | 40 ++ examples/scope-hoisting/graph3.png | Bin 0 -> 24897 bytes examples/scope-hoisting/graph3.svg | 46 ++ examples/scope-hoisting/lazy.js | 3 + examples/scope-hoisting/node_modules/a.js | 3 + examples/scope-hoisting/node_modules/b.js | 4 + examples/scope-hoisting/node_modules/c.js | 6 + examples/scope-hoisting/node_modules/cjs.js | 2 + examples/scope-hoisting/node_modules/d.js | 2 + .../scope-hoisting/node_modules/shared.js | 3 + .../scope-hoisting/node_modules/shared2.js | 2 + examples/scope-hoisting/template.md | 118 +++++ lib/Compilation.js | 5 + lib/NormalModule.js | 9 +- lib/optimize/ConcatenatedModule.js | 488 ++++++++++++++++++ lib/optimize/ModuleConcatenationPlugin.js | 209 ++++++++ lib/webpack.js | 1 + package.json | 1 + test/TestCases.test.js | 5 + .../scope-hoisting/chained-reexport/a.js | 1 + .../scope-hoisting/chained-reexport/b.js | 1 + .../scope-hoisting/chained-reexport/c.js | 1 + .../scope-hoisting/chained-reexport/index.js | 5 + .../scope-hoisting/export-namespace/index.js | 16 + .../export-namespace/module1.js | 2 + .../export-namespace/module2.js | 2 + .../scope-hoisting/export-namespace/ns1.js | 2 + .../scope-hoisting/export-namespace/ns2.js | 2 + test/cases/scope-hoisting/reexport-cjs/a.js | 1 + test/cases/scope-hoisting/reexport-cjs/b.js | 1 + test/cases/scope-hoisting/reexport-cjs/c.js | 1 + .../scope-hoisting/reexport-cjs/index.js | 5 + .../scope-hoisting/reexport-exposed-cjs/a.js | 1 + .../scope-hoisting/reexport-exposed-cjs/b.js | 1 + .../scope-hoisting/reexport-exposed-cjs/c.js | 1 + .../reexport-exposed-cjs/index.js | 5 + .../reexport-exposed-default-cjs/a.js | 1 + .../reexport-exposed-default-cjs/b.js | 1 + .../reexport-exposed-default-cjs/c.js | 1 + .../reexport-exposed-default-cjs/index.js | 5 + .../reexport-exposed-harmony/a.js | 1 + .../reexport-exposed-harmony/b.js | 1 + .../reexport-exposed-harmony/c.js | 1 + .../reexport-exposed-harmony/index.js | 5 + test/cases/scope-hoisting/simple/index.js | 6 + test/cases/scope-hoisting/simple/module.js | 2 + 52 files changed, 1510 insertions(+), 2 deletions(-) create mode 100644 examples/scope-hoisting/README.md create mode 100644 examples/scope-hoisting/build.js create mode 100644 examples/scope-hoisting/example.js create mode 100644 examples/scope-hoisting/graph.png create mode 100644 examples/scope-hoisting/graph.svg create mode 100644 examples/scope-hoisting/graph2.png create mode 100644 examples/scope-hoisting/graph2.svg create mode 100644 examples/scope-hoisting/graph3.png create mode 100644 examples/scope-hoisting/graph3.svg create mode 100644 examples/scope-hoisting/lazy.js create mode 100644 examples/scope-hoisting/node_modules/a.js create mode 100644 examples/scope-hoisting/node_modules/b.js create mode 100644 examples/scope-hoisting/node_modules/c.js create mode 100644 examples/scope-hoisting/node_modules/cjs.js create mode 100644 examples/scope-hoisting/node_modules/d.js create mode 100644 examples/scope-hoisting/node_modules/shared.js create mode 100644 examples/scope-hoisting/node_modules/shared2.js create mode 100644 examples/scope-hoisting/template.md create mode 100644 lib/optimize/ConcatenatedModule.js create mode 100644 lib/optimize/ModuleConcatenationPlugin.js create mode 100644 test/cases/scope-hoisting/chained-reexport/a.js create mode 100644 test/cases/scope-hoisting/chained-reexport/b.js create mode 100644 test/cases/scope-hoisting/chained-reexport/c.js create mode 100644 test/cases/scope-hoisting/chained-reexport/index.js create mode 100644 test/cases/scope-hoisting/export-namespace/index.js create mode 100644 test/cases/scope-hoisting/export-namespace/module1.js create mode 100644 test/cases/scope-hoisting/export-namespace/module2.js create mode 100644 test/cases/scope-hoisting/export-namespace/ns1.js create mode 100644 test/cases/scope-hoisting/export-namespace/ns2.js create mode 100644 test/cases/scope-hoisting/reexport-cjs/a.js create mode 100644 test/cases/scope-hoisting/reexport-cjs/b.js create mode 100644 test/cases/scope-hoisting/reexport-cjs/c.js create mode 100644 test/cases/scope-hoisting/reexport-cjs/index.js create mode 100644 test/cases/scope-hoisting/reexport-exposed-cjs/a.js create mode 100644 test/cases/scope-hoisting/reexport-exposed-cjs/b.js create mode 100644 test/cases/scope-hoisting/reexport-exposed-cjs/c.js create mode 100644 test/cases/scope-hoisting/reexport-exposed-cjs/index.js create mode 100644 test/cases/scope-hoisting/reexport-exposed-default-cjs/a.js create mode 100644 test/cases/scope-hoisting/reexport-exposed-default-cjs/b.js create mode 100644 test/cases/scope-hoisting/reexport-exposed-default-cjs/c.js create mode 100644 test/cases/scope-hoisting/reexport-exposed-default-cjs/index.js create mode 100644 test/cases/scope-hoisting/reexport-exposed-harmony/a.js create mode 100644 test/cases/scope-hoisting/reexport-exposed-harmony/b.js create mode 100644 test/cases/scope-hoisting/reexport-exposed-harmony/c.js create mode 100644 test/cases/scope-hoisting/reexport-exposed-harmony/index.js create mode 100644 test/cases/scope-hoisting/simple/index.js create mode 100644 test/cases/scope-hoisting/simple/module.js diff --git a/examples/scope-hoisting/README.md b/examples/scope-hoisting/README.md new file mode 100644 index 000000000..f6996f762 --- /dev/null +++ b/examples/scope-hoisting/README.md @@ -0,0 +1,463 @@ +This example demonstrates Scope Hoisting in combination with Code Splitting. + +This is the dependency graph for the example: (solid lines express sync imports, dashed lines async imports) + +![](graph.png) + +All modules except `cjs` are EcmaScript modules. `cjs` is a CommonJs module. + +The interesting thing here is that putting all modules in single scope won't work, because of multiple reasons: + +* Modules `lazy`, `c`, `d` and `cjs` need to be in a separate chunk +* Module `shared` is accessed by two chunks (difference scopes) +* Module `cjs` is a CommonJs module + +![](graph2.png) + +webpack therefore uses a approach called **"Partial Scope Hoisting"** or "Module concatenation", which chooses the largest possible subsets of ES modules which can be scope hoisted and combines them with the default webpack primitives. + +![](graph3.png) + +While module concatentation identifiers in modules are renamed to avoid conflicts and internal imports are simplified. External imports and exports from the root module use the existing ESM constructs. + +# example.js + +``` javascript +import { a, x, y } from "a"; +import * as b from "b"; + +import("./lazy").then(function(lazy) { + console.log(a, b.a(), x, y, lazy.c, lazy.d.a, lazy.x, lazy.y); +}); +``` + +# lazy.js + +``` javascript +export * from "c"; +import * as d from "d"; +export { d }; +``` + +# a.js + +``` javascript +// module a +export var a = "a"; +export * from "shared"; +``` + +# b.js + +``` javascript +// module b +export function a() { + return "b"; +}; +``` + +# c.js + +``` javascript +// module c +import { c as e } from "cjs"; + +export var c = String.fromCharCode(e.charCodeAt(0) - 2); + +export { x, y } from "shared"; +``` + +# d.js + +``` javascript +// module d +export var a = "d"; +``` + +# cjs.js + +``` javascript +// module cjs (commonjs) +exports.c = "e"; +``` + +# shared.js + +``` javascript +// shared module +export var x = "x"; +export * from "shared2"; +``` + +# shared2.js + +``` javascript +// shared2 module +export var y = "y"; +``` + + + +# webpack.config.js + +``` javascript +var webpack = require("../../"); + +module.exports = { + plugins: [ + new webpack.optimize.ModuleConcatenationPlugin() + ] +}; +``` + + + + +# js/output.js + +
/******/ (function(modules) { /* webpackBootstrap */ }) + +``` javascript +/******/ (function(modules) { // webpackBootstrap +/******/ // install a JSONP callback for chunk loading +/******/ var parentJsonpFunction = window["webpackJsonp"]; +/******/ window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) { +/******/ // add "moreModules" to the modules object, +/******/ // then flag all "chunkIds" as loaded and fire callback +/******/ var moduleId, chunkId, i = 0, resolves = [], result; +/******/ for(;i < chunkIds.length; i++) { +/******/ chunkId = chunkIds[i]; +/******/ if(installedChunks[chunkId]) { +/******/ resolves.push(installedChunks[chunkId][0]); +/******/ } +/******/ installedChunks[chunkId] = 0; +/******/ } +/******/ for(moduleId in moreModules) { +/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { +/******/ modules[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules); +/******/ while(resolves.length) { +/******/ resolves.shift()(); +/******/ } +/******/ +/******/ }; +/******/ +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // objects to store loaded and loading chunks +/******/ var installedChunks = { +/******/ 1: 0 +/******/ }; +/******/ +/******/ var resolvedPromise = new Promise(function(resolve) { resolve(); }); +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ // This file contains only the entry chunk. +/******/ // The chunk loading function for additional chunks +/******/ __webpack_require__.e = function requireEnsure(chunkId) { +/******/ if(installedChunks[chunkId] === 0) { +/******/ return resolvedPromise; +/******/ } +/******/ +/******/ // a Promise means "currently loading". +/******/ if(installedChunks[chunkId]) { +/******/ return installedChunks[chunkId][2]; +/******/ } +/******/ +/******/ // setup Promise in chunk cache +/******/ var promise = new Promise(function(resolve, reject) { +/******/ installedChunks[chunkId] = [resolve, reject]; +/******/ }); +/******/ installedChunks[chunkId][2] = promise; +/******/ +/******/ // start chunk loading +/******/ var head = document.getElementsByTagName('head')[0]; +/******/ var script = document.createElement('script'); +/******/ script.type = 'text/javascript'; +/******/ script.charset = 'utf-8'; +/******/ script.async = true; +/******/ script.timeout = 120000; +/******/ +/******/ if (__webpack_require__.nc) { +/******/ script.setAttribute("nonce", __webpack_require__.nc); +/******/ } +/******/ script.src = __webpack_require__.p + "" + chunkId + ".output.js"; +/******/ var timeout = setTimeout(onScriptComplete, 120000); +/******/ script.onerror = script.onload = onScriptComplete; +/******/ function onScriptComplete() { +/******/ // avoid mem leaks in IE. +/******/ script.onerror = script.onload = null; +/******/ clearTimeout(timeout); +/******/ var chunk = installedChunks[chunkId]; +/******/ if(chunk !== 0) { +/******/ if(chunk) { +/******/ chunk[1](new Error('Loading chunk ' + chunkId + ' failed.')); +/******/ } +/******/ installedChunks[chunkId] = undefined; +/******/ } +/******/ }; +/******/ head.appendChild(script); +/******/ +/******/ return promise; +/******/ }; +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // identity function for calling harmony imports with the correct context +/******/ __webpack_require__.i = function(value) { return value; }; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = "js/"; +/******/ +/******/ // on error function for async loading +/******/ __webpack_require__.oe = function(err) { console.error(err); throw err; }; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 0); +/******/ }) +/************************************************************************/ +``` + +
+ +``` javascript +/******/ ([ +/* 0 */ +/* unknown exports provided */ +/* all exports used */ +/*!********************************!*\ + !*** ./example.js + 2 modules ***! + \********************************/ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); + +// CONCATENAMED MODULE: ./node_modules/a.js +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_shared__ = __webpack_require__(/*! shared */ 1); +// module a +var a = "a"; + + +// CONCATENAMED MODULE: ./node_modules/b.js +// module b +function b_js_a() { + return "b"; +}; + +// CONCATENAMED MODULE: ./example.js + + + +__webpack_require__.e/* import() */(0).then(__webpack_require__.bind(null, /*! ./lazy */ 2)).then(function(lazy) { + console.log(a, b_js_a(), __WEBPACK_IMPORTED_MODULE_0_shared__["x"], __WEBPACK_IMPORTED_MODULE_0_shared__["y"], lazy.c, lazy.d.a, lazy.x, lazy.y); +}); + + +/***/ }), +/* 1 */ +/* exports provided: x, y */ +/* exports used: x, y */ +/*!********************************************!*\ + !*** ./node_modules/shared.js + 1 modules ***! + \********************************************/ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); + +// CONCATENAMED MODULE: ./node_modules/shared2.js +// shared2 module +var y = "y"; + +// CONCATENAMED MODULE: ./node_modules/shared.js +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return x; }); +/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "y", function() { return y; }); +// shared module +var x = "x"; + + + +/***/ }) +/******/ ]); +``` + +# js/0.output.js + +``` javascript +webpackJsonp([0],[ +/* 0 */, +/* 1 */, +/* 2 */ +/* exports provided: d, c, x, y */ +/* all exports used */ +/*!*****************************!*\ + !*** ./lazy.js + 2 modules ***! + \*****************************/ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); + +// CONCATENAMED MODULE: ./node_modules/c.js +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_cjs__ = __webpack_require__(/*! cjs */ 3); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_cjs___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_cjs__); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_shared__ = __webpack_require__(/*! shared */ 1); +// module c + + +var c = String.fromCharCode(__WEBPACK_IMPORTED_MODULE_0_cjs__["c"].charCodeAt(0) - 2); + + + +// CONCATENAMED MODULE: ./node_modules/d.js +var d_js_namespaceObject = {}; +__webpack_require__.d(d_js_namespaceObject, "a", function() { return a; }); +// module d +var a = "d"; + +// CONCATENAMED MODULE: ./lazy.js +/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "c", function() { return c; }); +/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "x", function() { return __WEBPACK_IMPORTED_MODULE_1_shared__["x"]; }); +/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "y", function() { return __WEBPACK_IMPORTED_MODULE_1_shared__["y"]; }); +/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "d", function() { return d_js_namespaceObject; }); + + + + + +/***/ }), +/* 3 */ +/* unknown exports provided */ +/* exports used: c */ +/*!*****************************!*\ + !*** ./node_modules/cjs.js ***! + \*****************************/ +/***/ (function(module, exports) { + +// module cjs (commonjs) +exports.c = "e"; + + +/***/ }) +]); +``` + +Minimized + +``` javascript +webpackJsonp([0],[,,function(n,r,t){"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=t(3),u=(t.n(e),t(1)),c=String.fromCharCode(e.c.charCodeAt(0)-2),o={};t.d(o,"a",function(){return d});var d="d";t.d(r,"c",function(){return c}),t.d(r,"x",function(){return u.x}),t.d(r,"y",function(){return u.y}),t.d(r,"d",function(){return o})},function(n,r){r.c="e"}]); +``` + +# Info + +## Uncompressed + +``` +Hash: 383b132e31f349cdb930 +Version: webpack 2.5.1 + Asset Size Chunks Chunk Names +0.output.js 1.85 kB 0 [emitted] + output.js 7.53 kB 1 [emitted] main +Entrypoint main = output.js +chunk {0} 0.output.js 276 bytes {1} [rendered] + > [4] 4:0-16 + [2] ./lazy.js + 2 modules 232 bytes {0} [built] + [exports: d, c, x, y] + [no exports used] + import() ./lazy [4] ./example.js 4:0-16 + [3] ./node_modules/cjs.js 44 bytes {0} [built] + [only some exports used: c] + harmony import cjs [8] ./node_modules/c.js 2:0-29 +chunk {1} output.js (main) 385 bytes [entry] [rendered] + > main [4] + [0] ./example.js + 2 modules 280 bytes {1} [built] + [no exports used] + [1] ./node_modules/shared.js + 1 modules 105 bytes {1} [built] + [exports: x, y] + [no exports used] + harmony import shared [6] ./node_modules/a.js 3:0-23 + harmony import shared [8] ./node_modules/c.js 6:0-30 +``` + +## Minimized (uglify-js, no zip) + +``` +Hash: 383b132e31f349cdb930 +Version: webpack 2.5.1 + Asset Size Chunks Chunk Names +0.output.js 379 bytes 0 [emitted] + output.js 1.73 kB 1 [emitted] main +Entrypoint main = output.js +chunk {0} 0.output.js 276 bytes {1} [rendered] + > [4] 4:0-16 + [2] ./lazy.js + 2 modules 232 bytes {0} [built] + [exports: d, c, x, y] + [no exports used] + import() ./lazy [4] ./example.js 4:0-16 + [3] ./node_modules/cjs.js 44 bytes {0} [built] + [only some exports used: c] + harmony import cjs [8] ./node_modules/c.js 2:0-29 +chunk {1} output.js (main) 385 bytes [entry] [rendered] + > main [4] + [0] ./example.js + 2 modules 280 bytes {1} [built] + [no exports used] + [1] ./node_modules/shared.js + 1 modules 105 bytes {1} [built] + [exports: x, y] + [no exports used] + harmony import shared [6] ./node_modules/a.js 3:0-23 + harmony import shared [8] ./node_modules/c.js 6:0-30 +``` diff --git a/examples/scope-hoisting/build.js b/examples/scope-hoisting/build.js new file mode 100644 index 000000000..41c29c9d1 --- /dev/null +++ b/examples/scope-hoisting/build.js @@ -0,0 +1 @@ +require("../build-common"); \ No newline at end of file diff --git a/examples/scope-hoisting/example.js b/examples/scope-hoisting/example.js new file mode 100644 index 000000000..1db9365cf --- /dev/null +++ b/examples/scope-hoisting/example.js @@ -0,0 +1,6 @@ +import { a, x, y } from "a"; +import * as b from "b"; + +import("./lazy").then(function(lazy) { + console.log(a, b.a(), x, y, lazy.c, lazy.d.a, lazy.x, lazy.y); +}); diff --git a/examples/scope-hoisting/graph.png b/examples/scope-hoisting/graph.png new file mode 100644 index 0000000000000000000000000000000000000000..46c6fbf9f4a4c54534abd23c79d13fae0a917e29 GIT binary patch literal 16450 zcmaL91yCJP*DV;qf@=s4L4yXj;10o^;9T52IKdq*8rurW1rc_n3PXX<3+VhSQR_8_-#adF^dVR5iAvU72@wP7}~x5fI*OAL&_ z;i;zO@;~jbUVYCnjZswW62|O3Nxvo8o+oY2mH2aM7#2o2DQWyV)@(7xRK7*-8Y9=& zvyq94zIgd&WjK9Rm#8SpcAsc{Eu1ry&<82N>-49e=~ia%sOU**7sPqAW7X}_JXNK) zye)Tni}S&*rN%EbX+8T`F0z~*zxZ}iVN^L$fJ=Ms>rdOXKUhiID#FtF$~^gN^IrYf zDzlGYE8`(Fe$wHOq)J*8%%4R)ii8A6MYTp-*GEsDK)gSsjE}n}__pIAZpDXL@FGnU(@$j(l;PE8BMr)oC5+mJ?n^-Onj-BTI{>8)~dBoOjkLrhqZ~e3LL~SgBSgc=Jv#Y;&hG7KgZZ?n|5E1Wwp?)wL8A*!@IDc!@q>zraG;qA}jJ{Q~ ztB-??xLB++I^v||wqWW5UMzAJ^csEe%GV9Y)>XusV^Xi}1i>e+%YQpf&@E1)E#@!$ z$=`FGNeo+#Z$Yu#nJ7)pHs$yIwoeeif#4VQYIn$}f6_KNS0=$EYR@*4*ZEUk=(t`y zvGLpBt@A*AB;|&U^V=V8Ya~)};&I09r^ctso8M&{Jl!5_BudRKk^`-64ET$#l(2oY zHBsVHI+oxk5YrlEjZX{&p8Lt}7U*J6b_^fpQLcmU73$LPXH32fd8);Rr?TtGHXsTg zeRw|=d$Pg;^Zl@w+Jn>j#(=mY!su=_pRCq5_W%KeV?zOXxMfd&s*#s)h zm1D8I!DJH;IWneF!z>aAQ)lUT@m$w29!Rxaj9dQEn|(CGHsiGC(INeO@E)X%y+}2s zIG+A`YFqqmuJDoYAMti8_1`R)*GG#OWP$~t7u#tk3AZoZ*VdEl*l8jdDn%>G8v4h2 z3d~pM!n6u>QmgTH7kGrU7^ZZS`@q@%Qq|9n?HLiGc2(a=jf0Jc&hp>u3x4ZUYm)h~!I{RkIsknco-#eqDY>uow zGyG*)Nu(p?b0&ucc93oprM+{=k^`VzB()7I+t zsRxIP&R;|mZ8qaLR$S_HOq{7ImgdfT(Zh;}64=x4sNP|kf)nS05Y zVIF@CI&PGFaMzY)MdTI%88pzVV^406I&~C&_QUnw-;#;%n+`Xr=iO&f5D44zpGsE< zg|Ks`8@VDGd-{kU!N_|YoP?sMQw43&vMpU=`-tT-gKCX~_B1(x;Q0rM2@!b`<$QQg zl`5uUma*aCO^l@lYNEiOJ)O>ReZJ@Owpt7Msl*ur+g7^WAwt&$E~@Z&e<*ld%Q0@VQvb z70DmG!wJ#Uq^5rY6VAZJ=%9O081atgQCYxN86H{^Jx=b92Ldl?Gi%l7PZ{r!LsjJ5tD`ej|cRy z-u0lMAk|_8b#?VUR$J@HLoYl{$BejiE9yfqr4Zw%aKqJ)+%6|8!HoHAuiPCSd2T5) zKH;jV7b}d_{rbMALj1tHqM=R=u?JVp�(AJrD9(hK>v)&^zSxP|r-c6~uO!Jy`r9 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 FzW^*lkWByp literal 0 HcmV?d00001 diff --git a/examples/scope-hoisting/graph.svg b/examples/scope-hoisting/graph.svg new file mode 100644 index 000000000..c18b625de --- /dev/null +++ b/examples/scope-hoisting/graph.svg @@ -0,0 +1,23 @@ +exampleabsharedshared2lazycdcjs \ No newline at end of file diff --git a/examples/scope-hoisting/graph2.png b/examples/scope-hoisting/graph2.png new file mode 100644 index 0000000000000000000000000000000000000000..d8e410d5a9b1204d8b717495cd00c14100ab8d08 GIT binary patch literal 20112 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 Z*AFfoD~N7C3slT)bFgu-uD0~O_zz!M2x|ZU literal 0 HcmV?d00001 diff --git a/examples/scope-hoisting/graph2.svg b/examples/scope-hoisting/graph2.svg new file mode 100644 index 000000000..bda1a325b --- /dev/null +++ b/examples/scope-hoisting/graph2.svg @@ -0,0 +1,40 @@ +Chunk AChunk Bexampleabsharedshared2lazycdcjs \ No newline at end of file diff --git a/examples/scope-hoisting/graph3.png b/examples/scope-hoisting/graph3.png new file mode 100644 index 0000000000000000000000000000000000000000..d7075f91013d55b9e392848f89564f21eee3e08b GIT binary patch literal 24897 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

G&ty-`)?YlM25LE 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 R_@4-PP&rlEVrk=m{{i@#-LC)u literal 0 HcmV?d00001 diff --git a/examples/scope-hoisting/graph3.svg b/examples/scope-hoisting/graph3.svg new file mode 100644 index 000000000..c7f81ae7b --- /dev/null +++ b/examples/scope-hoisting/graph3.svg @@ -0,0 +1,46 @@ +Chunk AScope 1Scope 2Chunk BScope 3exampleabsharedshared2cjslazycd \ No newline at end of file diff --git a/examples/scope-hoisting/lazy.js b/examples/scope-hoisting/lazy.js new file mode 100644 index 000000000..f79a25dbb --- /dev/null +++ b/examples/scope-hoisting/lazy.js @@ -0,0 +1,3 @@ +export * from "c"; +import * as d from "d"; +export { d }; diff --git a/examples/scope-hoisting/node_modules/a.js b/examples/scope-hoisting/node_modules/a.js new file mode 100644 index 000000000..589bfadc4 --- /dev/null +++ b/examples/scope-hoisting/node_modules/a.js @@ -0,0 +1,3 @@ +// module a +export var a = "a"; +export * from "shared"; diff --git a/examples/scope-hoisting/node_modules/b.js b/examples/scope-hoisting/node_modules/b.js new file mode 100644 index 000000000..3b7c9a0c6 --- /dev/null +++ b/examples/scope-hoisting/node_modules/b.js @@ -0,0 +1,4 @@ +// module b +export function a() { + return "b"; +}; diff --git a/examples/scope-hoisting/node_modules/c.js b/examples/scope-hoisting/node_modules/c.js new file mode 100644 index 000000000..5db6ace1f --- /dev/null +++ b/examples/scope-hoisting/node_modules/c.js @@ -0,0 +1,6 @@ +// module c +import { c as e } from "cjs"; + +export var c = String.fromCharCode(e.charCodeAt(0) - 2); + +export { x, y } from "shared"; diff --git a/examples/scope-hoisting/node_modules/cjs.js b/examples/scope-hoisting/node_modules/cjs.js new file mode 100644 index 000000000..8a001e65b --- /dev/null +++ b/examples/scope-hoisting/node_modules/cjs.js @@ -0,0 +1,2 @@ +// module cjs (commonjs) +exports.c = "e"; diff --git a/examples/scope-hoisting/node_modules/d.js b/examples/scope-hoisting/node_modules/d.js new file mode 100644 index 000000000..f4e177035 --- /dev/null +++ b/examples/scope-hoisting/node_modules/d.js @@ -0,0 +1,2 @@ +// module d +export var a = "d"; diff --git a/examples/scope-hoisting/node_modules/shared.js b/examples/scope-hoisting/node_modules/shared.js new file mode 100644 index 000000000..2600e2340 --- /dev/null +++ b/examples/scope-hoisting/node_modules/shared.js @@ -0,0 +1,3 @@ +// shared module +export var x = "x"; +export * from "shared2"; diff --git a/examples/scope-hoisting/node_modules/shared2.js b/examples/scope-hoisting/node_modules/shared2.js new file mode 100644 index 000000000..38ea5bd24 --- /dev/null +++ b/examples/scope-hoisting/node_modules/shared2.js @@ -0,0 +1,2 @@ +// shared2 module +export var y = "y"; diff --git a/examples/scope-hoisting/template.md b/examples/scope-hoisting/template.md new file mode 100644 index 000000000..ff01791a1 --- /dev/null +++ b/examples/scope-hoisting/template.md @@ -0,0 +1,118 @@ +This example demonstrates Scope Hoisting in combination with Code Splitting. + +This is the dependency graph for the example: (solid lines express sync imports, dashed lines async imports) + +![](graph.png) + +All modules except `cjs` are EcmaScript modules. `cjs` is a CommonJs module. + +The interesting thing here is that putting all modules in single scope won't work, because of multiple reasons: + +* Modules `lazy`, `c`, `d` and `cjs` need to be in a separate chunk +* Module `shared` is accessed by two chunks (different scopes) +* Module `cjs` is a CommonJs module + +![](graph2.png) + +webpack therefore uses a approach called **"Partial Scope Hoisting"** or "Module concatenation", which chooses the largest possible subsets of ES modules which can be scope hoisted and combines them with the default webpack primitives. + +![](graph3.png) + +While module concatentation identifiers in modules are renamed to avoid conflicts and internal imports are simplified. External imports and exports from the root module use the existing ESM constructs. + +# example.js + +``` javascript +{{example.js}} +``` + +# lazy.js + +``` javascript +{{lazy.js}} +``` + +# a.js + +``` javascript +{{node_modules/a.js}} +``` + +# b.js + +``` javascript +{{node_modules/b.js}} +``` + +# c.js + +``` javascript +{{node_modules/c.js}} +``` + +# d.js + +``` javascript +{{node_modules/d.js}} +``` + +# cjs.js + +``` javascript +{{node_modules/cjs.js}} +``` + +# shared.js + +``` javascript +{{node_modules/shared.js}} +``` + +# shared2.js + +``` javascript +{{node_modules/shared2.js}} +``` + + + +# webpack.config.js + +``` javascript +{{webpack.config.js}} +``` + + + + +# js/output.js + +``` javascript +{{js/output.js}} +``` + +# js/0.output.js + +``` javascript +{{js/0.output.js}} +``` + +Minimized + +``` javascript +{{min:js/0.output.js}} +``` + +# Info + +## Uncompressed + +``` +{{stdout}} +``` + +## Minimized (uglify-js, no zip) + +``` +{{min:stdout}} +``` diff --git a/lib/Compilation.js b/lib/Compilation.js index dbc016612..9287e7d48 100644 --- a/lib/Compilation.js +++ b/lib/Compilation.js @@ -584,6 +584,11 @@ class Compilation extends Tapable { self.applyPlugins2("after-optimize-tree", self.chunks, self.modules); + while(self.applyPluginsBailResult("optimize-chunk-modules-basic", self.chunks, self.modules) || + self.applyPluginsBailResult("optimize-chunk-modules", self.chunks, self.modules) || + self.applyPluginsBailResult("optimize-chunk-modules-advanced", self.chunks, self.modules)); // eslint-disable-line no-extra-semi + self.applyPlugins2("after-optimize-chunk-modules", self.chunks, self.modules); + const shouldRecord = self.applyPluginsBailResult("should-record") !== false; self.applyPlugins2("revive-modules", self.modules, self.records); diff --git a/lib/NormalModule.js b/lib/NormalModule.js index 94085a311..381bddaef 100644 --- a/lib/NormalModule.js +++ b/lib/NormalModule.js @@ -74,6 +74,7 @@ class NormalModule extends Module { this.assets = {}; this.built = false; this._cachedSource = null; + this._dependencyTemplatesHashMap = new Map(); } identifier() { @@ -301,9 +302,13 @@ class NormalModule extends Module { }); } - getHashDigest() { + getHashDigest(dependencyTemplates) { + let dtId = this._dependencyTemplatesHashMap.get(dependencyTemplates); + if(dtId === undefined) + this._dependencyTemplatesHashMap.set(dependencyTemplates, dtId = this._dependencyTemplatesHashMap.size + 1); const hash = crypto.createHash("md5"); this.updateHash(hash); + hash.update(`${dtId}`); return hash.digest("hex"); } @@ -437,7 +442,7 @@ class NormalModule extends Module { } source(dependencyTemplates, outputOptions, requestShortener) { - const hashDigest = this.getHashDigest(); + const hashDigest = this.getHashDigest(dependencyTemplates); if(this._cachedSource && this._cachedSource.hash === hashDigest) { return this._cachedSource.source; } diff --git a/lib/optimize/ConcatenatedModule.js b/lib/optimize/ConcatenatedModule.js new file mode 100644 index 000000000..17fe066c1 --- /dev/null +++ b/lib/optimize/ConcatenatedModule.js @@ -0,0 +1,488 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +"use strict"; + +const Module = require("../Module"); +const Template = require("../Template"); +const acorn = require("acorn"); +const escope = require("escope"); +const ReplaceSource = require("webpack-sources/lib/ReplaceSource"); +const ConcatSource = require("webpack-sources/lib/ConcatSource"); +const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency"); +const HarmonyImportSpecifierDependency = require("../dependencies/HarmonyImportSpecifierDependency"); +const HarmonyExportSpecifierDependency = require("../dependencies/HarmonyExportSpecifierDependency"); +const HarmonyExportExpressionDependency = require("../dependencies/HarmonyExportExpressionDependency"); +const HarmonyExportImportedSpecifierDependency = require("../dependencies/HarmonyExportImportedSpecifierDependency"); +const HarmonyCompatibilityDependency = require("../dependencies/HarmonyCompatibilityDependency"); +const HarmonyModulesHelpers = require("../dependencies/HarmonyModulesHelpers"); + +function getFinalName(info, exportName, moduleToInfoMap, requestShortener) { + const directExport = info.exportMap.get(exportName); + if(directExport) { + if(exportName === true) + info.needNamespaceObject = true; + return info.internalNames.get(directExport); + } + const reexport = info.reexportMap.get(exportName); + if(reexport) { + const refInfo = moduleToInfoMap.get(reexport.module); + if(refInfo) { + // module is in the concatenation + return getFinalName(refInfo, reexport.exportName, moduleToInfoMap, requestShortener); + } else { + const dep = reexport.dependency; + const importedModule = reexport.module; + const exportName = reexport.exportName; + const isNotAHarmonyModule = !(importedModule && (!importedModule.meta || importedModule.meta.harmonyModule)); + const importedVar = dep.importedVar; + const used = importedModule.isUsed(exportName); + if(!used) return "/* unused reexport */undefined"; + if(isNotAHarmonyModule && exportName === "default") { + return `${importedVar}_default.a`; + } + return `${importedVar}[${JSON.stringify(used)}]`; + } + } + throw new Error(`Cannot get final name for export "${exportName}" in "${info.module.readableIdentifier(requestShortener)}"` + + ` (known exports: ${Array.from(info.exportMap.keys()).join(" ")}, ` + + `known reexports: ${Array.from(info.reexportMap.keys()).join(" ")})`); +} + +class ConcatenatedModule extends Module { + constructor(rootModule, modules) { + super(); + this.rootModule = rootModule; + this.modules = modules; + this.usedExports = rootModule.usedExports; + this.providedExports = rootModule.providedExports; + this._chunks = new Set(rootModule._chunks); + this.index = rootModule.index; + this.index2 = rootModule.index2; + this.depth = rootModule.depth; + this.built = modules.some(m => m.built); + this.cacheable = modules.every(m => m.cacheable); + const modulesSet = new Set(modules); + this.reasons = rootModule.reasons.filter(reason => !modulesSet.has(reason.module)); + this.meta = rootModule.meta; + this.dependenciesWarnings = modules.reduce((w, m) => m.dependenciesWarnings.forEach(x => w.push(x)), []); + this.dependenciesErrors = modules.reduce((w, m) => m.dependenciesErrors.forEach(x => w.push(x)), []); + this.warnings = modules.reduce((w, m) => m.warnings.forEach(x => w.push(x)), []); + this.errors = modules.reduce((w, m) => m.errors.forEach(x => w.push(x)), []); + this.moduleArgument = rootModule.moduleArgument; + this.exportsArgument = rootModule.exportsArgument; + this.strict = true; + modules.forEach((m, idx) => { + for(const dep of m.dependencies.filter(dep => !modulesSet.has(dep.module))) { + this.dependencies.push(dep); + } + }); + } + + identifier() { + return this.modules.map(m => m.identifier()).join(" "); + } + + readableIdentifier(requestShortener) { + return this.rootModule.readableIdentifier(requestShortener) + ` + ${this.modules.length - 1} modules`; + } + + libIdent(options) { + return this.modules.map(m => m.libIdent(options)).join(" "); + } + + nameForCondition() { + return this.rootModule.nameForCondition(); + } + + build(options, compilation, resolver, fs, callback) { + throw new Error("Cannot build this module. It should be already built."); + } + + size() { + // Guess size from embedded modules + return this.modules.reduce((sum, m) => sum + m.size(), 0); + } + + source(dependencyTemplates, outputOptions, requestShortener) { + const modulesSet = new Set(); + this.modules.forEach(m => modulesSet.add(m)); + + // Metainfo for each module + const modulesWithInfo = this.modules.map((m, idx) => { + const exportMap = new Map(); + const reexportMap = new Map(); + m.dependencies.forEach(dep => { + if(dep instanceof HarmonyExportSpecifierDependency) { + exportMap.set(dep.name, dep.id); + } else if(dep instanceof HarmonyExportExpressionDependency) { + exportMap.set("default", "__WEBPACK_MODULE_DEFAULT_EXPORT__"); + } else if(dep instanceof HarmonyExportImportedSpecifierDependency) { + const exportName = dep.name; + const importName = dep.id; + const importModule = dep.importDependency.module; + const innerReexport = modulesSet.has(importModule); + if(exportName && importName) { + reexportMap.set(exportName, { + module: importModule, + exportName: importName, + dependency: dep + }); + } else if(exportName) { + reexportMap.set(exportName, { + module: importModule, + exportName: true, + dependency: dep + }); + } else if(Array.isArray(importModule.providedExports)) { + var activeExports = new Set(HarmonyModulesHelpers.getActiveExports(dep.originModule, dep)); + importModule.providedExports.forEach(name => { + if(activeExports.has(name) || name === "default") + return; + reexportMap.set(name, { + module: importModule, + exportName: name, + dependency: dep + }); + }); + } else if(innerReexport) { + throw new Error(`Module "${importModule.readableIdentifier(requestShortener)}" doesn't provide static exports for "export *" in ${m.readableIdentifier(requestShortener)}`); + } + } + }); + return { + module: m, + index: idx, + source: undefined, + globalScope: undefined, + moduleScope: undefined, + internalNames: new Map(), + exportMap: exportMap, + reexportMap: reexportMap, + needCompatibilityFlag: false, + needNamespaceObject: false + }; + }); + + // Create mapping from module to info + const moduleToInfoMap = new Map(); + modulesWithInfo.forEach(m => moduleToInfoMap.set(m.module, m)); + + // Configure template decorators for dependencies + const innerDependencyTemplates = new Map(dependencyTemplates); + + innerDependencyTemplates.set(HarmonyImportSpecifierDependency, new HarmonyImportSpecifierDependencyConcatenatedTemplate( + dependencyTemplates.get(HarmonyImportSpecifierDependency), + moduleToInfoMap + )); + innerDependencyTemplates.set(HarmonyImportDependency, new HarmonyImportDependencyConcatenatedTemplate( + dependencyTemplates.get(HarmonyImportDependency), + moduleToInfoMap + )); + innerDependencyTemplates.set(HarmonyExportSpecifierDependency, new HarmonyExportSpecifierDependencyConcatenatedTemplate( + dependencyTemplates.get(HarmonyExportSpecifierDependency), + this.rootModule + )); + innerDependencyTemplates.set(HarmonyExportExpressionDependency, new HarmonyExportExpressionDependencyConcatenatedTemplate( + dependencyTemplates.get(HarmonyExportExpressionDependency), + this.rootModule, + moduleToInfoMap + )); + innerDependencyTemplates.set(HarmonyExportImportedSpecifierDependency, new HarmonyExportImportedSpecifierDependencyConcatenatedTemplate( + dependencyTemplates.get(HarmonyExportImportedSpecifierDependency), + this.rootModule, + moduleToInfoMap + )); + innerDependencyTemplates.set(HarmonyCompatibilityDependency, new HarmonyCompatibilityDependencyConcatenatedTemplate( + dependencyTemplates.get(HarmonyCompatibilityDependency), + this.rootModule, + moduleToInfoMap + )); + + // Generate source code and analyse scopes + // Prepare a ReplaceSource for the final source + modulesWithInfo.forEach(info => { + const m = info.module; + const source = m.source(innerDependencyTemplates, outputOptions, requestShortener); + const code = source.source(); + const ast = acorn.parse(code, { + ranges: true, + locations: true, + ecmaVersion: 2017, + sourceType: "module" + }); + const scopeManager = escope.analyze(ast, { + ecmaVersion: 6, + sourceType: "module", + optimistic: true, + ignoreEval: true, + impliedStrict: true + }); + const globalScope = scopeManager.acquire(ast); + const moduleScope = globalScope.childScopes[0]; + const resultSource = new ReplaceSource(m.source(innerDependencyTemplates, outputOptions, requestShortener)); + info.source = resultSource; + info.globalScope = globalScope; + info.moduleScope = moduleScope; + }); + + // List of all used names to avoid conflicts + const allUsedNames = new Set(["__WEBPACK_MODULE_DEFAULT_EXPORT__", "defaultExport", "Object"]); + + // get all global names + modulesWithInfo.forEach(info => { + info.globalScope.through.map(reference => reference.identifier.name).forEach(name => { + if(!/^__WEBPACK_MODULE_REFERENCE__\d+_(\d+|ns)__$/.test(name)) + allUsedNames.add(name); + }); + }); + + modulesWithInfo.forEach(info => { + const namespaceObjectName = this.findNewName("namespaceObject", allUsedNames, info.module.readableIdentifier(requestShortener)); + info.internalNames.set(namespaceObjectName, namespaceObjectName); + info.exportMap.set(true, namespaceObjectName); + info.moduleScope.variables.forEach(variable => { + let name = variable.name; + if(allUsedNames.has(name)) { + const newName = this.findNewName(name, allUsedNames, info.module.readableIdentifier(requestShortener)); + allUsedNames.add(newName); + info.internalNames.set(name, newName); + const source = info.source; + const allIdentifiers = new Set(variable.references.map(r => r.identifier).concat(variable.identifiers)); + for(const identifier of allIdentifiers) { + const r = identifier.range; + source.replace(r[0], r[1] - 1, newName); + } + } else { + allUsedNames.add(name); + info.internalNames.set(name, name); + } + }); + }); + + modulesWithInfo.forEach(info => { + info.globalScope.through.forEach(reference => { + const name = reference.identifier.name; + const match = /^__WEBPACK_MODULE_REFERENCE__(\d+)_(\d+|ns)__$/.exec(name); + if(match) { + const referencedModule = modulesWithInfo[+match[1]]; + let exportName; + if(match[2] === "ns") { + exportName = true; + } else { + const exportIdx = +match[2]; + exportName = referencedModule.module.providedExports[exportIdx]; + } + const finalName = getFinalName(referencedModule, exportName, moduleToInfoMap, requestShortener); + if(!finalName) + throw new Error(`Cannot map to variable name in module ${info.module.resource} (export '${exportName}')`); + const r = reference.identifier.range; + const source = info.source; + source.replace(r[0], r[1] - 1, finalName); + } + }); + }); + + const result = new ConcatSource(); + if(moduleToInfoMap.get(this.rootModule).needCompatibilityFlag) { + result.add(`Object.defineProperty(${this.rootModule.moduleArgument || "exports"}, "__esModule", { value: true });\n`); + } + modulesWithInfo.forEach(info => { + result.add(`\n// CONCATENAMED MODULE: ${info.module.readableIdentifier(requestShortener)}\n`); + if(info.needNamespaceObject) { + const name = info.exportMap.get(true); + const nsObj = [`var ${name} = {};`]; + for(const exportName of info.module.providedExports) { + const finalName = getFinalName(info, exportName, moduleToInfoMap, requestShortener); + nsObj.push(`__webpack_require__.d(${name}, ${JSON.stringify(exportName)}, function() { return ${finalName}; });`); + } + result.add(nsObj.join("\n") + "\n"); + } + result.add(info.source); + }); + + return result; + } + + findNewName(oldName, usedNamed, extraInfo) { + let name = oldName; + + if(name === "__WEBPACK_MODULE_DEFAULT_EXPORT__") + name = "defaultExport"; + + const splittedInfo = extraInfo.split("/"); + while(splittedInfo.length) { + name = splittedInfo.pop() + "_" + name; + if(!usedNamed.has(Template.toIdentifier(name))) return Template.toIdentifier(name); + } + + while(!usedNamed.has(name = name + "_")); + return name; + } + +} + +class HarmonyImportSpecifierDependencyConcatenatedTemplate { + constructor(originalTemplate, modulesMap) { + this.originalTemplate = originalTemplate; + this.modulesMap = modulesMap; + } + + apply(dep, source, outputOptions, requestShortener, dependencyTemplates) { + const module = dep.importDependency.module; + const info = this.modulesMap.get(module); + if(!info) { + this.originalTemplate.apply(dep, source, outputOptions, requestShortener, dependencyTemplates); + return; + } + if(!Array.isArray(module.providedExports)) + throw new Error(`Module ${module.resource} has no static exports ${module.providedExports}`); + let content; + if(dep.id === null) { + content = `__WEBPACK_MODULE_REFERENCE__${info.index}_ns__`; + } else { + const exportIdx = (module.providedExports).indexOf(dep.id); + content = exportIdx === -1 ? "undefined" : `__WEBPACK_MODULE_REFERENCE__${info.index}_${exportIdx}__`; + } + if(dep.shorthand) { + content = dep.name + ": " + content; + } + source.replace(dep.range[0], dep.range[1] - 1, content); + } +} + +class HarmonyImportDependencyConcatenatedTemplate { + constructor(originalTemplate, modulesMap) { + this.originalTemplate = originalTemplate; + this.modulesMap = modulesMap; + } + + apply(dep, source, outputOptions, requestShortener, dependencyTemplates) { + const module = dep.module; + const info = this.modulesMap.get(module); + if(!info) { + this.originalTemplate.apply(dep, source, outputOptions, requestShortener, dependencyTemplates); + return; + } + source.replace(dep.range[0], dep.range[1] - 1, ""); + } +} + +class HarmonyExportSpecifierDependencyConcatenatedTemplate { + constructor(originalTemplate, rootModule) { + this.originalTemplate = originalTemplate; + this.rootModule = rootModule; + } + + apply(dep, source, outputOptions, requestShortener, dependencyTemplates) { + if(dep.originModule === this.rootModule) { + this.originalTemplate.apply(dep, source, outputOptions, requestShortener, dependencyTemplates); + } + } +} + +class HarmonyExportExpressionDependencyConcatenatedTemplate { + constructor(originalTemplate, rootModule) { + this.originalTemplate = originalTemplate; + this.rootModule = rootModule; + } + + apply(dep, source, outputOptions, requestShortener, dependencyTemplates) { + if(dep.originModule === this.rootModule) { + this.originalTemplate.apply(dep, source, outputOptions, requestShortener, dependencyTemplates); + } else { + const content = "/* harmony default export */ var __WEBPACK_MODULE_DEFAULT_EXPORT__ = "; + + if(dep.range) { + source.replace(dep.rangeStatement[0], dep.range[0] - 1, content + "("); + source.replace(dep.range[1], dep.rangeStatement[1] - 1, ");"); + return; + } + + source.replace(dep.rangeStatement[0], dep.rangeStatement[1] - 1, content); + } + } +} + +class HarmonyExportImportedSpecifierDependencyConcatenatedTemplate { + constructor(originalTemplate, rootModule, modulesMap) { + this.originalTemplate = originalTemplate; + this.rootModule = rootModule; + this.modulesMap = modulesMap; + } + + getExports(dep) { + const active = HarmonyModulesHelpers.isActive(dep.originModule, dep); + if(!active) return []; + const importModule = dep.importDependency.module; + if(dep.id) { + // export { named } from "module" + return [{ + name: dep.name, + id: dep.id, + module: importModule + }]; + } + if(dep.name) { + // export * as abc from "module" + return [{ + name: dep.name, + id: true, + module: importModule + }]; + } + // export * from "module" + const activeExports = new Set(HarmonyModulesHelpers.getActiveExports(dep.originModule, dep)); + return importModule.providedExports.filter(exp => exp !== "default" && !activeExports.has(exp)).map(exp => { + return { + name: exp, + id: exp, + module: importModule + }; + }); + } + + apply(dep, source, outputOptions, requestShortener, dependencyTemplates) { + if(dep.originModule === this.rootModule) { + if(this.modulesMap.get(dep.importDependency.module)) { + const exportDefs = this.getExports(dep); + exportDefs.forEach(def => { + const info = this.modulesMap.get(def.module); + const used = dep.originModule.isUsed(def.name); + if(!used) { + source.insert(-1, `/* unused concated harmony import ${dep.name} */\n`); + } + let finalName; + if(def.id === true) { + finalName = `__WEBPACK_MODULE_REFERENCE__${info.index}_ns__`; + } else { + const exportIdx = def.module.providedExports.indexOf(def.id); + finalName = exportIdx < 0 ? "undefined" : `__WEBPACK_MODULE_REFERENCE__${info.index}_${exportIdx}__`; + } + const exportsName = this.rootModule.exportsArgument || "exports"; + const content = `/* concated harmony reexport */__webpack_require__.d(${exportsName}, ${JSON.stringify(def.name)}, function() { return ${finalName}; });\n`; + source.insert(-1, content); + }); + } else { + this.originalTemplate.apply(dep, source, outputOptions, requestShortener, dependencyTemplates); + } + } + } +} + +class HarmonyCompatibilityDependencyConcatenatedTemplate { + constructor(originalTemplate, rootModule, modulesMap) { + this.originalTemplate = originalTemplate; + this.rootModule = rootModule; + this.modulesMap = modulesMap; + } + + apply(dep, source, outputOptions, requestShortener, dependencyTemplates) { + if(dep.originModule === this.rootModule) { + this.modulesMap.get(this.rootModule).needCompatibilityFlag = true; + } + } +} + +module.exports = ConcatenatedModule; diff --git a/lib/optimize/ModuleConcatenationPlugin.js b/lib/optimize/ModuleConcatenationPlugin.js new file mode 100644 index 000000000..8b4e1a2c7 --- /dev/null +++ b/lib/optimize/ModuleConcatenationPlugin.js @@ -0,0 +1,209 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +"use strict"; + +const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency"); +const ConcatenatedModule = require("./ConcatenatedModule"); +const HarmonyExportImportedSpecifierDependency = require("../dependencies/HarmonyExportImportedSpecifierDependency"); + +class ModuleConcatenationPlugin { + constructor(options) { + if(typeof options !== "object") options = {}; + this.options = options; + } + + apply(compiler) { + compiler.plugin("compilation", (compilation, params) => { + params.normalModuleFactory.plugin("parser", (parser, parserOptions) => { + parser.plugin("call eval", () => { + parser.state.module.meta.hasEval = true; + }); + }); + compilation.plugin("optimize-chunk-modules", (chunks, modules) => { + chunks.forEach(chunk => { + const relevantModules = chunk.mapModules(m => m).filter(module => { + // Module must not be in other chunks + // TODO add an option to allow module to be in other entry points + if(module.getNumberOfChunks() !== 1) + return false; + + // Because of variable renaming we can't use modules with eval + if(module.meta && module.meta.hasEval) + return false; + + return true; + }); + const possibleInners = new Set(relevantModules.filter(module => { + // Module must not be the entry points + if(chunk.entryModule === module) + return false; + + // Exports must be known (and not dynamic) + if(!Array.isArray(module.providedExports)) + return false; + + // Using dependency variables is not possible as this wraps the code in a function + if(module.variables.length > 0) + return false; + + // Module must only be used by Harmony Imports + if(!module.reasons.every(reason => reason.dependency instanceof HarmonyImportDependency)) + return false; + + // It must be statically known which exports are provided or used + if(!Array.isArray(module.providedExports)) + return false; + + return true; + })); + const possibleRoots = relevantModules.filter(module => { + return true; + }); + const concatConfigurations = []; + while(possibleRoots.length) { + const currentRoot = possibleRoots.pop(); + // console.log("#process", currentRoot.debugId, currentRoot.resource); + const currentConfiguration = new ConcatConfiguration(currentRoot); + for(let imp of this.getImports(currentRoot)) { + this.tryToAdd(currentConfiguration, imp, possibleInners); + } + if(!currentConfiguration.isEmpty()) + concatConfigurations.push(currentConfiguration); + } + concatConfigurations.sort((a, b) => { + return b.modules.size - a.modules.size; + }); + const usedModules = new Set(); + for(const config of concatConfigurations) { + if(usedModules.has(config.rootModule)) + continue; + const orderedModules = new Set(); + this.addInOrder(config.rootModule, config.modules, orderedModules); + const newModule = new ConcatenatedModule(config.rootModule, Array.from(orderedModules)); + for(const m of orderedModules) { + usedModules.add(m); + chunk.removeModule(m); + } + chunk.addModule(newModule); + compilation.modules.push(newModule); + if(chunk.entryModule === config.rootModule) + chunk.entryModule = newModule; + config.rootModule.reasons.forEach(reason => { + if(!config.modules.has(reason.module)) + reason.dependency.module = newModule; + }); + } + }); + }); + }); + } + + getImports(module) { + return Array.from(new Set(module.dependencies + + // Only harmony Dependencies + .filter(dep => dep instanceof HarmonyImportDependency && dep.module) + + // Dependencies are simple enough to concat them + .filter(dep => { + return !module.dependencies.some(d => + d instanceof HarmonyExportImportedSpecifierDependency && + d.importDependency === dep && + !d.id && + !Array.isArray(dep.module.providedExports) + ); + }) + + // Take the imported module + .map(dep => dep.module) + )); + } + + tryToAdd(config, module, possibleModules) { + // console.log("tryToAdd", module.debugId, module.resource); + + // Already added? + if(config.has(module)) { + // console.log("already added"); + return true; + } + + // Not possible to add? + if(!possibleModules.has(module)) { + // console.log("not possible"); + return false; + } + + // Clone config to make experimental changes + const testConfig = config.clone(); + + // Add the module + testConfig.add(module); + + // Every module which depends on the added module must be in the configuration too. + // console.log("reasons start"); + for(const reason of module.reasons) { + if(!this.tryToAdd(testConfig, reason.module, possibleModules)) { + // console.log("reason failed"); + return false; + } + } + // console.log("reasons end"); + + // Eagerly try to add imports too if possible + // console.log("imports start"); + for(const imp of this.getImports(module)) + this.tryToAdd(testConfig, imp, possibleModules); + // console.log("imports end"); + + // console.log("commit"); + // Commit experimental changes + config.set(testConfig); + return true; + } + + addInOrder(module, unorderedSet, orderedSet) { + if(orderedSet.has(module)) return; + if(!unorderedSet.has(module)) return; + orderedSet.add(module); + for(const imp of this.getImports(module)) + this.addInOrder(imp, unorderedSet, orderedSet); + orderedSet.delete(module); + orderedSet.add(module); + } +} + +class ConcatConfiguration { + constructor(rootModule) { + this.rootModule = rootModule; + this.modules = new Set([rootModule]); + } + + add(module) { + this.modules.add(module); + } + + has(module) { + return this.modules.has(module); + } + + isEmpty() { + return this.modules.size === 1; + } + + clone() { + const clone = new ConcatConfiguration(this.rootModule); + for(const module of this.modules) + clone.add(module); + return clone; + } + + set(config) { + this.rootModule = config.rootModule; + this.modules = new Set(config.modules); + } +} + +module.exports = ModuleConcatenationPlugin; diff --git a/lib/webpack.js b/lib/webpack.js index b20150800..7964f65da 100644 --- a/lib/webpack.js +++ b/lib/webpack.js @@ -114,6 +114,7 @@ exportPlugins(exports.optimize = {}, "./optimize", [ "DedupePlugin", "LimitChunkCountPlugin", "MinChunkSizePlugin", + "ModuleConcatenationPlugin", "OccurrenceOrderPlugin", "UglifyJsPlugin" ]); diff --git a/package.json b/package.json index 0957ea0cc..46b1513a4 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "ajv-keywords": "^1.1.1", "async": "^2.1.2", "enhanced-resolve": "^3.0.0", + "escope": "^3.6.0", "interpret": "^1.0.0", "json-loader": "^0.5.4", "json5": "^0.5.1", diff --git a/test/TestCases.test.js b/test/TestCases.test.js index fd97d6e01..5c6461626 100644 --- a/test/TestCases.test.js +++ b/test/TestCases.test.js @@ -22,6 +22,11 @@ describe("TestCases", () => { }); [{ name: "normal" + }, { + name: "concat", + plugins: [ + new webpack.optimize.ModuleConcatenationPlugin() + ] }, { name: "hot", plugins: [ diff --git a/test/cases/scope-hoisting/chained-reexport/a.js b/test/cases/scope-hoisting/chained-reexport/a.js new file mode 100644 index 000000000..df79c24c5 --- /dev/null +++ b/test/cases/scope-hoisting/chained-reexport/a.js @@ -0,0 +1 @@ +export var named = "named"; diff --git a/test/cases/scope-hoisting/chained-reexport/b.js b/test/cases/scope-hoisting/chained-reexport/b.js new file mode 100644 index 000000000..378dcf843 --- /dev/null +++ b/test/cases/scope-hoisting/chained-reexport/b.js @@ -0,0 +1 @@ +export * from "./a"; diff --git a/test/cases/scope-hoisting/chained-reexport/c.js b/test/cases/scope-hoisting/chained-reexport/c.js new file mode 100644 index 000000000..feca56aea --- /dev/null +++ b/test/cases/scope-hoisting/chained-reexport/c.js @@ -0,0 +1 @@ +export { named } from "./b"; diff --git a/test/cases/scope-hoisting/chained-reexport/index.js b/test/cases/scope-hoisting/chained-reexport/index.js new file mode 100644 index 000000000..5ac21327b --- /dev/null +++ b/test/cases/scope-hoisting/chained-reexport/index.js @@ -0,0 +1,5 @@ +import { named } from "./c"; + +it("should have the correct values", function() { + named.should.be.eql("named"); +}); diff --git a/test/cases/scope-hoisting/export-namespace/index.js b/test/cases/scope-hoisting/export-namespace/index.js new file mode 100644 index 000000000..6c1b35d6f --- /dev/null +++ b/test/cases/scope-hoisting/export-namespace/index.js @@ -0,0 +1,16 @@ +import { ns as ns1 } from "./module1"; +const ns2 = require("./module2").ns; + +it("should allow to export a namespace object (concated)", function() { + ns1.should.be.eql({ + a: "a", + b: "b" + }); +}); + +it("should allow to export a namespace object (exposed)", function() { + ns2.should.be.eql({ + a: "a", + b: "b" + }); +}); diff --git a/test/cases/scope-hoisting/export-namespace/module1.js b/test/cases/scope-hoisting/export-namespace/module1.js new file mode 100644 index 000000000..59e7d89f9 --- /dev/null +++ b/test/cases/scope-hoisting/export-namespace/module1.js @@ -0,0 +1,2 @@ +import * as ns from "./ns1"; +export { ns }; diff --git a/test/cases/scope-hoisting/export-namespace/module2.js b/test/cases/scope-hoisting/export-namespace/module2.js new file mode 100644 index 000000000..32e099888 --- /dev/null +++ b/test/cases/scope-hoisting/export-namespace/module2.js @@ -0,0 +1,2 @@ +import * as ns from "./ns2"; +export { ns }; diff --git a/test/cases/scope-hoisting/export-namespace/ns1.js b/test/cases/scope-hoisting/export-namespace/ns1.js new file mode 100644 index 000000000..2151809d0 --- /dev/null +++ b/test/cases/scope-hoisting/export-namespace/ns1.js @@ -0,0 +1,2 @@ +export var a = "a"; +export var b = "b"; diff --git a/test/cases/scope-hoisting/export-namespace/ns2.js b/test/cases/scope-hoisting/export-namespace/ns2.js new file mode 100644 index 000000000..2151809d0 --- /dev/null +++ b/test/cases/scope-hoisting/export-namespace/ns2.js @@ -0,0 +1,2 @@ +export var a = "a"; +export var b = "b"; diff --git a/test/cases/scope-hoisting/reexport-cjs/a.js b/test/cases/scope-hoisting/reexport-cjs/a.js new file mode 100644 index 000000000..c1ce35449 --- /dev/null +++ b/test/cases/scope-hoisting/reexport-cjs/a.js @@ -0,0 +1 @@ +exports.named = "named"; diff --git a/test/cases/scope-hoisting/reexport-cjs/b.js b/test/cases/scope-hoisting/reexport-cjs/b.js new file mode 100644 index 000000000..ee6e29df9 --- /dev/null +++ b/test/cases/scope-hoisting/reexport-cjs/b.js @@ -0,0 +1 @@ +export { named } from "./a"; diff --git a/test/cases/scope-hoisting/reexport-cjs/c.js b/test/cases/scope-hoisting/reexport-cjs/c.js new file mode 100644 index 000000000..feca56aea --- /dev/null +++ b/test/cases/scope-hoisting/reexport-cjs/c.js @@ -0,0 +1 @@ +export { named } from "./b"; diff --git a/test/cases/scope-hoisting/reexport-cjs/index.js b/test/cases/scope-hoisting/reexport-cjs/index.js new file mode 100644 index 000000000..5ac21327b --- /dev/null +++ b/test/cases/scope-hoisting/reexport-cjs/index.js @@ -0,0 +1,5 @@ +import { named } from "./c"; + +it("should have the correct values", function() { + named.should.be.eql("named"); +}); diff --git a/test/cases/scope-hoisting/reexport-exposed-cjs/a.js b/test/cases/scope-hoisting/reexport-exposed-cjs/a.js new file mode 100644 index 000000000..c1ce35449 --- /dev/null +++ b/test/cases/scope-hoisting/reexport-exposed-cjs/a.js @@ -0,0 +1 @@ +exports.named = "named"; diff --git a/test/cases/scope-hoisting/reexport-exposed-cjs/b.js b/test/cases/scope-hoisting/reexport-exposed-cjs/b.js new file mode 100644 index 000000000..ee6e29df9 --- /dev/null +++ b/test/cases/scope-hoisting/reexport-exposed-cjs/b.js @@ -0,0 +1 @@ +export { named } from "./a"; diff --git a/test/cases/scope-hoisting/reexport-exposed-cjs/c.js b/test/cases/scope-hoisting/reexport-exposed-cjs/c.js new file mode 100644 index 000000000..feca56aea --- /dev/null +++ b/test/cases/scope-hoisting/reexport-exposed-cjs/c.js @@ -0,0 +1 @@ +export { named } from "./b"; diff --git a/test/cases/scope-hoisting/reexport-exposed-cjs/index.js b/test/cases/scope-hoisting/reexport-exposed-cjs/index.js new file mode 100644 index 000000000..f9a31c159 --- /dev/null +++ b/test/cases/scope-hoisting/reexport-exposed-cjs/index.js @@ -0,0 +1,5 @@ +var c = require("./c"); + +it("should have the correct values", function() { + c.named.should.be.eql("named"); +}); diff --git a/test/cases/scope-hoisting/reexport-exposed-default-cjs/a.js b/test/cases/scope-hoisting/reexport-exposed-default-cjs/a.js new file mode 100644 index 000000000..674b586d5 --- /dev/null +++ b/test/cases/scope-hoisting/reexport-exposed-default-cjs/a.js @@ -0,0 +1 @@ +module.exports = "default"; diff --git a/test/cases/scope-hoisting/reexport-exposed-default-cjs/b.js b/test/cases/scope-hoisting/reexport-exposed-default-cjs/b.js new file mode 100644 index 000000000..ffe5601ed --- /dev/null +++ b/test/cases/scope-hoisting/reexport-exposed-default-cjs/b.js @@ -0,0 +1 @@ +export { default } from "./a"; diff --git a/test/cases/scope-hoisting/reexport-exposed-default-cjs/c.js b/test/cases/scope-hoisting/reexport-exposed-default-cjs/c.js new file mode 100644 index 000000000..dfb1001dd --- /dev/null +++ b/test/cases/scope-hoisting/reexport-exposed-default-cjs/c.js @@ -0,0 +1 @@ +export { default } from "./b"; diff --git a/test/cases/scope-hoisting/reexport-exposed-default-cjs/index.js b/test/cases/scope-hoisting/reexport-exposed-default-cjs/index.js new file mode 100644 index 000000000..80958b553 --- /dev/null +++ b/test/cases/scope-hoisting/reexport-exposed-default-cjs/index.js @@ -0,0 +1,5 @@ +var c = require("./c"); + +it("should have the correct values", function() { + c.default.should.be.eql("default"); +}); diff --git a/test/cases/scope-hoisting/reexport-exposed-harmony/a.js b/test/cases/scope-hoisting/reexport-exposed-harmony/a.js new file mode 100644 index 000000000..df79c24c5 --- /dev/null +++ b/test/cases/scope-hoisting/reexport-exposed-harmony/a.js @@ -0,0 +1 @@ +export var named = "named"; diff --git a/test/cases/scope-hoisting/reexport-exposed-harmony/b.js b/test/cases/scope-hoisting/reexport-exposed-harmony/b.js new file mode 100644 index 000000000..378dcf843 --- /dev/null +++ b/test/cases/scope-hoisting/reexport-exposed-harmony/b.js @@ -0,0 +1 @@ +export * from "./a"; diff --git a/test/cases/scope-hoisting/reexport-exposed-harmony/c.js b/test/cases/scope-hoisting/reexport-exposed-harmony/c.js new file mode 100644 index 000000000..feca56aea --- /dev/null +++ b/test/cases/scope-hoisting/reexport-exposed-harmony/c.js @@ -0,0 +1 @@ +export { named } from "./b"; diff --git a/test/cases/scope-hoisting/reexport-exposed-harmony/index.js b/test/cases/scope-hoisting/reexport-exposed-harmony/index.js new file mode 100644 index 000000000..f9a31c159 --- /dev/null +++ b/test/cases/scope-hoisting/reexport-exposed-harmony/index.js @@ -0,0 +1,5 @@ +var c = require("./c"); + +it("should have the correct values", function() { + c.named.should.be.eql("named"); +}); diff --git a/test/cases/scope-hoisting/simple/index.js b/test/cases/scope-hoisting/simple/index.js new file mode 100644 index 000000000..b0ca24d53 --- /dev/null +++ b/test/cases/scope-hoisting/simple/index.js @@ -0,0 +1,6 @@ +import value, { named } from "./module"; + +it("should have the correct values", function() { + value.should.be.eql("default"); + named.should.be.eql("named"); +}); diff --git a/test/cases/scope-hoisting/simple/module.js b/test/cases/scope-hoisting/simple/module.js new file mode 100644 index 000000000..95dac8cca --- /dev/null +++ b/test/cases/scope-hoisting/simple/module.js @@ -0,0 +1,2 @@ +export default "default"; +export var named = "named"; From c41ab084f64b09a5f0df4e1adf92d8aed47d0551 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Tue, 16 May 2017 11:14:59 +0200 Subject: [PATCH 12/40] fix export mangling in concatenated modules --- examples/scope-hoisting/README.md | 24 ++++++++++-------------- lib/optimize/ConcatenatedModule.js | 3 ++- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/examples/scope-hoisting/README.md b/examples/scope-hoisting/README.md index f6996f762..e3e9dad86 100644 --- a/examples/scope-hoisting/README.md +++ b/examples/scope-hoisting/README.md @@ -9,7 +9,7 @@ All modules except `cjs` are EcmaScript modules. `cjs` is a CommonJs module. The interesting thing here is that putting all modules in single scope won't work, because of multiple reasons: * Modules `lazy`, `c`, `d` and `cjs` need to be in a separate chunk -* Module `shared` is accessed by two chunks (difference scopes) +* Module `shared` is accessed by two chunks (different scopes) * Module `cjs` is a CommonJs module ![](graph2.png) @@ -303,7 +303,7 @@ function b_js_a() { __webpack_require__.e/* import() */(0).then(__webpack_require__.bind(null, /*! ./lazy */ 2)).then(function(lazy) { - console.log(a, b_js_a(), __WEBPACK_IMPORTED_MODULE_0_shared__["x"], __WEBPACK_IMPORTED_MODULE_0_shared__["y"], lazy.c, lazy.d.a, lazy.x, lazy.y); + console.log(a, b_js_a(), __WEBPACK_IMPORTED_MODULE_0_shared__["a"], __WEBPACK_IMPORTED_MODULE_0_shared__["b"], lazy.c, lazy.d.a, lazy.x, lazy.y); }); @@ -325,7 +325,7 @@ var y = "y"; // CONCATENAMED MODULE: ./node_modules/shared.js /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return x; }); -/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "y", function() { return y; }); +/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "b", function() { return y; }); // shared module var x = "x"; @@ -371,8 +371,8 @@ var a = "d"; // CONCATENAMED MODULE: ./lazy.js /* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "c", function() { return c; }); -/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "x", function() { return __WEBPACK_IMPORTED_MODULE_1_shared__["x"]; }); -/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "y", function() { return __WEBPACK_IMPORTED_MODULE_1_shared__["y"]; }); +/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "x", function() { return __WEBPACK_IMPORTED_MODULE_1_shared__["a"]; }); +/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "y", function() { return __WEBPACK_IMPORTED_MODULE_1_shared__["b"]; }); /* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "d", function() { return d_js_namespaceObject; }); @@ -399,7 +399,7 @@ exports.c = "e"; Minimized ``` javascript -webpackJsonp([0],[,,function(n,r,t){"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=t(3),u=(t.n(e),t(1)),c=String.fromCharCode(e.c.charCodeAt(0)-2),o={};t.d(o,"a",function(){return d});var d="d";t.d(r,"c",function(){return c}),t.d(r,"x",function(){return u.x}),t.d(r,"y",function(){return u.y}),t.d(r,"d",function(){return o})},function(n,r){r.c="e"}]); +webpackJsonp([0],[,,function(n,r,t){"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=t(3),u=(t.n(e),t(1)),c=String.fromCharCode(e.c.charCodeAt(0)-2),o={};t.d(o,"a",function(){return d});var d="d";t.d(r,"c",function(){return c}),t.d(r,"x",function(){return u.a}),t.d(r,"y",function(){return u.b}),t.d(r,"d",function(){return o})},function(n,r){r.c="e"}]); ``` # Info @@ -407,7 +407,7 @@ webpackJsonp([0],[,,function(n,r,t){"use strict";Object.defineProperty(exports," ## Uncompressed ``` -Hash: 383b132e31f349cdb930 +Hash: 4091e96718e53f8b98fd Version: webpack 2.5.1 Asset Size Chunks Chunk Names 0.output.js 1.85 kB 0 [emitted] @@ -417,7 +417,6 @@ chunk {0} 0.output.js 276 bytes {1} [rendered] > [4] 4:0-16 [2] ./lazy.js + 2 modules 232 bytes {0} [built] [exports: d, c, x, y] - [no exports used] import() ./lazy [4] ./example.js 4:0-16 [3] ./node_modules/cjs.js 44 bytes {0} [built] [only some exports used: c] @@ -425,10 +424,9 @@ chunk {0} 0.output.js 276 bytes {1} [rendered] chunk {1} output.js (main) 385 bytes [entry] [rendered] > main [4] [0] ./example.js + 2 modules 280 bytes {1} [built] - [no exports used] [1] ./node_modules/shared.js + 1 modules 105 bytes {1} [built] [exports: x, y] - [no exports used] + [only some exports used: x, y] harmony import shared [6] ./node_modules/a.js 3:0-23 harmony import shared [8] ./node_modules/c.js 6:0-30 ``` @@ -436,7 +434,7 @@ chunk {1} output.js (main) 385 bytes [entry] [rendered] ## Minimized (uglify-js, no zip) ``` -Hash: 383b132e31f349cdb930 +Hash: 4091e96718e53f8b98fd Version: webpack 2.5.1 Asset Size Chunks Chunk Names 0.output.js 379 bytes 0 [emitted] @@ -446,7 +444,6 @@ chunk {0} 0.output.js 276 bytes {1} [rendered] > [4] 4:0-16 [2] ./lazy.js + 2 modules 232 bytes {0} [built] [exports: d, c, x, y] - [no exports used] import() ./lazy [4] ./example.js 4:0-16 [3] ./node_modules/cjs.js 44 bytes {0} [built] [only some exports used: c] @@ -454,10 +451,9 @@ chunk {0} 0.output.js 276 bytes {1} [rendered] chunk {1} output.js (main) 385 bytes [entry] [rendered] > main [4] [0] ./example.js + 2 modules 280 bytes {1} [built] - [no exports used] [1] ./node_modules/shared.js + 1 modules 105 bytes {1} [built] [exports: x, y] - [no exports used] + [only some exports used: x, y] harmony import shared [6] ./node_modules/a.js 3:0-23 harmony import shared [8] ./node_modules/c.js 6:0-30 ``` diff --git a/lib/optimize/ConcatenatedModule.js b/lib/optimize/ConcatenatedModule.js index 17fe066c1..7e130bf89 100644 --- a/lib/optimize/ConcatenatedModule.js +++ b/lib/optimize/ConcatenatedModule.js @@ -57,6 +57,7 @@ class ConcatenatedModule extends Module { this.modules = modules; this.usedExports = rootModule.usedExports; this.providedExports = rootModule.providedExports; + this.used = rootModule.used; this._chunks = new Set(rootModule._chunks); this.index = rootModule.index; this.index2 = rootModule.index2; @@ -461,7 +462,7 @@ class HarmonyExportImportedSpecifierDependencyConcatenatedTemplate { finalName = exportIdx < 0 ? "undefined" : `__WEBPACK_MODULE_REFERENCE__${info.index}_${exportIdx}__`; } const exportsName = this.rootModule.exportsArgument || "exports"; - const content = `/* concated harmony reexport */__webpack_require__.d(${exportsName}, ${JSON.stringify(def.name)}, function() { return ${finalName}; });\n`; + const content = `/* concated harmony reexport */__webpack_require__.d(${exportsName}, ${JSON.stringify(used)}, function() { return ${finalName}; });\n`; source.insert(-1, content); }); } else { From 4a25a17bb6590aa398114020214b7ed941b9909a Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sun, 21 May 2017 06:56:24 +0200 Subject: [PATCH 13/40] improvements from review --- lib/Compilation.js | 2 +- lib/Parser.js | 12 ++++++++---- lib/optimize/ConcatenatedModule.js | 11 ++++++----- lib/optimize/ModuleConcatenationPlugin.js | 2 +- test/cases/scope-hoisting/indirect-reexport/a.js | 1 + test/cases/scope-hoisting/indirect-reexport/b.js | 2 ++ test/cases/scope-hoisting/indirect-reexport/c.js | 2 ++ test/cases/scope-hoisting/indirect-reexport/index.js | 5 +++++ 8 files changed, 26 insertions(+), 11 deletions(-) create mode 100644 test/cases/scope-hoisting/indirect-reexport/a.js create mode 100644 test/cases/scope-hoisting/indirect-reexport/b.js create mode 100644 test/cases/scope-hoisting/indirect-reexport/c.js create mode 100644 test/cases/scope-hoisting/indirect-reexport/index.js diff --git a/lib/Compilation.js b/lib/Compilation.js index 9287e7d48..16d0dfdc6 100644 --- a/lib/Compilation.js +++ b/lib/Compilation.js @@ -586,7 +586,7 @@ class Compilation extends Tapable { while(self.applyPluginsBailResult("optimize-chunk-modules-basic", self.chunks, self.modules) || self.applyPluginsBailResult("optimize-chunk-modules", self.chunks, self.modules) || - self.applyPluginsBailResult("optimize-chunk-modules-advanced", self.chunks, self.modules)); // eslint-disable-line no-extra-semi + self.applyPluginsBailResult("optimize-chunk-modules-advanced", self.chunks, self.modules)) { /* empty */ } self.applyPlugins2("after-optimize-chunk-modules", self.chunks, self.modules); const shouldRecord = self.applyPluginsBailResult("should-record") !== false; diff --git a/lib/Parser.js b/lib/Parser.js index 11f72412d..a77c00391 100644 --- a/lib/Parser.js +++ b/lib/Parser.js @@ -17,10 +17,12 @@ function joinRanges(startRange, endRange) { return [startRange[0], endRange[1]]; } +const ECMA_VERSION = 2017; + const POSSIBLE_AST_OPTIONS = [{ ranges: true, locations: true, - ecmaVersion: 2017, + ecmaVersion: ECMA_VERSION, sourceType: "module", plugins: { dynamicImport: true @@ -28,7 +30,7 @@ const POSSIBLE_AST_OPTIONS = [{ }, { ranges: true, locations: true, - ecmaVersion: 2017, + ecmaVersion: ECMA_VERSION, sourceType: "script", plugins: { dynamicImport: true @@ -1335,7 +1337,7 @@ class Parser extends Tapable { ast = acorn.parse(source, { ranges: true, locations: true, - ecmaVersion: 2017, + ecmaVersion: ECMA_VERSION, sourceType: "module", plugins: { dynamicImport: true @@ -1369,7 +1371,7 @@ class Parser extends Tapable { const ast = acorn.parse("(" + source + ")", { ranges: true, locations: true, - ecmaVersion: 2017, + ecmaVersion: ECMA_VERSION, sourceType: "module", plugins: { dynamicImport: true @@ -1401,4 +1403,6 @@ class Parser extends Tapable { } +Parser.ECMA_VERSION = ECMA_VERSION; + module.exports = Parser; diff --git a/lib/optimize/ConcatenatedModule.js b/lib/optimize/ConcatenatedModule.js index 7e130bf89..08dc6424e 100644 --- a/lib/optimize/ConcatenatedModule.js +++ b/lib/optimize/ConcatenatedModule.js @@ -6,6 +6,7 @@ const Module = require("../Module"); const Template = require("../Template"); +const Parser = require("../Parser"); const acorn = require("acorn"); const escope = require("escope"); const ReplaceSource = require("webpack-sources/lib/ReplaceSource"); @@ -35,11 +36,11 @@ function getFinalName(info, exportName, moduleToInfoMap, requestShortener) { const dep = reexport.dependency; const importedModule = reexport.module; const exportName = reexport.exportName; - const isNotAHarmonyModule = !(importedModule && (!importedModule.meta || importedModule.meta.harmonyModule)); + const isHarmonyModule = importedModule && (!importedModule.meta || importedModule.meta.harmonyModule); const importedVar = dep.importedVar; const used = importedModule.isUsed(exportName); if(!used) return "/* unused reexport */undefined"; - if(isNotAHarmonyModule && exportName === "default") { + if(!isHarmonyModule && exportName === "default") { return `${importedVar}_default.a`; } return `${importedVar}[${JSON.stringify(used)}]`; @@ -210,7 +211,7 @@ class ConcatenatedModule extends Module { const ast = acorn.parse(code, { ranges: true, locations: true, - ecmaVersion: 2017, + ecmaVersion: Parser.ECMA_VERSION, sourceType: "module" }); const scopeManager = escope.analyze(ast, { @@ -244,7 +245,7 @@ class ConcatenatedModule extends Module { info.internalNames.set(namespaceObjectName, namespaceObjectName); info.exportMap.set(true, namespaceObjectName); info.moduleScope.variables.forEach(variable => { - let name = variable.name; + const name = variable.name; if(allUsedNames.has(name)) { const newName = this.findNewName(name, allUsedNames, info.module.readableIdentifier(requestShortener)); allUsedNames.add(newName); @@ -290,7 +291,7 @@ class ConcatenatedModule extends Module { result.add(`Object.defineProperty(${this.rootModule.moduleArgument || "exports"}, "__esModule", { value: true });\n`); } modulesWithInfo.forEach(info => { - result.add(`\n// CONCATENAMED MODULE: ${info.module.readableIdentifier(requestShortener)}\n`); + result.add(`\n// CONCATENATED MODULE: ${info.module.readableIdentifier(requestShortener)}\n`); if(info.needNamespaceObject) { const name = info.exportMap.get(true); const nsObj = [`var ${name} = {};`]; diff --git a/lib/optimize/ModuleConcatenationPlugin.js b/lib/optimize/ModuleConcatenationPlugin.js index 8b4e1a2c7..20403ab72 100644 --- a/lib/optimize/ModuleConcatenationPlugin.js +++ b/lib/optimize/ModuleConcatenationPlugin.js @@ -66,7 +66,7 @@ class ModuleConcatenationPlugin { const currentRoot = possibleRoots.pop(); // console.log("#process", currentRoot.debugId, currentRoot.resource); const currentConfiguration = new ConcatConfiguration(currentRoot); - for(let imp of this.getImports(currentRoot)) { + for(const imp of this.getImports(currentRoot)) { this.tryToAdd(currentConfiguration, imp, possibleInners); } if(!currentConfiguration.isEmpty()) diff --git a/test/cases/scope-hoisting/indirect-reexport/a.js b/test/cases/scope-hoisting/indirect-reexport/a.js new file mode 100644 index 000000000..f22b615c7 --- /dev/null +++ b/test/cases/scope-hoisting/indirect-reexport/a.js @@ -0,0 +1 @@ +export default "named"; diff --git a/test/cases/scope-hoisting/indirect-reexport/b.js b/test/cases/scope-hoisting/indirect-reexport/b.js new file mode 100644 index 000000000..fa64420ef --- /dev/null +++ b/test/cases/scope-hoisting/indirect-reexport/b.js @@ -0,0 +1,2 @@ +import named from "./a"; +export { named } diff --git a/test/cases/scope-hoisting/indirect-reexport/c.js b/test/cases/scope-hoisting/indirect-reexport/c.js new file mode 100644 index 000000000..87b65ebdf --- /dev/null +++ b/test/cases/scope-hoisting/indirect-reexport/c.js @@ -0,0 +1,2 @@ +import { named } from "./b"; +export { named } diff --git a/test/cases/scope-hoisting/indirect-reexport/index.js b/test/cases/scope-hoisting/indirect-reexport/index.js new file mode 100644 index 000000000..f9a31c159 --- /dev/null +++ b/test/cases/scope-hoisting/indirect-reexport/index.js @@ -0,0 +1,5 @@ +var c = require("./c"); + +it("should have the correct values", function() { + c.named.should.be.eql("named"); +}); From 5d9eef85c7413aa377f96b3e9f906cc9550f6301 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sun, 21 May 2017 07:14:10 +0200 Subject: [PATCH 14/40] improvements from review --- lib/optimize/ModuleConcatenationPlugin.js | 29 ++++++++++------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/lib/optimize/ModuleConcatenationPlugin.js b/lib/optimize/ModuleConcatenationPlugin.js index 20403ab72..0aaa90513 100644 --- a/lib/optimize/ModuleConcatenationPlugin.js +++ b/lib/optimize/ModuleConcatenationPlugin.js @@ -52,19 +52,10 @@ class ModuleConcatenationPlugin { if(!module.reasons.every(reason => reason.dependency instanceof HarmonyImportDependency)) return false; - // It must be statically known which exports are provided or used - if(!Array.isArray(module.providedExports)) - return false; - return true; })); - const possibleRoots = relevantModules.filter(module => { - return true; - }); const concatConfigurations = []; - while(possibleRoots.length) { - const currentRoot = possibleRoots.pop(); - // console.log("#process", currentRoot.debugId, currentRoot.resource); + for(const currentRoot of relevantModules) { const currentConfiguration = new ConcatConfiguration(currentRoot); for(const imp of this.getImports(currentRoot)) { this.tryToAdd(currentConfiguration, imp, possibleInners); @@ -72,26 +63,30 @@ class ModuleConcatenationPlugin { if(!currentConfiguration.isEmpty()) concatConfigurations.push(currentConfiguration); } + // HACK: Sort configurations by length and start with the longest one + // to get the biggers groups possible. Used modules are marked with usedModules + // TODO: Allow to reuse existing configuration while trying to add dependencies. + // This would improve performance. O(n^2) -> O(n) concatConfigurations.sort((a, b) => { return b.modules.size - a.modules.size; }); const usedModules = new Set(); - for(const config of concatConfigurations) { - if(usedModules.has(config.rootModule)) + for(const concatConfiguration of concatConfigurations) { + if(usedModules.has(concatConfiguration.rootModule)) continue; const orderedModules = new Set(); - this.addInOrder(config.rootModule, config.modules, orderedModules); - const newModule = new ConcatenatedModule(config.rootModule, Array.from(orderedModules)); + this.addInOrder(concatConfiguration.rootModule, concatConfiguration.modules, orderedModules); + const newModule = new ConcatenatedModule(concatConfiguration.rootModule, Array.from(orderedModules)); for(const m of orderedModules) { usedModules.add(m); chunk.removeModule(m); } chunk.addModule(newModule); compilation.modules.push(newModule); - if(chunk.entryModule === config.rootModule) + if(chunk.entryModule === concatConfiguration.rootModule) chunk.entryModule = newModule; - config.rootModule.reasons.forEach(reason => { - if(!config.modules.has(reason.module)) + concatConfiguration.rootModule.reasons.forEach(reason => { + if(!concatConfiguration.modules.has(reason.module)) reason.dependency.module = newModule; }); } From d967a4623cbbd1256bcc05a8632b0a47b7e53403 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sun, 21 May 2017 09:13:33 +0200 Subject: [PATCH 15/40] add `module.strictThisContextOnImports` option to allow spec-comforming behavior this context on called imported harmony functions --- lib/MainTemplate.js | 4 -- lib/Parser.js | 6 +++ lib/WebpackOptionsDefaulter.js | 1 + .../HarmonyImportDependencyParserPlugin.js | 49 +++++++++++++------ .../HarmonyImportSpecifierDependency.js | 6 ++- lib/dependencies/HarmonyModulesPlugin.js | 13 +++++ schemas/webpackOptionsSchema.json | 3 ++ .../parsing/harmony-this/abc.js | 0 .../parsing/harmony-this/index.js | 4 +- .../parsing/harmony-this/new.js | 0 .../parsing/harmony-this/webpack.config.js | 5 ++ .../aggressive-splitting-entry/expected.txt | 2 +- .../expected.txt | 2 +- test/statsCases/chunks/expected.txt | 2 +- test/statsCases/color-disabled/expected.txt | 2 +- .../color-enabled-custom/expected.txt | 2 +- test/statsCases/color-enabled/expected.txt | 2 +- .../commons-chunk-min-size-0/expected.txt | 2 +- .../expected.txt | 4 +- test/statsCases/define-plugin/expected.txt | 4 +- .../exclude-with-loader/expected.txt | 4 +- test/statsCases/external/expected.txt | 2 +- test/statsCases/filter-warnings/expected.txt | 14 +++--- .../limit-chunk-count-plugin/expected.txt | 10 ++-- .../max-modules-default/expected.txt | 2 +- test/statsCases/max-modules/expected.txt | 2 +- .../expected.txt | 2 +- .../expected.txt | 2 +- .../named-chunks-plugin-async/expected.txt | 2 +- .../named-chunks-plugin/expected.txt | 2 +- test/statsCases/optimize-chunks/expected.txt | 2 +- .../expected.txt | 2 +- test/statsCases/preset-verbose/expected.txt | 2 +- .../resolve-plugin-context/expected.txt | 2 +- .../reverse-sort-modules/expected.txt | 2 +- .../separate-css-bundle/expected.txt | 4 +- test/statsCases/simple-more-info/expected.txt | 2 +- test/statsCases/simple/expected.txt | 2 +- test/statsCases/tree-shaking/expected.txt | 2 +- 39 files changed, 111 insertions(+), 64 deletions(-) rename test/{cases => configCases}/parsing/harmony-this/abc.js (100%) rename test/{cases => configCases}/parsing/harmony-this/index.js (83%) rename test/{cases => configCases}/parsing/harmony-this/new.js (100%) create mode 100644 test/configCases/parsing/harmony-this/webpack.config.js diff --git a/lib/MainTemplate.js b/lib/MainTemplate.js index c76cff5e0..8eacc004a 100644 --- a/lib/MainTemplate.js +++ b/lib/MainTemplate.js @@ -114,10 +114,6 @@ module.exports = class MainTemplate extends Template { buf.push("// expose the module cache"); buf.push(`${this.requireFn}.c = installedModules;`); - buf.push(""); - buf.push("// identity function for calling harmony imports with the correct context"); - buf.push(`${this.requireFn}.i = function(value) { return value; };`); - buf.push(""); buf.push("// define getter function for harmony exports"); buf.push(`${this.requireFn}.d = function(exports, name, getter) {`); diff --git a/lib/Parser.js b/lib/Parser.js index a77c00391..1bfcc7c7c 100644 --- a/lib/Parser.js +++ b/lib/Parser.js @@ -1112,6 +1112,12 @@ class Parser extends Tapable { result = this.applyPluginsBailResult1("call " + callee.identifier, expression); if(result === true) return; + let identifier = callee.identifier.replace(/\.[^\.]+$/, ".*"); + if(identifier !== callee.identifier) { + result = this.applyPluginsBailResult1("call " + identifier, expression); + if(result === true) + return; + } } if(expression.callee) diff --git a/lib/WebpackOptionsDefaulter.js b/lib/WebpackOptionsDefaulter.js index 6f664d06d..513191359 100644 --- a/lib/WebpackOptionsDefaulter.js +++ b/lib/WebpackOptionsDefaulter.js @@ -28,6 +28,7 @@ class WebpackOptionsDefaulter extends OptionsDefaulter { this.set("module.wrappedContextRecursive", true); this.set("module.wrappedContextCritical", false); this.set("module.strictExportPresence", false); + this.set("module.strictThisContextOnImports", false); this.set("module.unsafeCache", true); diff --git a/lib/dependencies/HarmonyImportDependencyParserPlugin.js b/lib/dependencies/HarmonyImportDependencyParserPlugin.js index 88ed4b141..5551882ac 100644 --- a/lib/dependencies/HarmonyImportDependencyParserPlugin.js +++ b/lib/dependencies/HarmonyImportDependencyParserPlugin.js @@ -13,6 +13,7 @@ const HarmonyModulesHelpers = require("./HarmonyModulesHelpers"); module.exports = class HarmonyImportDependencyParserPlugin { constructor(moduleOptions) { this.strictExportPresence = moduleOptions.strictExportPresence; + this.strictThisContextOnImports = moduleOptions.strictThisContextOnImports; } apply(parser) { @@ -52,22 +53,38 @@ module.exports = class HarmonyImportDependencyParserPlugin { parser.state.current.addDependency(dep); return true; }); - parser.plugin("call imported var", (expr) => { - const args = expr.arguments; - const fullExpr = expr; - expr = expr.callee; - const name = expr.name; - const settings = parser.state.harmonySpecifier[`$${name}`]; - const dep = new HarmonyImportSpecifierDependency(settings[0], settings[1], settings[2], name, expr.range, this.strictExportPresence); - dep.directImport = true; - dep.callArgs = args; - dep.call = fullExpr; - dep.loc = expr.loc; - parser.state.current.addDependency(dep); - if(args) - parser.walkExpressions(args); - return true; - }); + if(this.strictThisContextOnImports) { + // only in case when we strictly follow the spec we need a special case here + parser.plugin("call imported var.*", (expr) => { + const name = expr.callee.object.name; + const settings = parser.state.harmonySpecifier[`$${name}`]; + if(settings[2] !== null) + return false; + const dep = new HarmonyImportSpecifierDependency(settings[0], settings[1], expr.callee.property.name || expr.callee.property.value, name, expr.callee.range, this.strictExportPresence); + dep.shorthand = parser.scope.inShorthand; + dep.directImport = false; + dep.namespaceObjectAsContext = true; + dep.loc = expr.callee.loc; + parser.state.current.addDependency(dep); + return true; + }); + parser.plugin("call imported var", (expr) => { + const args = expr.arguments; + const fullExpr = expr; + expr = expr.callee; + const name = expr.name; + const settings = parser.state.harmonySpecifier[`$${name}`]; + const dep = new HarmonyImportSpecifierDependency(settings[0], settings[1], settings[2], name, expr.range, this.strictExportPresence); + dep.directImport = true; + dep.callArgs = args; + dep.call = fullExpr; + dep.loc = expr.loc; + parser.state.current.addDependency(dep); + if(args) + parser.walkExpressions(args); + return true; + }); + } parser.plugin("hot accept callback", (expr, requests) => { const dependencies = requests .filter(request => HarmonyModulesHelpers.checkModuleVar(parser.state, request)) diff --git a/lib/dependencies/HarmonyImportSpecifierDependency.js b/lib/dependencies/HarmonyImportSpecifierDependency.js index b2a42151e..746f747ea 100644 --- a/lib/dependencies/HarmonyImportSpecifierDependency.js +++ b/lib/dependencies/HarmonyImportSpecifierDependency.js @@ -14,6 +14,10 @@ class HarmonyImportSpecifierDependency extends NullDependency { this.name = name; this.range = range; this.strictExportPresence = strictExportPresence; + this.namespaceObjectAsContext = false; + this.callArgs = undefined; + this.call = undefined; + this.directImport = undefined; } get type() { @@ -24,7 +28,7 @@ class HarmonyImportSpecifierDependency extends NullDependency { if(!this.importDependency.module) return null; return { module: this.importDependency.module, - importedNames: this.id ? [this.id] : true + importedNames: this.id && !this.namespaceObjectAsContext ? [this.id] : true }; } diff --git a/lib/dependencies/HarmonyModulesPlugin.js b/lib/dependencies/HarmonyModulesPlugin.js index 1b8969c5e..0b6c3e408 100644 --- a/lib/dependencies/HarmonyModulesPlugin.js +++ b/lib/dependencies/HarmonyModulesPlugin.js @@ -66,6 +66,19 @@ class HarmonyModulesPlugin { new HarmonyExportDependencyParserPlugin() ); }); + + if(this.options.strictThisContextOnImports) { + compilation.mainTemplate.plugin("require-extensions", (source, chunk, hash) => { + + const buf = [source]; + + buf.push(""); + buf.push("// identity function for calling harmony imports with the correct context"); + buf.push(`${compilation.mainTemplate.requireFn}.i = function(value) { return value; };`); + + return buf.join("\n"); + }); + } }); } } diff --git a/schemas/webpackOptionsSchema.json b/schemas/webpackOptionsSchema.json index 81a971d25..5e5294773 100644 --- a/schemas/webpackOptionsSchema.json +++ b/schemas/webpackOptionsSchema.json @@ -221,6 +221,9 @@ }, "strictExportPresence": { "type": "boolean" + }, + "strictThisContextOnImports": { + "type": "boolean" } }, "type": "object" diff --git a/test/cases/parsing/harmony-this/abc.js b/test/configCases/parsing/harmony-this/abc.js similarity index 100% rename from test/cases/parsing/harmony-this/abc.js rename to test/configCases/parsing/harmony-this/abc.js diff --git a/test/cases/parsing/harmony-this/index.js b/test/configCases/parsing/harmony-this/index.js similarity index 83% rename from test/cases/parsing/harmony-this/index.js rename to test/configCases/parsing/harmony-this/index.js index ae8c422a5..af774470b 100644 --- a/test/cases/parsing/harmony-this/index.js +++ b/test/configCases/parsing/harmony-this/index.js @@ -13,8 +13,10 @@ it("should have this = undefined on imported non-strict functions", function() { x B().should.be.eql("undefined"); x - abc.a().should.be.eql(abc); + abc.a().should.be.type("object"); x + var thing = abc.a(); + Object.keys(thing).should.be.eql(["a", "b", "default"]); }); import C2, { C } from "./new"; diff --git a/test/cases/parsing/harmony-this/new.js b/test/configCases/parsing/harmony-this/new.js similarity index 100% rename from test/cases/parsing/harmony-this/new.js rename to test/configCases/parsing/harmony-this/new.js diff --git a/test/configCases/parsing/harmony-this/webpack.config.js b/test/configCases/parsing/harmony-this/webpack.config.js new file mode 100644 index 000000000..dfb1984cf --- /dev/null +++ b/test/configCases/parsing/harmony-this/webpack.config.js @@ -0,0 +1,5 @@ +module.exports = { + module: { + strictThisContextOnImports: true + } +}; diff --git a/test/statsCases/aggressive-splitting-entry/expected.txt b/test/statsCases/aggressive-splitting-entry/expected.txt index d00d71dc1..fff900916 100644 --- a/test/statsCases/aggressive-splitting-entry/expected.txt +++ b/test/statsCases/aggressive-splitting-entry/expected.txt @@ -1,7 +1,7 @@ Hash: c4756fe25e35ccb187f7 Time: Xms Asset Size Chunks Chunk Names -48c8b1dae03a37363ec8.js 4.37 kB 1 [emitted] +48c8b1dae03a37363ec8.js 4.2 kB 1 [emitted] 002fc3bb6fc14459f8e8.js 2.23 kB 2 [emitted] 9356e9a0fb00a97b2e73.js 1.94 kB 3 [emitted] 88d78642a86768757078.js 979 bytes 4 [emitted] diff --git a/test/statsCases/aggressive-splitting-on-demand/expected.txt b/test/statsCases/aggressive-splitting-on-demand/expected.txt index 89205984e..c37ff156d 100644 --- a/test/statsCases/aggressive-splitting-on-demand/expected.txt +++ b/test/statsCases/aggressive-splitting-on-demand/expected.txt @@ -6,7 +6,7 @@ cd45585186d59208602b.js 1.96 kB 1 [emitted] 6b94c231e016c5aaccdb.js 1.94 kB 2 [emitted] fd0985cee894c4f3f1a6.js 1.94 kB 3 [emitted] d9fc46873c8ea924b895.js 979 bytes 4 [emitted] -a773fee259e5a284dea9.js 7.63 kB 6 [emitted] main +a773fee259e5a284dea9.js 7.47 kB 6 [emitted] main b08c507d4e1e05cbab45.js 985 bytes 9 [emitted] 5d50e858fe6e559aa47c.js 977 bytes 11 [emitted] Entrypoint main = a773fee259e5a284dea9.js diff --git a/test/statsCases/chunks/expected.txt b/test/statsCases/chunks/expected.txt index cc1a6fbde..c31376a9a 100644 --- a/test/statsCases/chunks/expected.txt +++ b/test/statsCases/chunks/expected.txt @@ -4,7 +4,7 @@ Time: Xms 0.bundle.js 238 bytes 0 [emitted] 1.bundle.js 108 bytes 1 [emitted] 2.bundle.js 204 bytes 2 [emitted] - bundle.js 6.27 kB 3 [emitted] main + bundle.js 6.11 kB 3 [emitted] main chunk {0} 0.bundle.js 54 bytes {3} [rendered] > [5] (webpack)/test/statsCases/chunks/index.js 3:0-16 [2] (webpack)/test/statsCases/chunks/c.js 54 bytes {0} [built] diff --git a/test/statsCases/color-disabled/expected.txt b/test/statsCases/color-disabled/expected.txt index 89a004014..bfdc113eb 100644 --- a/test/statsCases/color-disabled/expected.txt +++ b/test/statsCases/color-disabled/expected.txt @@ -1,6 +1,6 @@ Hash: 6c781fe6bf412ba6435b Time: Xms Asset Size Chunks Chunk Names -main.js 2.63 kB 0 [emitted] main +main.js 2.47 kB 0 [emitted] main chunk {0} main.js (main) 0 bytes [entry] [rendered] [0] (webpack)/test/statsCases/color-disabled/index.js 0 bytes {0} [built] \ No newline at end of file diff --git a/test/statsCases/color-enabled-custom/expected.txt b/test/statsCases/color-enabled-custom/expected.txt index e75eca438..4ece616c4 100644 --- a/test/statsCases/color-enabled-custom/expected.txt +++ b/test/statsCases/color-enabled-custom/expected.txt @@ -1,6 +1,6 @@ Hash: 6c781fe6bf412ba6435b Time: Xms Asset Size Chunks Chunk Names -main.js 2.63 kB 0 [emitted] main +main.js 2.47 kB 0 [emitted] main chunk {0} main.js (main) 0 bytes [entry] [rendered] [0] (webpack)/test/statsCases/color-enabled-custom/index.js 0 bytes {0} [built] \ No newline at end of file diff --git a/test/statsCases/color-enabled/expected.txt b/test/statsCases/color-enabled/expected.txt index 3873582f1..b835db9f1 100644 --- a/test/statsCases/color-enabled/expected.txt +++ b/test/statsCases/color-enabled/expected.txt @@ -1,6 +1,6 @@ Hash: 6c781fe6bf412ba6435b Time: Xms Asset Size Chunks Chunk Names -main.js 2.63 kB 0 [emitted] main +main.js 2.47 kB 0 [emitted] main chunk {0} main.js (main) 0 bytes [entry] [rendered] [0] (webpack)/test/statsCases/color-enabled/index.js 0 bytes {0} [built] \ No newline at end of file diff --git a/test/statsCases/commons-chunk-min-size-0/expected.txt b/test/statsCases/commons-chunk-min-size-0/expected.txt index d56bbc66c..f265ca90a 100644 --- a/test/statsCases/commons-chunk-min-size-0/expected.txt +++ b/test/statsCases/commons-chunk-min-size-0/expected.txt @@ -2,7 +2,7 @@ Hash: dc6038bec87a57d1a45e Time: Xms Asset Size Chunks Chunk Names entry-1.js 25 bytes 0 [emitted] entry-1 -vendor-1.js 6.92 kB 1 [emitted] vendor-1 +vendor-1.js 6.76 kB 1 [emitted] vendor-1 chunk {0} entry-1.js (entry-1) 0 bytes {1} [initial] [rendered] chunk {1} vendor-1.js (vendor-1) 329 bytes [entry] [rendered] [0] (webpack)/test/statsCases/commons-chunk-min-size-0/modules/a.js 22 bytes {1} [built] diff --git a/test/statsCases/commons-chunk-min-size-Infinity/expected.txt b/test/statsCases/commons-chunk-min-size-Infinity/expected.txt index 7fc0b94b5..71a9b135a 100644 --- a/test/statsCases/commons-chunk-min-size-Infinity/expected.txt +++ b/test/statsCases/commons-chunk-min-size-Infinity/expected.txt @@ -1,8 +1,8 @@ Hash: 9c0d5be5c7febb314e7a Time: Xms Asset Size Chunks Chunk Names - entry-1.js 3.27 kB 0 [emitted] entry-1 -vendor-1.js 3.02 kB 1 [emitted] vendor-1 + entry-1.js 3.11 kB 0 [emitted] entry-1 +vendor-1.js 2.85 kB 1 [emitted] vendor-1 chunk {0} entry-1.js (entry-1) 277 bytes [entry] [rendered] [0] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/a.js 22 bytes {0} {1} [built] [1] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/b.js 22 bytes {0} {1} [built] diff --git a/test/statsCases/define-plugin/expected.txt b/test/statsCases/define-plugin/expected.txt index d208e1168..2305b3e70 100644 --- a/test/statsCases/define-plugin/expected.txt +++ b/test/statsCases/define-plugin/expected.txt @@ -3,13 +3,13 @@ Child Hash: 052d0451a89cb963e4d3 Time: Xms Asset Size Chunks Chunk Names - main.js 2.68 kB 0 [emitted] main + main.js 2.52 kB 0 [emitted] main chunk {0} main.js (main) 24 bytes [entry] [rendered] [0] (webpack)/test/statsCases/define-plugin/index.js 24 bytes {0} [built] Child Hash: eb3ff8e5a88b9234d04f Time: Xms Asset Size Chunks Chunk Names - main.js 2.68 kB 0 [emitted] main + main.js 2.52 kB 0 [emitted] main chunk {0} main.js (main) 24 bytes [entry] [rendered] [0] (webpack)/test/statsCases/define-plugin/index.js 24 bytes {0} [built] \ No newline at end of file diff --git a/test/statsCases/exclude-with-loader/expected.txt b/test/statsCases/exclude-with-loader/expected.txt index af7ff0f8d..a0562e5b1 100644 --- a/test/statsCases/exclude-with-loader/expected.txt +++ b/test/statsCases/exclude-with-loader/expected.txt @@ -1,7 +1,7 @@ Hash: 7ab067a6a9fc61623ae0 Time: Xms - Asset Size Chunks Chunk Names -bundle.js 2.9 kB 0 [emitted] main + Asset Size Chunks Chunk Names +bundle.js 2.74 kB 0 [emitted] main chunk {0} bundle.js (main) 132 bytes [entry] [rendered] [0] (webpack)/test/statsCases/exclude-with-loader/a.txt 43 bytes {0} [built] [2] (webpack)/test/statsCases/exclude-with-loader/index.js 46 bytes {0} [built] diff --git a/test/statsCases/external/expected.txt b/test/statsCases/external/expected.txt index 18706b3f9..671cbcc3e 100644 --- a/test/statsCases/external/expected.txt +++ b/test/statsCases/external/expected.txt @@ -1,7 +1,7 @@ Hash: 86950abf8dcf924d9cc1 Time: Xms Asset Size Chunks Chunk Names -main.js 2.77 kB 0 [emitted] main +main.js 2.61 kB 0 [emitted] main chunk {0} main.js (main) 59 bytes [entry] [rendered] [0] (webpack)/test/statsCases/external/index.js 17 bytes {0} [built] [1] external "test" 42 bytes {0} [not cacheable] \ No newline at end of file diff --git a/test/statsCases/filter-warnings/expected.txt b/test/statsCases/filter-warnings/expected.txt index f51c93065..dcee17631 100644 --- a/test/statsCases/filter-warnings/expected.txt +++ b/test/statsCases/filter-warnings/expected.txt @@ -12,7 +12,7 @@ Child Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] - Dropping side-effect-free statement [./index.js:6,0] + Collapsing variable someRequiredUsedFunction [./index.js:5,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] @@ -67,7 +67,7 @@ Child Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] - Dropping side-effect-free statement [./index.js:6,0] + Collapsing variable someRequiredUsedFunction [./index.js:5,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] @@ -86,7 +86,7 @@ Child Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] - Dropping side-effect-free statement [./index.js:6,0] + Collapsing variable someRequiredUsedFunction [./index.js:5,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] @@ -105,7 +105,7 @@ Child Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] - Dropping side-effect-free statement [./index.js:6,0] + Collapsing variable someRequiredUsedFunction [./index.js:5,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] @@ -124,7 +124,7 @@ Child Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] - Dropping side-effect-free statement [./index.js:6,0] + Collapsing variable someRequiredUsedFunction [./index.js:5,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] @@ -143,7 +143,7 @@ Child Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] - Dropping side-effect-free statement [./index.js:6,0] + Collapsing variable someRequiredUsedFunction [./index.js:5,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] @@ -162,7 +162,7 @@ Child Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] - Dropping side-effect-free statement [./index.js:6,0] + Collapsing variable someRequiredUsedFunction [./index.js:5,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] diff --git a/test/statsCases/limit-chunk-count-plugin/expected.txt b/test/statsCases/limit-chunk-count-plugin/expected.txt index 6e558fdfe..0f81a20d2 100644 --- a/test/statsCases/limit-chunk-count-plugin/expected.txt +++ b/test/statsCases/limit-chunk-count-plugin/expected.txt @@ -2,8 +2,8 @@ Hash: 7785ad0c3d45a94a3238a8178dd1adacd47a6b70043f3d1f8be496acf7a6e0df24380874d1 Child Hash: 7785ad0c3d45a94a3238 Time: Xms - Asset Size Chunks Chunk Names - bundle.js 3.56 kB 0 [emitted] main + Asset Size Chunks Chunk Names + bundle.js 3.4 kB 0 [emitted] main chunk {0} bundle.js (main) 191 bytes [entry] [rendered] [0] (webpack)/test/statsCases/limit-chunk-count-plugin/a.js 22 bytes {0} [built] [1] (webpack)/test/statsCases/limit-chunk-count-plugin/b.js 22 bytes {0} [built] @@ -16,7 +16,7 @@ Child Time: Xms Asset Size Chunks Chunk Names 0.bundle.js 592 bytes 0 [emitted] - bundle.js 6.29 kB 1 [emitted] main + bundle.js 6.12 kB 1 [emitted] main chunk {0} 0.bundle.js 118 bytes {1} [rendered] [0] (webpack)/test/statsCases/limit-chunk-count-plugin/a.js 22 bytes {0} [built] [1] (webpack)/test/statsCases/limit-chunk-count-plugin/b.js 22 bytes {0} [built] @@ -31,7 +31,7 @@ Child Asset Size Chunks Chunk Names 0.bundle.js 445 bytes 0 [emitted] 1.bundle.js 204 bytes 1 [emitted] - bundle.js 6.27 kB 2 [emitted] main + bundle.js 6.11 kB 2 [emitted] main chunk {0} 0.bundle.js 74 bytes {2} [rendered] [0] (webpack)/test/statsCases/limit-chunk-count-plugin/a.js 22 bytes {0} [built] [2] (webpack)/test/statsCases/limit-chunk-count-plugin/c.js 30 bytes {0} [built] @@ -48,7 +48,7 @@ Child 0.bundle.js 204 bytes 0 [emitted] 1.bundle.js 195 bytes 1 [emitted] 2.bundle.js 283 bytes 2 [emitted] - bundle.js 6.26 kB 3 [emitted] main + bundle.js 6.1 kB 3 [emitted] main chunk {0} 0.bundle.js 44 bytes {2} {3} [rendered] [1] (webpack)/test/statsCases/limit-chunk-count-plugin/b.js 22 bytes {0} [built] [4] (webpack)/test/statsCases/limit-chunk-count-plugin/e.js 22 bytes {0} [built] diff --git a/test/statsCases/max-modules-default/expected.txt b/test/statsCases/max-modules-default/expected.txt index 6f4233e4b..28d7d6790 100644 --- a/test/statsCases/max-modules-default/expected.txt +++ b/test/statsCases/max-modules-default/expected.txt @@ -1,7 +1,7 @@ Hash: 8f4b66734cb63e0581be Time: Xms Asset Size Chunks Chunk Names -main.js 5.95 kB 0 [emitted] main +main.js 5.79 kB 0 [emitted] main chunk {0} main.js (main) 1.18 kB [entry] [rendered] [0] (webpack)/test/statsCases/max-modules-default/a.js?1 33 bytes {0} [built] [1] (webpack)/test/statsCases/max-modules-default/a.js?10 33 bytes {0} [built] diff --git a/test/statsCases/max-modules/expected.txt b/test/statsCases/max-modules/expected.txt index 16a20b5f2..c8d3f2d2a 100644 --- a/test/statsCases/max-modules/expected.txt +++ b/test/statsCases/max-modules/expected.txt @@ -1,7 +1,7 @@ Hash: 8f4b66734cb63e0581be Time: Xms Asset Size Chunks Chunk Names -main.js 5.95 kB 0 [emitted] main +main.js 5.79 kB 0 [emitted] main chunk {0} main.js (main) 1.18 kB [entry] [rendered] [0] (webpack)/test/statsCases/max-modules/a.js?1 33 bytes {0} [built] [1] (webpack)/test/statsCases/max-modules/a.js?10 33 bytes {0} [built] diff --git a/test/statsCases/module-trace-disabled-in-error/expected.txt b/test/statsCases/module-trace-disabled-in-error/expected.txt index 423af5c6e..1f9b72f65 100644 --- a/test/statsCases/module-trace-disabled-in-error/expected.txt +++ b/test/statsCases/module-trace-disabled-in-error/expected.txt @@ -1,7 +1,7 @@ Hash: 6e950f2e83663cb6e9a6 Time: Xms Asset Size Chunks Chunk Names -main.js 2.81 kB 0 [emitted] main +main.js 2.65 kB 0 [emitted] main chunk {0} main.js (main) 25 bytes [entry] [rendered] [0] (webpack)/test/statsCases/module-trace-disabled-in-error/index.js 25 bytes {0} [built] diff --git a/test/statsCases/module-trace-enabled-in-error/expected.txt b/test/statsCases/module-trace-enabled-in-error/expected.txt index edb194098..e5ad8c65a 100644 --- a/test/statsCases/module-trace-enabled-in-error/expected.txt +++ b/test/statsCases/module-trace-enabled-in-error/expected.txt @@ -1,7 +1,7 @@ Hash: 6e950f2e83663cb6e9a6 Time: Xms Asset Size Chunks Chunk Names -main.js 2.81 kB 0 [emitted] main +main.js 2.65 kB 0 [emitted] main chunk {0} main.js (main) 25 bytes [entry] [rendered] [0] (webpack)/test/statsCases/module-trace-enabled-in-error/index.js 25 bytes {0} [built] diff --git a/test/statsCases/named-chunks-plugin-async/expected.txt b/test/statsCases/named-chunks-plugin-async/expected.txt index bdd1c509f..16ad228b5 100644 --- a/test/statsCases/named-chunks-plugin-async/expected.txt +++ b/test/statsCases/named-chunks-plugin-async/expected.txt @@ -3,7 +3,7 @@ Time: Xms Asset Size Chunks Chunk Names chunk-containing-__a_js.js 266 bytes chunk-containing-__a_js [emitted] chunk-containing-__b_js.js 123 bytes chunk-containing-__b_js [emitted] - entry.js 6.15 kB entry [emitted] entry + entry.js 5.99 kB entry [emitted] entry chunk {chunk-containing-__a_js} chunk-containing-__a_js.js 37 bytes {entry} [rendered] [2] (webpack)/test/statsCases/named-chunks-plugin-async/modules/a.js 37 bytes {chunk-containing-__a_js} [built] chunk {chunk-containing-__b_js} chunk-containing-__b_js.js 22 bytes {chunk-containing-__a_js} {entry} [rendered] diff --git a/test/statsCases/named-chunks-plugin/expected.txt b/test/statsCases/named-chunks-plugin/expected.txt index c4704ca4d..503a569d9 100644 --- a/test/statsCases/named-chunks-plugin/expected.txt +++ b/test/statsCases/named-chunks-plugin/expected.txt @@ -2,7 +2,7 @@ Hash: ac63e5be974bcdfea3a3 Time: Xms Asset Size Chunks Chunk Names entry.js 345 bytes entry [emitted] entry -manifest.js 5.95 kB manifest [emitted] manifest +manifest.js 5.78 kB manifest [emitted] manifest vendor.js 397 bytes vendor [emitted] vendor chunk {entry} entry.js (entry) 94 bytes {vendor} [initial] [rendered] [./entry.js] (webpack)/test/statsCases/named-chunks-plugin/entry.js 72 bytes {entry} [built] diff --git a/test/statsCases/optimize-chunks/expected.txt b/test/statsCases/optimize-chunks/expected.txt index 49f2369d0..4f4efd372 100644 --- a/test/statsCases/optimize-chunks/expected.txt +++ b/test/statsCases/optimize-chunks/expected.txt @@ -8,7 +8,7 @@ Time: Xms 4.js 140 bytes 4, 6 [emitted] chunk 5.js 306 bytes 5, 3 [emitted] cir2 from cir1 6.js 80 bytes 6 [emitted] ac in ab -main.js 6.94 kB 7 [emitted] main +main.js 6.78 kB 7 [emitted] main chunk {0} 0.js (cir1) 81 bytes {3} {5} {7} [rendered] > duplicate cir1 from cir2 [3] (webpack)/test/statsCases/optimize-chunks/circular2.js 1:0-79 > duplicate cir1 [7] (webpack)/test/statsCases/optimize-chunks/index.js 13:0-54 diff --git a/test/statsCases/performance-no-async-chunks-shown/expected.txt b/test/statsCases/performance-no-async-chunks-shown/expected.txt index 3437df4c2..ed7cf6e5c 100644 --- a/test/statsCases/performance-no-async-chunks-shown/expected.txt +++ b/test/statsCases/performance-no-async-chunks-shown/expected.txt @@ -1,6 +1,6 @@ Time: Xms Asset Size Chunks Chunk Names - sec.js 2.98 kB 0 [emitted] sec + sec.js 2.82 kB 0 [emitted] sec main.js 303 kB 1 [emitted] [big] main Entrypoint main [big] = main.js Entrypoint sec = sec.js diff --git a/test/statsCases/preset-verbose/expected.txt b/test/statsCases/preset-verbose/expected.txt index f53f5e384..5ad626004 100644 --- a/test/statsCases/preset-verbose/expected.txt +++ b/test/statsCases/preset-verbose/expected.txt @@ -4,7 +4,7 @@ Time: Xms 0.js 238 bytes 0 [emitted] 1.js 108 bytes 1 [emitted] 2.js 204 bytes 2 [emitted] -main.js 6.26 kB 3 [emitted] main +main.js 6.1 kB 3 [emitted] main Entrypoint main = main.js chunk {0} 0.js 54 bytes {3} [rendered] [2] (webpack)/test/statsCases/preset-verbose/c.js 54 bytes {0} [depth 1] [built] diff --git a/test/statsCases/resolve-plugin-context/expected.txt b/test/statsCases/resolve-plugin-context/expected.txt index ef3c9661c..a6da5097f 100644 --- a/test/statsCases/resolve-plugin-context/expected.txt +++ b/test/statsCases/resolve-plugin-context/expected.txt @@ -1,7 +1,7 @@ Hash: 94e1d97f3e1cf37e753f Time: Xms Asset Size Chunks Chunk Names -bundle.js 3.04 kB 0 [emitted] main +bundle.js 2.88 kB 0 [emitted] main chunk {0} bundle.js (main) 80 bytes [entry] [rendered] [0] (webpack)/test/statsCases/resolve-plugin-context/node_modules/xyz/index.js 0 bytes {0} [built] [1] (webpack)/test/statsCases/resolve-plugin-context/index.js 48 bytes {0} [built] diff --git a/test/statsCases/reverse-sort-modules/expected.txt b/test/statsCases/reverse-sort-modules/expected.txt index bf4a49031..710321d88 100644 --- a/test/statsCases/reverse-sort-modules/expected.txt +++ b/test/statsCases/reverse-sort-modules/expected.txt @@ -1,7 +1,7 @@ Hash: 8f4b66734cb63e0581be Time: Xms Asset Size Chunks Chunk Names -main.js 5.95 kB 0 [emitted] main +main.js 5.79 kB 0 [emitted] main chunk {0} main.js (main) 1.18 kB [entry] [rendered] [30] (webpack)/test/statsCases/reverse-sort-modules/index.js 181 bytes {0} [built] [28] (webpack)/test/statsCases/reverse-sort-modules/c.js?8 33 bytes {0} [built] diff --git a/test/statsCases/separate-css-bundle/expected.txt b/test/statsCases/separate-css-bundle/expected.txt index d7862ad52..41c9683d1 100644 --- a/test/statsCases/separate-css-bundle/expected.txt +++ b/test/statsCases/separate-css-bundle/expected.txt @@ -3,7 +3,7 @@ Child Hash: 0be4035986816982617a Time: Xms Asset Size Chunks Chunk Names - c7ab11336573e45dc51e.js 2.78 kB 0 [emitted] main + c7ab11336573e45dc51e.js 2.62 kB 0 [emitted] main c815cf440254d4f3bba4e7041db00a28.css 26 bytes 0 [emitted] main chunk {0} c7ab11336573e45dc51e.js, c815cf440254d4f3bba4e7041db00a28.css (main) 64 bytes [entry] [rendered] [0] (webpack)/test/statsCases/separate-css-bundle/a/file.css 41 bytes {0} [built] @@ -16,7 +16,7 @@ Child Hash: 1139e89514abc13454ce Time: Xms Asset Size Chunks Chunk Names - c7ab11336573e45dc51e.js 2.78 kB 0 [emitted] main + c7ab11336573e45dc51e.js 2.62 kB 0 [emitted] main a3f385680aef7a9bb2a517699532cc34.css 28 bytes 0 [emitted] main chunk {0} c7ab11336573e45dc51e.js, a3f385680aef7a9bb2a517699532cc34.css (main) 64 bytes [entry] [rendered] [0] (webpack)/test/statsCases/separate-css-bundle/b/file.css 41 bytes {0} [built] diff --git a/test/statsCases/simple-more-info/expected.txt b/test/statsCases/simple-more-info/expected.txt index 2058e7a0d..dc090aaae 100644 --- a/test/statsCases/simple-more-info/expected.txt +++ b/test/statsCases/simple-more-info/expected.txt @@ -1,7 +1,7 @@ Hash: 0bd4f09244f0e8c60354 Time: Xms Asset Size Chunks Chunk Names -bundle.js 2.63 kB 0 [emitted] main +bundle.js 2.47 kB 0 [emitted] main chunk {0} bundle.js (main) 0 bytes [entry] [rendered] > main [0] (webpack)/test/statsCases/simple-more-info/index.js [0] (webpack)/test/statsCases/simple-more-info/index.js 0 bytes {0} [built] diff --git a/test/statsCases/simple/expected.txt b/test/statsCases/simple/expected.txt index 71893b161..082e6d4d7 100644 --- a/test/statsCases/simple/expected.txt +++ b/test/statsCases/simple/expected.txt @@ -1,6 +1,6 @@ Hash: 0bd4f09244f0e8c60354 Time: Xms Asset Size Chunks Chunk Names -bundle.js 2.63 kB 0 [emitted] main +bundle.js 2.47 kB 0 [emitted] main chunk {0} bundle.js (main) 0 bytes [entry] [rendered] [0] (webpack)/test/statsCases/simple/index.js 0 bytes {0} [built] \ No newline at end of file diff --git a/test/statsCases/tree-shaking/expected.txt b/test/statsCases/tree-shaking/expected.txt index a6b3bed4a..daaca66cc 100644 --- a/test/statsCases/tree-shaking/expected.txt +++ b/test/statsCases/tree-shaking/expected.txt @@ -1,7 +1,7 @@ Hash: 347e6d2384c1a580ac4d Time: Xms Asset Size Chunks Chunk Names -bundle.js 7.49 kB 0 [emitted] main +bundle.js 7.33 kB 0 [emitted] main chunk {0} bundle.js (main) 588 bytes [entry] [rendered] [0] (webpack)/test/statsCases/tree-shaking/a.js 13 bytes {0} [built] [exports: a] From 6b31b4e085fc5b7322ddd2ec83e32657f4608272 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sun, 21 May 2017 20:16:09 +0200 Subject: [PATCH 16/40] don't use __webpack_require__.i in DefinePlugin --- lib/DefinePlugin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/DefinePlugin.js b/lib/DefinePlugin.js index b2414a578..99bac5fb2 100644 --- a/lib/DefinePlugin.js +++ b/lib/DefinePlugin.js @@ -35,7 +35,7 @@ class DefinePlugin { }(definitions, "")); function stringifyObj(obj) { - return "__webpack_require__.i({" + Object.keys(obj).map((key) => { + return "Object({" + Object.keys(obj).map((key) => { const code = obj[key]; return JSON.stringify(key) + ":" + toCode(code); }).join(",") + "})"; From 1ebca7e55df2a9caa4cf78d9c0bcfeb260bb3cdd Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sun, 21 May 2017 20:16:39 +0200 Subject: [PATCH 17/40] use `Object` constructor to clear context from functions --- .../HarmonyImportSpecifierDependency.js | 2 +- lib/dependencies/HarmonyModulesPlugin.js | 13 ------------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/lib/dependencies/HarmonyImportSpecifierDependency.js b/lib/dependencies/HarmonyImportSpecifierDependency.js index 746f747ea..1e7ceb6c7 100644 --- a/lib/dependencies/HarmonyImportSpecifierDependency.js +++ b/lib/dependencies/HarmonyImportSpecifierDependency.js @@ -97,7 +97,7 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen } if(dep.call && dep.id) { - return `${shortHandPrefix}__webpack_require__.i(${importedVar}${importedVarSuffix})`; + return `${shortHandPrefix}Object(${importedVar}${importedVarSuffix})`; } return `${shortHandPrefix}${importedVar}${importedVarSuffix}`; diff --git a/lib/dependencies/HarmonyModulesPlugin.js b/lib/dependencies/HarmonyModulesPlugin.js index 0b6c3e408..1b8969c5e 100644 --- a/lib/dependencies/HarmonyModulesPlugin.js +++ b/lib/dependencies/HarmonyModulesPlugin.js @@ -66,19 +66,6 @@ class HarmonyModulesPlugin { new HarmonyExportDependencyParserPlugin() ); }); - - if(this.options.strictThisContextOnImports) { - compilation.mainTemplate.plugin("require-extensions", (source, chunk, hash) => { - - const buf = [source]; - - buf.push(""); - buf.push("// identity function for calling harmony imports with the correct context"); - buf.push(`${compilation.mainTemplate.requireFn}.i = function(value) { return value; };`); - - return buf.join("\n"); - }); - } }); } } From 8d5a8da16db52bb95297d3d8bad46ff286e5dabf Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sun, 21 May 2017 21:26:54 +0200 Subject: [PATCH 18/40] fix uglify test cases --- test/configCases/plugins/uglifyjs-plugin/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/configCases/plugins/uglifyjs-plugin/index.js b/test/configCases/plugins/uglifyjs-plugin/index.js index 040074e30..9d81d8042 100644 --- a/test/configCases/plugins/uglifyjs-plugin/index.js +++ b/test/configCases/plugins/uglifyjs-plugin/index.js @@ -20,7 +20,7 @@ it("should pass mangle options", function() { var fs = require("fs"), path = require("path"); var source = fs.readFileSync(path.join(__dirname, "ie8.js"), "utf-8"); - source.should.containEql("function r(n){return function(t){try{n()}catch(n){t(n)}}}"); + source.should.containEql("function r(t){return function(n){try{t()}catch(t){n(t)}}}"); }); it("should extract comments to separate file", function() { @@ -48,7 +48,7 @@ it("should pass compress options", function() { var fs = require("fs"), path = require("path"); var source = fs.readFileSync(path.join(__dirname, "compress.js"), "utf-8"); - source.should.containEql("function e(){var n=2;n=3,console.log(1+n),console.log(n+3),console.log(4),console.log(1+n+3)}"); + source.should.containEql("function e(){var o=2;o=3,console.log(1+o),console.log(o+3),console.log(4),console.log(1+o+3)}"); }); require.include("./test.js"); From 2bc666207bdb1063e6e93d875b1a0f2f274cb474 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sun, 21 May 2017 21:28:40 +0200 Subject: [PATCH 19/40] update stats snapshots --- test/statsCases/filter-warnings/expected.txt | 66 +++++++++---------- .../statsCases/warnings-uglifyjs/expected.txt | 4 +- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/test/statsCases/filter-warnings/expected.txt b/test/statsCases/filter-warnings/expected.txt index dcee17631..0d4b13cb0 100644 --- a/test/statsCases/filter-warnings/expected.txt +++ b/test/statsCases/filter-warnings/expected.txt @@ -2,8 +2,8 @@ Hash: e4d2b189bb205589ee1ee4d2b189bb205589ee1ee4d2b189bb205589ee1ee4d2b189bb2055 Child Hash: e4d2b189bb205589ee1e Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] WARNING in bundle.js from UglifyJs @@ -12,7 +12,7 @@ Child Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] - Collapsing variable someRequiredUsedFunction [./index.js:5,0] + Dropping side-effect-free statement [./index.js:6,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] @@ -21,44 +21,44 @@ Child Child Hash: e4d2b189bb205589ee1e Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] Child Hash: e4d2b189bb205589ee1e Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] Child Hash: e4d2b189bb205589ee1e Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] Child Hash: e4d2b189bb205589ee1e Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] Child Hash: e4d2b189bb205589ee1e Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] Child Hash: e4d2b189bb205589ee1e Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] Child Hash: e4d2b189bb205589ee1e Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] WARNING in bundle.js from UglifyJs @@ -67,7 +67,7 @@ Child Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] - Collapsing variable someRequiredUsedFunction [./index.js:5,0] + Dropping side-effect-free statement [./index.js:6,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] @@ -76,8 +76,8 @@ Child Child Hash: e4d2b189bb205589ee1e Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] WARNING in bundle.js from UglifyJs @@ -86,7 +86,7 @@ Child Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] - Collapsing variable someRequiredUsedFunction [./index.js:5,0] + Dropping side-effect-free statement [./index.js:6,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] @@ -95,8 +95,8 @@ Child Child Hash: e4d2b189bb205589ee1e Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] WARNING in bundle.js from UglifyJs @@ -105,7 +105,7 @@ Child Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] - Collapsing variable someRequiredUsedFunction [./index.js:5,0] + Dropping side-effect-free statement [./index.js:6,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] @@ -114,8 +114,8 @@ Child Child Hash: e4d2b189bb205589ee1e Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] WARNING in bundle.js from UglifyJs @@ -124,7 +124,7 @@ Child Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] - Collapsing variable someRequiredUsedFunction [./index.js:5,0] + Dropping side-effect-free statement [./index.js:6,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] @@ -133,8 +133,8 @@ Child Child Hash: e4d2b189bb205589ee1e Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] WARNING in bundle.js from UglifyJs @@ -143,7 +143,7 @@ Child Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] - Collapsing variable someRequiredUsedFunction [./index.js:5,0] + Dropping side-effect-free statement [./index.js:6,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] @@ -152,8 +152,8 @@ Child Child Hash: e4d2b189bb205589ee1e Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] WARNING in bundle.js from UglifyJs @@ -162,7 +162,7 @@ Child Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] - Collapsing variable someRequiredUsedFunction [./index.js:5,0] + Dropping side-effect-free statement [./index.js:6,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] diff --git a/test/statsCases/warnings-uglifyjs/expected.txt b/test/statsCases/warnings-uglifyjs/expected.txt index edc03af90..45d780b2f 100644 --- a/test/statsCases/warnings-uglifyjs/expected.txt +++ b/test/statsCases/warnings-uglifyjs/expected.txt @@ -1,7 +1,7 @@ Hash: 4beee256fa6b8f69eae8 Time: Xms - Asset Size Chunks Chunk Names -bundle.js 2.17 kB 0 [emitted] main + Asset Size Chunks Chunk Names +bundle.js 2.1 kB 0 [emitted] main chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] [0] (webpack)/buildin/module.js 495 bytes {0} [built] [1] (webpack)/test/statsCases/warnings-uglifyjs/a.js 249 bytes {0} [built] From 9f8cdd28a9d1452894db8355b4f8c0504e0fd593 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sun, 21 May 2017 23:41:33 +0200 Subject: [PATCH 20/40] add missing file --- examples/scope-hoisting/webpack.config.js | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 examples/scope-hoisting/webpack.config.js diff --git a/examples/scope-hoisting/webpack.config.js b/examples/scope-hoisting/webpack.config.js new file mode 100644 index 000000000..da883a7c1 --- /dev/null +++ b/examples/scope-hoisting/webpack.config.js @@ -0,0 +1,7 @@ +var webpack = require("../../"); + +module.exports = { + plugins: [ + new webpack.optimize.ModuleConcatenationPlugin() + ] +}; From 1c3bef901c1e6db958c6098930c1059b97121b8c Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 22 May 2017 20:04:23 +0200 Subject: [PATCH 21/40] merge PR #4884 again by @filipesilva --- lib/optimize/ConcatenatedModule.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/optimize/ConcatenatedModule.js b/lib/optimize/ConcatenatedModule.js index 08dc6424e..e721a853a 100644 --- a/lib/optimize/ConcatenatedModule.js +++ b/lib/optimize/ConcatenatedModule.js @@ -288,7 +288,7 @@ class ConcatenatedModule extends Module { const result = new ConcatSource(); if(moduleToInfoMap.get(this.rootModule).needCompatibilityFlag) { - result.add(`Object.defineProperty(${this.rootModule.moduleArgument || "exports"}, "__esModule", { value: true });\n`); + result.add(`Object.defineProperty(${this.rootModule.exportsArgument || "exports"}, "__esModule", { value: true });\n`); } modulesWithInfo.forEach(info => { result.add(`\n// CONCATENATED MODULE: ${info.module.readableIdentifier(requestShortener)}\n`); From 1886105608de67accffccb07a626fdf781947211 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 24 May 2017 11:22:29 +0200 Subject: [PATCH 22/40] add test case --- test/cases/scope-hoisting/intra-references/a.js | 1 + test/cases/scope-hoisting/intra-references/b.js | 1 + test/cases/scope-hoisting/intra-references/c.js | 1 + test/cases/scope-hoisting/intra-references/index.js | 9 +++++++++ 4 files changed, 12 insertions(+) create mode 100644 test/cases/scope-hoisting/intra-references/a.js create mode 100644 test/cases/scope-hoisting/intra-references/b.js create mode 100644 test/cases/scope-hoisting/intra-references/c.js create mode 100644 test/cases/scope-hoisting/intra-references/index.js diff --git a/test/cases/scope-hoisting/intra-references/a.js b/test/cases/scope-hoisting/intra-references/a.js new file mode 100644 index 000000000..dfb1001dd --- /dev/null +++ b/test/cases/scope-hoisting/intra-references/a.js @@ -0,0 +1 @@ +export { default } from "./b"; diff --git a/test/cases/scope-hoisting/intra-references/b.js b/test/cases/scope-hoisting/intra-references/b.js new file mode 100644 index 000000000..04134a85c --- /dev/null +++ b/test/cases/scope-hoisting/intra-references/b.js @@ -0,0 +1 @@ +export { default } from "./c"; diff --git a/test/cases/scope-hoisting/intra-references/c.js b/test/cases/scope-hoisting/intra-references/c.js new file mode 100644 index 000000000..5c6b89abf --- /dev/null +++ b/test/cases/scope-hoisting/intra-references/c.js @@ -0,0 +1 @@ +export default "ok"; diff --git a/test/cases/scope-hoisting/intra-references/index.js b/test/cases/scope-hoisting/intra-references/index.js new file mode 100644 index 000000000..371843667 --- /dev/null +++ b/test/cases/scope-hoisting/intra-references/index.js @@ -0,0 +1,9 @@ +import value from "./a"; + +it("should have the correct values", function() { + value.should.be.eql("ok"); +}); + + +// prevent scope hoisting of b +require("./b"); From b4d25208f44500b47902d4ba7002f958df25566a Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 24 May 2017 11:22:42 +0200 Subject: [PATCH 23/40] filter modules from modules array --- lib/optimize/ModuleConcatenationPlugin.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/optimize/ModuleConcatenationPlugin.js b/lib/optimize/ModuleConcatenationPlugin.js index 0aaa90513..cb349e1cb 100644 --- a/lib/optimize/ModuleConcatenationPlugin.js +++ b/lib/optimize/ModuleConcatenationPlugin.js @@ -90,6 +90,7 @@ class ModuleConcatenationPlugin { reason.dependency.module = newModule; }); } + compilation.modules = compilation.modules.filter(m => !usedModules.has(m)); }); }); }); From d8539561fd334f3379629f33b9d0c44c27d3e72b Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sun, 28 May 2017 15:25:07 +0200 Subject: [PATCH 24/40] add optimization bailout info track optimization bailout in concat plugin --- bin/webpack.js | 10 ++ lib/FunctionModuleTemplatePlugin.js | 22 +-- lib/Module.js | 1 + lib/Stats.js | 15 ++ lib/optimize/ConcatenatedModule.js | 1 + lib/optimize/ModuleConcatenationPlugin.js | 168 ++++++++++++++++------ schemas/webpackOptionsSchema.json | 12 ++ 7 files changed, 175 insertions(+), 54 deletions(-) diff --git a/bin/webpack.js b/bin/webpack.js index 37125533c..7bed86add 100755 --- a/bin/webpack.js +++ b/bin/webpack.js @@ -124,6 +124,11 @@ yargs.options({ group: DISPLAY_GROUP, describe: "Display information about exports provided from modules" }, + "display-optimization-bailout": { + type: "boolean", + group: DISPLAY_GROUP, + describe: "Display information about why optimization bailed out for modules" + }, "display-error-details": { type: "boolean", group: DISPLAY_GROUP, @@ -144,6 +149,7 @@ if(argv.verbose) { argv["display-entrypoints"] = true; argv["display-used-exports"] = true; argv["display-provided-exports"] = true; + argv["display-optimization-bailout"] = true; argv["display-error-details"] = true; argv["display-modules"] = true; argv["display-cached"] = true; @@ -243,6 +249,10 @@ function processOptions(options) { outputOptions.providedExports = bool; }); + ifArg("display-optimization-bailout", function(bool) { + outputOptions.optimizationBailout = bool; + }); + ifArg("display-error-details", function(bool) { outputOptions.errorDetails = bool; }); diff --git a/lib/FunctionModuleTemplatePlugin.js b/lib/FunctionModuleTemplatePlugin.js index ede3c1a96..32bcb47bc 100644 --- a/lib/FunctionModuleTemplatePlugin.js +++ b/lib/FunctionModuleTemplatePlugin.js @@ -25,17 +25,23 @@ class FunctionModuleTemplatePlugin { if(this.outputOptions.pathinfo) { const source = new ConcatSource(); const req = module.readableIdentifier(this.requestShortener); - if(Array.isArray(module.providedExports)) - source.add("/* exports provided: " + module.providedExports.join(", ") + " */\n"); - else if(module.providedExports) - source.add("/* unknown exports provided */\n"); - if(Array.isArray(module.usedExports)) - source.add("/* exports used: " + module.usedExports.join(", ") + " */\n"); - else if(module.usedExports) - source.add("/* all exports used */\n"); source.add("/*!****" + req.replace(/./g, "*") + "****!*\\\n"); source.add(" !*** " + req.replace(/\*\//g, "*_/") + " ***!\n"); source.add(" \\****" + req.replace(/./g, "*") + "****/\n"); + if(Array.isArray(module.providedExports)) + source.add("/*! exports provided: " + module.providedExports.join(", ") + " */\n"); + else if(module.providedExports) + source.add("/*! unknown exports provided */\n"); + if(Array.isArray(module.usedExports)) + source.add("/*! exports used: " + module.usedExports.join(", ") + " */\n"); + else if(module.usedExports) + source.add("/*! all exports used */\n"); + if(module.optimizationBailout) { + module.optimizationBailout.forEach(text => { + if(typeof text === "function") text = text(this.requestShortener); + source.add(`/*! ${text} */\n`); + }); + } source.add(moduleSource); return source; } diff --git a/lib/Module.js b/lib/Module.js index dec871c55..f946ce971 100644 --- a/lib/Module.js +++ b/lib/Module.js @@ -51,6 +51,7 @@ class Module extends DependenciesBlock { this.dependenciesErrors = []; this.strict = false; this.meta = {}; + this.optimizationBailout = []; } disconnect() { diff --git a/lib/Stats.js b/lib/Stats.js index a2c7f415b..85d9e4350 100644 --- a/lib/Stats.js +++ b/lib/Stats.js @@ -93,6 +93,7 @@ class Stats { const showReasons = optionOrFallback(options.reasons, !forToString); const showUsedExports = optionOrFallback(options.usedExports, !forToString); const showProvidedExports = optionOrFallback(options.providedExports, !forToString); + const showOptimizationBailout = optionOrFallback(options.optimizationBailout, !forToString); const showChildren = optionOrFallback(options.children, true); const showSource = optionOrFallback(options.source, !forToString); const showModuleTrace = optionOrFallback(options.moduleTrace, true); @@ -311,6 +312,12 @@ class Stats { if(showProvidedExports) { obj.providedExports = Array.isArray(module.providedExports) ? module.providedExports : null; } + if(showOptimizationBailout) { + obj.optimizationBailout = module.optimizationBailout.map(item => { + if(typeof item === "function") return item(requestShortener); + return item; + }); + } if(showDepth) { obj.depth = module.depth; } @@ -636,6 +643,13 @@ class Stats { newline(); } } + if(Array.isArray(module.optimizationBailout)) { + module.optimizationBailout.forEach(item => { + colors.normal(prefix); + colors.yellow(item); + newline(); + }); + } if(module.reasons) { module.reasons.forEach(reason => { colors.normal(prefix); @@ -867,6 +881,7 @@ class Stats { depth: pn === "verbose", usedExports: pn === "verbose", providedExports: pn === "verbose", + optimizationBailout: pn === "verbose", colors: true, performance: true }; diff --git a/lib/optimize/ConcatenatedModule.js b/lib/optimize/ConcatenatedModule.js index e721a853a..3514afa46 100644 --- a/lib/optimize/ConcatenatedModule.js +++ b/lib/optimize/ConcatenatedModule.js @@ -58,6 +58,7 @@ class ConcatenatedModule extends Module { this.modules = modules; this.usedExports = rootModule.usedExports; this.providedExports = rootModule.providedExports; + this.optimizationBailout = rootModule.optimizationBailout; this.used = rootModule.used; this._chunks = new Set(rootModule._chunks); this.index = rootModule.index; diff --git a/lib/optimize/ModuleConcatenationPlugin.js b/lib/optimize/ModuleConcatenationPlugin.js index cb349e1cb..b140b1b7f 100644 --- a/lib/optimize/ModuleConcatenationPlugin.js +++ b/lib/optimize/ModuleConcatenationPlugin.js @@ -21,47 +21,107 @@ class ModuleConcatenationPlugin { parser.state.module.meta.hasEval = true; }); }); + const bailoutReasonMap = new Map(); + function setBailoutReason(module, reason) { + bailoutReasonMap.set(module, reason); + module.optimizationBailout.push(reason); + } + function getBailoutReason(module, requestShortener) { + const reason = bailoutReasonMap.get(module); + if(typeof reason === "function") return reason(requestShortener); + return reason; + } compilation.plugin("optimize-chunk-modules", (chunks, modules) => { chunks.forEach(chunk => { - const relevantModules = chunk.mapModules(m => m).filter(module => { + const relevantModules = []; + const possibleInners = new Set(); + for(const module of chunk.modulesIterable) { + // Only harmony modules are valid for optimization + if(!module.meta || !module.meta.harmonyModule) { + continue; + } + // Module must not be in other chunks // TODO add an option to allow module to be in other entry points - if(module.getNumberOfChunks() !== 1) - return false; + if(module.getNumberOfChunks() !== 1) { + setBailoutReason(module, "ModuleConcatenation: module is in multiple chunks"); + continue; + } // Because of variable renaming we can't use modules with eval - if(module.meta && module.meta.hasEval) - return false; + if(module.meta && module.meta.hasEval) { + setBailoutReason(module, "ModuleConcatenation: eval is used in the module"); + continue; + } + + relevantModules.push(module); - return true; - }); - const possibleInners = new Set(relevantModules.filter(module => { // Module must not be the entry points - if(chunk.entryModule === module) - return false; + if(chunk.entryModule === module) { + setBailoutReason(module, "ModuleConcatenation (inner): module is an entrypoint"); + continue; + } // Exports must be known (and not dynamic) - if(!Array.isArray(module.providedExports)) - return false; + if(!Array.isArray(module.providedExports)) { + setBailoutReason(module, "ModuleConcatenation (inner): exports are not known"); + continue; + } // Using dependency variables is not possible as this wraps the code in a function - if(module.variables.length > 0) - return false; + if(module.variables.length > 0) { + setBailoutReason(module, "ModuleConcatenation (inner): dependency variables are used (i. e. ProvidePlugin)"); + continue; + } // Module must only be used by Harmony Imports - if(!module.reasons.every(reason => reason.dependency instanceof HarmonyImportDependency)) - return false; - - return true; - })); - const concatConfigurations = []; - for(const currentRoot of relevantModules) { - const currentConfiguration = new ConcatConfiguration(currentRoot); - for(const imp of this.getImports(currentRoot)) { - this.tryToAdd(currentConfiguration, imp, possibleInners); + const nonHarmonyReasons = module.reasons.filter(reason => !(reason.dependency instanceof HarmonyImportDependency)); + if(nonHarmonyReasons.length > 0) { + const importingModules = new Set(nonHarmonyReasons.map(r => r.module)); + setBailoutReason(module, (requestShortener) => { + const names = Array.from(importingModules).map(m => m.readableIdentifier(requestShortener)); + return `ModuleConcatenation (inner): module is used with non-harmony imports from ${names.join(", ")}`; + }); + continue; } - if(!currentConfiguration.isEmpty()) + + possibleInners.add(module); + } + // sort by depth + // modules with lower depth are more likly suited as roots + // this improves performance, because modules already selected as inner are skipped + relevantModules.sort((a, b) => { + return a.depth - b.depth; + }); + const concatConfigurations = []; + const usedAsInner = new Set(); + for(const currentRoot of relevantModules) { + // when used by another configuration as inner: + // the other configuration is better and we can skip this one + if(usedAsInner.has(currentRoot)) + continue; + + // create a configuration with the root + const currentConfiguration = new ConcatConfiguration(currentRoot); + + // cache failures to add modules + const failureCache = new Map(); + + // try to add all imports + for(const imp of this.getImports(currentRoot)) { + const problem = this.tryToAdd(currentConfiguration, imp, possibleInners, failureCache); + if(problem) { + failureCache.set(imp, problem); + currentConfiguration.addWarning(imp, problem); + } + } + if(!currentConfiguration.isEmpty()) { concatConfigurations.push(currentConfiguration); + for(const module of currentConfiguration.modules) { + if(module !== currentConfiguration.rootModule) + usedAsInner.add(module); + } + } } // HACK: Sort configurations by length and start with the longest one // to get the biggers groups possible. Used modules are marked with usedModules @@ -77,6 +137,16 @@ class ModuleConcatenationPlugin { const orderedModules = new Set(); this.addInOrder(concatConfiguration.rootModule, concatConfiguration.modules, orderedModules); const newModule = new ConcatenatedModule(concatConfiguration.rootModule, Array.from(orderedModules)); + for(const warning of concatConfiguration.warnings) { + newModule.optimizationBailout.push((requestShortener) => { + const reason = getBailoutReason(warning[0], requestShortener); + const reasonPrefix = reason ? `: ${reason}` : ""; + if(warning[0] === warning[1]) + return `ModuleConcatenation: Cannot concat with ${warning[0].readableIdentifier(requestShortener)}${reasonPrefix}`; + else + return `ModuleConcatenation: Cannot concat with ${warning[0].readableIdentifier(requestShortener)} because of ${warning[1].readableIdentifier(requestShortener)}${reasonPrefix}`; + }); + } for(const m of orderedModules) { usedModules.add(m); chunk.removeModule(m); @@ -85,10 +155,7 @@ class ModuleConcatenationPlugin { compilation.modules.push(newModule); if(chunk.entryModule === concatConfiguration.rootModule) chunk.entryModule = newModule; - concatConfiguration.rootModule.reasons.forEach(reason => { - if(!concatConfiguration.modules.has(reason.module)) - reason.dependency.module = newModule; - }); + newModule.reasons.forEach(reason => reason.dependency.module = newModule); } compilation.modules = compilation.modules.filter(m => !usedModules.has(m)); }); @@ -117,19 +184,20 @@ class ModuleConcatenationPlugin { )); } - tryToAdd(config, module, possibleModules) { - // console.log("tryToAdd", module.debugId, module.resource); + tryToAdd(config, module, possibleModules, failureCache) { + const cacheEntry = failureCache.get(module); + if(cacheEntry) { + return cacheEntry; + } // Already added? if(config.has(module)) { - // console.log("already added"); - return true; + return null; } // Not possible to add? if(!possibleModules.has(module)) { - // console.log("not possible"); - return false; + return module; } // Clone config to make experimental changes @@ -139,25 +207,25 @@ class ModuleConcatenationPlugin { testConfig.add(module); // Every module which depends on the added module must be in the configuration too. - // console.log("reasons start"); for(const reason of module.reasons) { - if(!this.tryToAdd(testConfig, reason.module, possibleModules)) { - // console.log("reason failed"); - return false; + const problem = this.tryToAdd(testConfig, reason.module, possibleModules, failureCache); + if(problem) { + failureCache.set(module, problem); // cache failures for performance + return problem; } } - // console.log("reasons end"); // Eagerly try to add imports too if possible - // console.log("imports start"); - for(const imp of this.getImports(module)) - this.tryToAdd(testConfig, imp, possibleModules); - // console.log("imports end"); + for(const imp of this.getImports(module)) { + const problem = this.tryToAdd(testConfig, imp, possibleModules, failureCache); + if(problem) { + config.addWarning(module, problem); + } + } - // console.log("commit"); // Commit experimental changes config.set(testConfig); - return true; + return null; } addInOrder(module, unorderedSet, orderedSet) { @@ -175,6 +243,7 @@ class ConcatConfiguration { constructor(rootModule) { this.rootModule = rootModule; this.modules = new Set([rootModule]); + this.warnings = new Map(); } add(module) { @@ -189,16 +258,23 @@ class ConcatConfiguration { return this.modules.size === 1; } + addWarning(module, problem) { + this.warnings.set(module, problem); + } + clone() { const clone = new ConcatConfiguration(this.rootModule); for(const module of this.modules) clone.add(module); + for(const pair of this.warnings) + clone.addWarning(pair[0], pair[1]); return clone; } set(config) { this.rootModule = config.rootModule; this.modules = new Set(config.modules); + this.warnings = new Map(config.warnings); } } diff --git a/schemas/webpackOptionsSchema.json b/schemas/webpackOptionsSchema.json index 5e5294773..b0efa1514 100644 --- a/schemas/webpackOptionsSchema.json +++ b/schemas/webpackOptionsSchema.json @@ -1011,6 +1011,18 @@ "assetsSort": { "type": "string", "description": "sort the assets by that field" + }, + "providedExports": { + "type": "boolean", + "description": "show exports provided by modules" + }, + "usedExports": { + "type": "boolean", + "description": "show exports used by modules" + }, + "optimizationBailout": { + "type": "boolean", + "description": "show reasons why optimization bailed out for modules" } } }, From 44bf6c245f76839e3926a442346c8de17334b27a Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sun, 28 May 2017 15:29:26 +0200 Subject: [PATCH 25/40] update graph correctly --- lib/optimize/ConcatenatedModule.js | 1 + lib/optimize/ModuleConcatenationPlugin.js | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/lib/optimize/ConcatenatedModule.js b/lib/optimize/ConcatenatedModule.js index 3514afa46..ffd67a3b3 100644 --- a/lib/optimize/ConcatenatedModule.js +++ b/lib/optimize/ConcatenatedModule.js @@ -68,6 +68,7 @@ class ConcatenatedModule extends Module { this.cacheable = modules.every(m => m.cacheable); const modulesSet = new Set(modules); this.reasons = rootModule.reasons.filter(reason => !modulesSet.has(reason.module)); + this.dependencies = [].concat.apply([], modules.map(m => m.dependencies.filter(dep => !modulesSet.has(dep.module)))); this.meta = rootModule.meta; this.dependenciesWarnings = modules.reduce((w, m) => m.dependenciesWarnings.forEach(x => w.push(x)), []); this.dependenciesErrors = modules.reduce((w, m) => m.dependenciesErrors.forEach(x => w.push(x)), []); diff --git a/lib/optimize/ModuleConcatenationPlugin.js b/lib/optimize/ModuleConcatenationPlugin.js index b140b1b7f..257920717 100644 --- a/lib/optimize/ModuleConcatenationPlugin.js +++ b/lib/optimize/ModuleConcatenationPlugin.js @@ -156,6 +156,14 @@ class ModuleConcatenationPlugin { if(chunk.entryModule === concatConfiguration.rootModule) chunk.entryModule = newModule; newModule.reasons.forEach(reason => reason.dependency.module = newModule); + newModule.dependencies.forEach(dep => { + if(dep.module) { + dep.module.reasons.forEach(reason => { + if(reason.dependency === dep) + reason.module = newModule; + }); + } + }); } compilation.modules = compilation.modules.filter(m => !usedModules.has(m)); }); From f1739f9af971bfe01a23c4c96a8104ce3fa938bb Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sun, 28 May 2017 17:19:48 +0200 Subject: [PATCH 26/40] add new hook to progress --- lib/ProgressPlugin.js | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/lib/ProgressPlugin.js b/lib/ProgressPlugin.js index 19ded4690..f0bad2fad 100644 --- a/lib/ProgressPlugin.js +++ b/lib/ProgressPlugin.js @@ -82,17 +82,19 @@ class ProgressPlugin { "optimize-chunks": [0.77, "chunk optimization"], "optimize-chunks-advanced": [0.78, "advanced chunk optimization"], // optimize-tree - "revive-modules": [0.80, "module reviving"], - "optimize-module-order": [0.81, "module order optimization"], - "optimize-module-ids": [0.82, "module id optimization"], - "revive-chunks": [0.83, "chunk reviving"], - "optimize-chunk-order": [0.84, "chunk order optimization"], - "optimize-chunk-ids": [0.85, "chunk id optimization"], - "before-hash": [0.86, "hashing"], - "before-module-assets": [0.87, "module assets processing"], - "before-chunk-assets": [0.88, "chunk assets processing"], - "additional-chunk-assets": [0.89, "additional chunk assets processing"], - "record": [0.90, "recording"] + "optimize-chunk-modules": [0.80, "chunk modules optimization"], + "optimize-chunk-modules-advanced": [0.81, "advanced chunk modules optimization"], + "revive-modules": [0.82, "module reviving"], + "optimize-module-order": [0.83, "module order optimization"], + "optimize-module-ids": [0.84, "module id optimization"], + "revive-chunks": [0.85, "chunk reviving"], + "optimize-chunk-order": [0.86, "chunk order optimization"], + "optimize-chunk-ids": [0.87, "chunk id optimization"], + "before-hash": [0.88, "hashing"], + "before-module-assets": [0.89, "module assets processing"], + "before-chunk-assets": [0.90, "chunk assets processing"], + "additional-chunk-assets": [0.91, "additional chunk assets processing"], + "record": [0.92, "recording"] }; Object.keys(syncHooks).forEach(name => { let pass = 0; From 8b81788a7331cb5adfa9ecadbf686d51aade59cb Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sun, 28 May 2017 19:20:17 +0200 Subject: [PATCH 27/40] fixes for stats --- lib/Stats.js | 1 + test/Stats.test.js | 2 ++ 2 files changed, 3 insertions(+) diff --git a/lib/Stats.js b/lib/Stats.js index 85d9e4350..d78bb4ac6 100644 --- a/lib/Stats.js +++ b/lib/Stats.js @@ -858,6 +858,7 @@ class Stats { depth: false, usedExports: false, providedExports: false, + optimizationBailout: false, children: false, source: false, errors: false, diff --git a/test/Stats.test.js b/test/Stats.test.js index 9943d9a50..75e5407bf 100644 --- a/test/Stats.test.js +++ b/test/Stats.test.js @@ -167,6 +167,7 @@ describe("Stats", () => { depth: false, usedExports: false, providedExports: false, + optimizationBailout: false, colors: true, performance: true }); @@ -194,6 +195,7 @@ describe("Stats", () => { depth: false, usedExports: false, providedExports: false, + optimizationBailout: false, children: false, source: false, errors: false, From 6a0e5877682e830bef6ca9898a69462aee82f135 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sun, 28 May 2017 23:31:58 +0200 Subject: [PATCH 28/40] spacing --- lib/optimize/ModuleConcatenationPlugin.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/optimize/ModuleConcatenationPlugin.js b/lib/optimize/ModuleConcatenationPlugin.js index 257920717..7e1759353 100644 --- a/lib/optimize/ModuleConcatenationPlugin.js +++ b/lib/optimize/ModuleConcatenationPlugin.js @@ -22,15 +22,18 @@ class ModuleConcatenationPlugin { }); }); const bailoutReasonMap = new Map(); + function setBailoutReason(module, reason) { bailoutReasonMap.set(module, reason); module.optimizationBailout.push(reason); } + function getBailoutReason(module, requestShortener) { const reason = bailoutReasonMap.get(module); if(typeof reason === "function") return reason(requestShortener); return reason; } + compilation.plugin("optimize-chunk-modules", (chunks, modules) => { chunks.forEach(chunk => { const relevantModules = []; From cc8e729ff4c308ab27abbbae263b1c6765c682d8 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 31 May 2017 16:46:25 +0200 Subject: [PATCH 29/40] detect conflicts with other variables fixes #4967 --- lib/optimize/ConcatenatedModule.js | 39 +++++++++++++++---- .../scope-hoisting/renaming-4967/file1.js | 10 +++++ .../scope-hoisting/renaming-4967/index.js | 5 +++ .../scope-hoisting/renaming-4967/module.js | 18 +++++++++ 4 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 test/cases/scope-hoisting/renaming-4967/file1.js create mode 100644 test/cases/scope-hoisting/renaming-4967/index.js create mode 100644 test/cases/scope-hoisting/renaming-4967/module.js diff --git a/lib/optimize/ConcatenatedModule.js b/lib/optimize/ConcatenatedModule.js index ffd67a3b3..5a09da769 100644 --- a/lib/optimize/ConcatenatedModule.js +++ b/lib/optimize/ConcatenatedModule.js @@ -51,6 +51,23 @@ function getFinalName(info, exportName, moduleToInfoMap, requestShortener) { `known reexports: ${Array.from(info.reexportMap.keys()).join(" ")})`); } +function getSymbolsFromScope(s, untilScope) { + const allUsedNames = new Set(); + let scope = s; + while(scope) { + if(untilScope === scope) break; + scope.variables.forEach(variable => allUsedNames.add(variable.name)); + scope = scope.upper; + } + return allUsedNames; +} + +function reduceSet(a, b) { + for(const item of b) + a.add(item); + return a; +} + class ConcatenatedModule extends Module { constructor(rootModule, modules) { super(); @@ -236,20 +253,27 @@ class ConcatenatedModule extends Module { // get all global names modulesWithInfo.forEach(info => { - info.globalScope.through.map(reference => reference.identifier.name).forEach(name => { - if(!/^__WEBPACK_MODULE_REFERENCE__\d+_(\d+|ns)__$/.test(name)) + info.globalScope.through.forEach(reference => { + const name = reference.identifier.name; + if(/^__WEBPACK_MODULE_REFERENCE__\d+_(\d+|ns)__$/.test(name)) { + for(const s of getSymbolsFromScope(reference.from, info.moduleScope)) { + allUsedNames.add(s); + } + } else { allUsedNames.add(name); + } }); }); modulesWithInfo.forEach(info => { - const namespaceObjectName = this.findNewName("namespaceObject", allUsedNames, info.module.readableIdentifier(requestShortener)); + const namespaceObjectName = this.findNewName("namespaceObject", allUsedNames, null, info.module.readableIdentifier(requestShortener)); info.internalNames.set(namespaceObjectName, namespaceObjectName); info.exportMap.set(true, namespaceObjectName); info.moduleScope.variables.forEach(variable => { const name = variable.name; if(allUsedNames.has(name)) { - const newName = this.findNewName(name, allUsedNames, info.module.readableIdentifier(requestShortener)); + const symbolsInReferences = variable.references.map(ref => getSymbolsFromScope(ref.from, info.moduleScope)).reduce(reduceSet, new Set()); + const newName = this.findNewName(name, allUsedNames, symbolsInReferences, info.module.readableIdentifier(requestShortener)); allUsedNames.add(newName); info.internalNames.set(name, newName); const source = info.source; @@ -309,7 +333,7 @@ class ConcatenatedModule extends Module { return result; } - findNewName(oldName, usedNamed, extraInfo) { + findNewName(oldName, usedNamed1, usedNamed2, extraInfo) { let name = oldName; if(name === "__WEBPACK_MODULE_DEFAULT_EXPORT__") @@ -318,10 +342,11 @@ class ConcatenatedModule extends Module { const splittedInfo = extraInfo.split("/"); while(splittedInfo.length) { name = splittedInfo.pop() + "_" + name; - if(!usedNamed.has(Template.toIdentifier(name))) return Template.toIdentifier(name); + const nameIdent = Template.toIdentifier(name); + if(!usedNamed1.has(nameIdent) && (!usedNamed2 || !usedNamed2.has(nameIdent))) return nameIdent; } - while(!usedNamed.has(name = name + "_")); + while(usedNamed1.has(name = name + "_") || (usedNamed2 && usedNamed2.has(name))) { /* do nothing */ } return name; } diff --git a/test/cases/scope-hoisting/renaming-4967/file1.js b/test/cases/scope-hoisting/renaming-4967/file1.js new file mode 100644 index 000000000..952255b8c --- /dev/null +++ b/test/cases/scope-hoisting/renaming-4967/file1.js @@ -0,0 +1,10 @@ +export function a() { + return "ok"; +} + +export function test() { + function file1_js_a() { + return "fail"; + } + return a(); +} diff --git a/test/cases/scope-hoisting/renaming-4967/index.js b/test/cases/scope-hoisting/renaming-4967/index.js new file mode 100644 index 000000000..445ebec05 --- /dev/null +++ b/test/cases/scope-hoisting/renaming-4967/index.js @@ -0,0 +1,5 @@ +it("should check existing variables when renaming", function() { + require("./module").d.x().should.be.eql("ok"); + require("./module").c.a().should.be.eql("ok"); + require("./module").test().should.be.eql("ok"); +}); diff --git a/test/cases/scope-hoisting/renaming-4967/module.js b/test/cases/scope-hoisting/renaming-4967/module.js new file mode 100644 index 000000000..d597dacb3 --- /dev/null +++ b/test/cases/scope-hoisting/renaming-4967/module.js @@ -0,0 +1,18 @@ +import { a as b, test } from './file1'; + +var c = { + a: function a() { + return b(); + }, +}; + +var d = { + x: function x() { + function a() { + return "fail"; + } + return b(); + }, +}; + +export { c, d, test }; From 0f16dd95b196198021bc480ffd4d639d83c2b65b Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Tue, 17 Jan 2017 22:26:38 +0100 Subject: [PATCH 30/40] fixes incorrect CLI stats output add "detailed" preset clean up presets to do more useful stuff fixes #4141 fixes #4118 --- bin/webpack.js | 68 +++-- lib/Stats.js | 246 ++++++++++-------- schemas/webpackOptionsSchema.json | 1 + test/BinTestCases.test.js | 4 +- test/MultiStats.test.js | 1 - test/Stats.test.js | 39 +-- test/binCases/entry/multi-file/test.opts | 5 + test/binCases/entry/named-entry/test.opts | 5 + .../entry/non-hyphenated-args/test.opts | 5 + .../uglifyjsplugin-empty-args/test.opts | 5 + test/binCases/stats/custom-preset/index.js | 1 + test/binCases/stats/custom-preset/test.js | 8 + test/binCases/stats/custom-preset/test.opts | 5 + test/binCases/stats/none/index.js | 1 + test/binCases/stats/none/test.js | 8 + test/binCases/stats/none/webpack.config.js | 6 + test/binCases/stats/single-config/test.js | 7 +- .../watch/multi-config-watch-opt/test.opts | 5 + .../watch/single-config-watch-opt/test.opts | 5 + .../webpack.config.js | 11 +- .../webpack.config.js | 11 +- test/statsCases/chunks/expected.txt | 19 +- test/statsCases/chunks/webpack.config.js | 12 +- test/statsCases/color-disabled/expected.txt | 3 +- .../color-enabled-custom/expected.txt | 3 +- test/statsCases/color-enabled/expected.txt | 3 +- .../commons-chunk-min-size-0/expected.txt | 18 +- .../expected.txt | 21 +- test/statsCases/define-plugin/expected.txt | 6 +- .../exclude-with-loader/expected.txt | 7 +- test/statsCases/external/expected.txt | 5 +- test/statsCases/filter-warnings/expected.txt | 13 - .../max-modules-default/expected.txt | 33 ++- test/statsCases/max-modules/expected.txt | 43 ++- .../expected.txt | 3 +- .../expected.txt | 3 +- .../named-chunks-plugin-async/expected.txt | 9 +- .../named-chunks-plugin/expected.txt | 13 +- .../optimize-chunks/webpack.config.js | 3 + .../performance-disabled/expected.txt | 16 +- .../statsCases/performance-error/expected.txt | 16 +- .../expected.txt | 15 +- .../performance-no-hints/expected.txt | 16 +- .../expected.txt | 9 +- test/statsCases/preset-detailed/a.js | 1 + test/statsCases/preset-detailed/b.js | 1 + test/statsCases/preset-detailed/c.js | 1 + test/statsCases/preset-detailed/d.js | 1 + test/statsCases/preset-detailed/e.js | 1 + test/statsCases/preset-detailed/expected.txt | 22 ++ test/statsCases/preset-detailed/index.js | 3 + .../preset-detailed/webpack.config.js | 4 + .../preset-minimal-simple/expected.txt | 2 +- test/statsCases/preset-minimal/expected.txt | 5 +- .../preset-mixed-array/expected.txt | 5 +- .../expected.txt | 16 +- .../preset-normal-performance/expected.txt | 16 +- test/statsCases/preset-normal/expected.txt | 15 +- test/statsCases/preset-verbose/expected.txt | 4 + .../resolve-plugin-context/expected.txt | 1 - .../reverse-sort-modules/expected.txt | 43 ++- .../separate-css-bundle/expected.txt | 26 +- test/statsCases/simple-more-info/expected.txt | 4 - test/statsCases/simple/expected.txt | 3 +- test/statsCases/tree-shaking/expected.txt | 1 - .../statsCases/warnings-uglifyjs/expected.txt | 1 - 66 files changed, 445 insertions(+), 467 deletions(-) mode change 100755 => 100644 bin/webpack.js create mode 100644 test/binCases/stats/custom-preset/index.js create mode 100644 test/binCases/stats/custom-preset/test.js create mode 100644 test/binCases/stats/custom-preset/test.opts create mode 100644 test/binCases/stats/none/index.js create mode 100644 test/binCases/stats/none/test.js create mode 100644 test/binCases/stats/none/webpack.config.js create mode 100644 test/statsCases/preset-detailed/a.js create mode 100644 test/statsCases/preset-detailed/b.js create mode 100644 test/statsCases/preset-detailed/c.js create mode 100644 test/statsCases/preset-detailed/d.js create mode 100644 test/statsCases/preset-detailed/e.js create mode 100644 test/statsCases/preset-detailed/expected.txt create mode 100644 test/statsCases/preset-detailed/index.js create mode 100644 test/statsCases/preset-detailed/webpack.config.js diff --git a/bin/webpack.js b/bin/webpack.js old mode 100755 new mode 100644 index 7bed86add..3c41d5b6e --- a/bin/webpack.js +++ b/bin/webpack.js @@ -134,6 +134,11 @@ yargs.options({ group: DISPLAY_GROUP, describe: "Display details about errors" }, + "display": { + type: "string", + group: DISPLAY_GROUP, + describe: "Select display preset (verbose, detailed, normal, minimal, errors-only, none)" + }, "verbose": { type: "boolean", group: DISPLAY_GROUP, @@ -144,16 +149,7 @@ yargs.options({ var argv = yargs.argv; if(argv.verbose) { - argv["display-reasons"] = true; - argv["display-depth"] = true; - argv["display-entrypoints"] = true; - argv["display-used-exports"] = true; - argv["display-provided-exports"] = true; - argv["display-optimization-bailout"] = true; - argv["display-error-details"] = true; - argv["display-modules"] = true; - argv["display-cached"] = true; - argv["display-cached-assets"] = true; + argv["display"] = "verbose"; } var options = require("./convert-argv")(yargs, argv); @@ -187,6 +183,11 @@ function processOptions(options) { } else if(!outputOptions) { outputOptions = {}; } + + ifArg("display", function(preset) { + outputOptions = statsPresetToOptions(preset); + }); + outputOptions = Object.create(outputOptions); if(Array.isArray(options) && !outputOptions.children) { outputOptions.children = options.map(o => o.stats); @@ -225,28 +226,36 @@ function processOptions(options) { outputOptions.cachedAssets = false; ifArg("display-chunks", function(bool) { - outputOptions.modules = !bool; - outputOptions.chunks = bool; + if(bool) { + outputOptions.modules = false; + outputOptions.chunks = true; + outputOptions.chunkModules = true; + } }); ifArg("display-entrypoints", function(bool) { - outputOptions.entrypoints = bool; + if(bool) + outputOptions.entrypoints = true; }); ifArg("display-reasons", function(bool) { - outputOptions.reasons = bool; + if(bool) + outputOptions.reasons = true; }); ifArg("display-depth", function(bool) { - outputOptions.depth = bool; + if(bool) + outputOptions.depth = true; }); ifArg("display-used-exports", function(bool) { - outputOptions.usedExports = bool; + if(bool) + outputOptions.usedExports = true; }); ifArg("display-provided-exports", function(bool) { - outputOptions.providedExports = bool; + if(bool) + outputOptions.providedExports = true; }); ifArg("display-optimization-bailout", function(bool) { @@ -254,11 +263,13 @@ function processOptions(options) { }); ifArg("display-error-details", function(bool) { - outputOptions.errorDetails = bool; + if(bool) + outputOptions.errorDetails = true; }); ifArg("display-origins", function(bool) { - outputOptions.chunkOrigins = bool; + if(bool) + outputOptions.chunkOrigins = true; }); ifArg("display-max-modules", function(value) { @@ -282,21 +293,6 @@ function processOptions(options) { outputOptions.maxModules = Infinity; outputOptions.exclude = undefined; } - } else { - if(typeof outputOptions.chunks === "undefined") - outputOptions.chunks = true; - if(typeof outputOptions.entrypoints === "undefined") - outputOptions.entrypoints = true; - if(typeof outputOptions.modules === "undefined") - outputOptions.modules = true; - if(typeof outputOptions.chunkModules === "undefined") - outputOptions.chunkModules = true; - if(typeof outputOptions.reasons === "undefined") - outputOptions.reasons = true; - if(typeof outputOptions.cached === "undefined") - outputOptions.cached = true; - if(typeof outputOptions.cachedAssets === "undefined") - outputOptions.cachedAssets = true; } ifArg("hide-modules", function(bool) { @@ -347,7 +343,9 @@ function processOptions(options) { process.stdout.write(JSON.stringify(stats.toJson(outputOptions), null, 2) + "\n"); } else if(stats.hash !== lastHash) { lastHash = stats.hash; - process.stdout.write(stats.toString(outputOptions) + "\n"); + var statsString = stats.toString(outputOptions); + if(statsString) + process.stdout.write(statsString + "\n"); } if(!options.watch && stats.hasErrors()) { process.on("exit", function() { diff --git a/lib/Stats.js b/lib/Stats.js index d78bb4ac6..75ec6bd4f 100644 --- a/lib/Stats.js +++ b/lib/Stats.js @@ -8,7 +8,7 @@ const RequestShortener = require("./RequestShortener"); const SizeFormatHelpers = require("./SizeFormatHelpers"); const formatLocation = require("./formatLocation"); -const optionOrFallback = (optionValue, fallbackValue) => optionValue !== undefined ? optionValue : fallbackValue; +const optionOrFallback = (optionValue, fallbackValue) => typeof optionValue !== "undefined" ? optionValue : fallbackValue; class Stats { constructor(compilation) { @@ -75,51 +75,62 @@ class Stats { options = {}; } + const optionOrLocalFallback = (v, def) => + typeof v !== "undefined" ? v : + typeof options.all !== "undefined" ? options.all : def; + const compilation = this.compilation; const requestShortener = new RequestShortener(optionOrFallback(options.context, process.cwd())); - const showPerformance = optionOrFallback(options.performance, true); - const showHash = optionOrFallback(options.hash, true); - const showVersion = optionOrFallback(options.version, true); - const showTimings = optionOrFallback(options.timings, true); - const showAssets = optionOrFallback(options.assets, true); - const showEntrypoints = optionOrFallback(options.entrypoints, !forToString); - const showChunks = optionOrFallback(options.chunks, true); - const showChunkModules = optionOrFallback(options.chunkModules, !!forToString); - const showChunkOrigins = optionOrFallback(options.chunkOrigins, !forToString); - const showModules = optionOrFallback(options.modules, !forToString); - const showDepth = optionOrFallback(options.depth, !forToString); - const showCachedModules = optionOrFallback(options.cached, true); - const showCachedAssets = optionOrFallback(options.cachedAssets, true); - const showReasons = optionOrFallback(options.reasons, !forToString); - const showUsedExports = optionOrFallback(options.usedExports, !forToString); - const showProvidedExports = optionOrFallback(options.providedExports, !forToString); - const showOptimizationBailout = optionOrFallback(options.optimizationBailout, !forToString); - const showChildren = optionOrFallback(options.children, true); - const showSource = optionOrFallback(options.source, !forToString); - const showModuleTrace = optionOrFallback(options.moduleTrace, true); - const showErrors = optionOrFallback(options.errors, true); - const showErrorDetails = optionOrFallback(options.errorDetails, !forToString); - const showWarnings = optionOrFallback(options.warnings, true); + const showPerformance = optionOrLocalFallback(options.performance, true); + const showHash = optionOrLocalFallback(options.hash, true); + const showVersion = optionOrLocalFallback(options.version, true); + const showTimings = optionOrLocalFallback(options.timings, true); + const showAssets = optionOrLocalFallback(options.assets, true); + const showEntrypoints = optionOrLocalFallback(options.entrypoints, !forToString); + const showChunks = optionOrLocalFallback(options.chunks, !forToString); + const showChunkModules = optionOrLocalFallback(options.chunkModules, !!forToString); + const showChunkOrigins = optionOrLocalFallback(options.chunkOrigins, !forToString); + const showModules = optionOrLocalFallback(options.modules, true); + const showDepth = optionOrLocalFallback(options.depth, !forToString); + const showCachedModules = optionOrLocalFallback(options.cached, true); + const showCachedAssets = optionOrLocalFallback(options.cachedAssets, true); + const showReasons = optionOrLocalFallback(options.reasons, !forToString); + const showUsedExports = optionOrLocalFallback(options.usedExports, !forToString); + const showProvidedExports = optionOrLocalFallback(options.providedExports, !forToString); + const showOptimizationBailout = optionOrLocalFallback(options.optimizationBailout, !forToString); + const showChildren = optionOrLocalFallback(options.children, true); + const showSource = optionOrLocalFallback(options.source, !forToString); + const showModuleTrace = optionOrLocalFallback(options.moduleTrace, true); + const showErrors = optionOrLocalFallback(options.errors, true); + const showErrorDetails = optionOrLocalFallback(options.errorDetails, !forToString); + const showWarnings = optionOrLocalFallback(options.warnings, true); const warningsFilter = optionOrFallback(options.warningsFilter, null); - const showPublicPath = optionOrFallback(options.publicPath, !forToString); - const excludeModules = [].concat(optionOrFallback(options.exclude, [])).map(str => { - if(typeof str !== "string") return str; - return new RegExp(`[\\\\/]${str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")}([\\\\/]|$|!|\\?)`); + const showPublicPath = optionOrLocalFallback(options.publicPath, !forToString); + const excludeModules = [].concat(optionOrFallback(options.exclude, [])).map(item => { + if(typeof item === "string") { + const regExp = new RegExp(`[\\\\/]${item.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")}([\\\\/]|$|!|\\?)`); + return ident => regExp.test(ident); + } + if(item && typeof item === "object" && typeof item.test === "function") + return ident => item.test(ident); + if(typeof item === "function") + return item; }); const maxModules = optionOrFallback(options.maxModules, forToString ? 15 : Infinity); const sortModules = optionOrFallback(options.modulesSort, "id"); const sortChunks = optionOrFallback(options.chunksSort, "id"); const sortAssets = optionOrFallback(options.assetsSort, ""); + if(!showCachedModules) { + excludeModules.push((ident, module) => !module.built); + } + const createModuleFilter = () => { let i = 0; return module => { - if(!showCachedModules && !module.built) { - return false; - } if(excludeModules.length > 0) { const ident = requestShortener.shorten(module.resource); - const excluded = excludeModules.some(regExp => regExp.test(ident)); + const excluded = excludeModules.some(fn => fn(ident, module)); if(excluded) return false; } @@ -699,6 +710,35 @@ class Stats { } }; + const processModulesList = (obj, prefix) => { + if(obj.modules) { + obj.modules.forEach(module => { + colors.normal(prefix); + if(module.id < 1000) colors.normal(" "); + if(module.id < 100) colors.normal(" "); + if(module.id < 10) colors.normal(" "); + colors.normal("["); + colors.normal(module.id); + colors.normal("] "); + colors.bold(module.name || module.identifier); + processModuleAttributes(module); + newline(); + processModuleContent(module, prefix + " "); + }); + if(obj.filteredModules > 0) { + colors.normal(prefix); + colors.normal(" "); + if(obj.modules.length > 0) + colors.normal(" + "); + colors.normal(obj.filteredModules); + if(obj.modules.length > 0) + colors.normal(" hidden"); + colors.normal(obj.filteredModules !== 1 ? " modules" : " module"); + newline(); + } + } + }; + if(obj.chunks) { obj.chunks.forEach(chunk => { colors.normal("chunk "); @@ -760,45 +800,11 @@ class Stats { newline(); }); } - if(chunk.modules) { - chunk.modules.forEach(module => { - colors.normal(" "); - if(module.id < 1000) colors.normal(" "); - if(module.id < 100) colors.normal(" "); - if(module.id < 10) colors.normal(" "); - colors.normal("["); - colors.normal(module.id); - colors.normal("] "); - colors.bold(module.name); - processModuleAttributes(module); - newline(); - processModuleContent(module, " "); - }); - if(chunk.filteredModules > 0) { - colors.normal(` + ${chunk.filteredModules} hidden modules`); - newline(); - } - } + processModulesList(chunk, " "); }); } - if(obj.modules) { - obj.modules.forEach(module => { - if(module.id < 1000) colors.normal(" "); - if(module.id < 100) colors.normal(" "); - if(module.id < 10) colors.normal(" "); - colors.normal("["); - colors.normal(module.id); - colors.normal("] "); - colors.bold(module.name || module.identifier); - processModuleAttributes(module); - newline(); - processModuleContent(module, " "); - }); - if(obj.filteredModules > 0) { - colors.normal(` + ${obj.filteredModules} hidden modules`); - newline(); - } - } + + processModulesList(obj, ""); if(obj._showWarnings && obj.warnings) { obj.warnings.forEach(warning => { @@ -841,53 +847,63 @@ class Stats { } static presetToOptions(name) { - //Accepted values: none, errors-only, minimal, normal, verbose - //Any other falsy value will behave as 'none', truthy values as 'normal' - const pn = (typeof name === "string") && name.toLowerCase() || name; - if(pn === "none" || !pn) { - return { - hash: false, - version: false, - timings: false, - assets: false, - entrypoints: false, - chunks: false, - chunkModules: false, - modules: false, - reasons: false, - depth: false, - usedExports: false, - providedExports: false, - optimizationBailout: false, - children: false, - source: false, - errors: false, - errorDetails: false, - warnings: false, - publicPath: false, - performance: false - }; - } else { - return { - hash: pn !== "errors-only" && pn !== "minimal", - version: pn === "verbose", - timings: pn !== "errors-only" && pn !== "minimal", - assets: pn === "verbose", - entrypoints: pn === "verbose", - chunks: pn !== "errors-only", - chunkModules: pn === "verbose", - //warnings: pn !== "errors-only", - errorDetails: pn !== "errors-only" && pn !== "minimal", - reasons: pn === "verbose", - depth: pn === "verbose", - usedExports: pn === "verbose", - providedExports: pn === "verbose", - optimizationBailout: pn === "verbose", - colors: true, - performance: true - }; + // Accepted values: none, errors-only, minimal, normal, detailed, verbose + // Any other falsy value will behave as 'none', truthy values as 'normal' + const pn = (typeof name === "string") && name.toLowerCase() || name || "none"; + switch(pn) { + case "none": + return { + all: false + }; + case "verbose": + return { + entrypoints: true, + modules: false, + chunks: true, + chunkModules: true, + chunkOrigins: true, + depth: true, + reasons: true, + usedExports: true, + providedExports: true, + optimizationBailout: true, + errorDetails: true, + publicPath: true, + exclude: () => false, + maxModules: Infinity, + }; + case "detailed": + return { + entrypoints: true, + chunks: true, + chunkModules: false, + chunkOrigins: true, + depth: true, + usedExports: true, + providedExports: true, + optimizationBailout: true, + errorDetails: true, + publicPath: true, + exclude: () => false, + maxModules: Infinity, + }; + case "minimal": + return { + all: false, + modules: true, + maxModules: 0, + errors: true, + warnings: true, + }; + case "errors-only": + return { + all: false, + errors: true, + moduleTrace: true, + }; + default: + return {}; } - } static getChildOptions(options, idx) { diff --git a/schemas/webpackOptionsSchema.json b/schemas/webpackOptionsSchema.json index b0efa1514..9e0eb215c 100644 --- a/schemas/webpackOptionsSchema.json +++ b/schemas/webpackOptionsSchema.json @@ -1035,6 +1035,7 @@ "errors-only", "minimal", "normal", + "detailed", "verbose" ] } diff --git a/test/BinTestCases.test.js b/test/BinTestCases.test.js index 7457edf10..98fff9fe0 100644 --- a/test/BinTestCases.test.js +++ b/test/BinTestCases.test.js @@ -22,7 +22,7 @@ function getTestSpecificArguments(testDirectory) { try { return loadOptsFile(path.join(testDirectory, "test.opts")); } catch(e) { - return []; + return null; } } @@ -51,7 +51,7 @@ describe("BinTestCases", function() { category.tests.forEach(function(testName) { const testDirectory = path.join(casesPath, category.name, testName); - const testArgs = defaultArgs.concat(getTestSpecificArguments(testDirectory)); + const testArgs = getTestSpecificArguments(testDirectory) || defaultArgs; const testAssertions = require(path.join(testDirectory, "test.js")); const outputPath = path.join(path.resolve(casesPath, "../js/bin"), category.name, testName); diff --git a/test/MultiStats.test.js b/test/MultiStats.test.js index c0737a0e8..211014e88 100644 --- a/test/MultiStats.test.js +++ b/test/MultiStats.test.js @@ -210,7 +210,6 @@ describe("MultiStats", () => { "(xyz890-compilation) xyz890-warning-1", "(xyz890-compilation) xyz890-warning-2" ], - hash: "abc123xyz890", children: [{ warnings: ["abc123-warning"], errors: ["abc123-error"], diff --git a/test/Stats.test.js b/test/Stats.test.js index 75e5407bf..c49ab7930 100644 --- a/test/Stats.test.js +++ b/test/Stats.test.js @@ -154,23 +154,7 @@ describe("Stats", () => { describe("Presets", () => { describe("presetToOptions", () => { it("returns correct object with 'Normal'", () => { - Stats.presetToOptions("Normal").should.eql({ - assets: false, - version: false, - timings: true, - hash: true, - entrypoints: false, - chunks: true, - chunkModules: false, - errorDetails: true, - reasons: false, - depth: false, - usedExports: false, - providedExports: false, - optimizationBailout: false, - colors: true, - performance: true - }); + Stats.presetToOptions("Normal").should.eql({}); }); it("truthy values behave as 'normal'", () => { const normalOpts = Stats.presetToOptions("normal"); @@ -183,26 +167,7 @@ describe("Stats", () => { }); it("returns correct object with 'none'", () => { Stats.presetToOptions("none").should.eql({ - hash: false, - version: false, - timings: false, - assets: false, - entrypoints: false, - chunks: false, - chunkModules: false, - modules: false, - reasons: false, - depth: false, - usedExports: false, - providedExports: false, - optimizationBailout: false, - children: false, - source: false, - errors: false, - errorDetails: false, - warnings: false, - publicPath: false, - performance: false + all: false }); }); it("falsy values behave as 'none'", () => { diff --git a/test/binCases/entry/multi-file/test.opts b/test/binCases/entry/multi-file/test.opts index 7e426fa77..53402ac53 100644 --- a/test/binCases/entry/multi-file/test.opts +++ b/test/binCases/entry/multi-file/test.opts @@ -1 +1,6 @@ +--entry ./index.js --entry ./a.js +--config ./webpack.config.js +--output-filename [name].js +--output-chunk-filename [id].chunk.js +--target async-node diff --git a/test/binCases/entry/named-entry/test.opts b/test/binCases/entry/named-entry/test.opts index fce9b8c17..b8f0fa016 100644 --- a/test/binCases/entry/named-entry/test.opts +++ b/test/binCases/entry/named-entry/test.opts @@ -1 +1,6 @@ --entry foo=./a.js +--entry ./index.js +--config ./webpack.config.js +--output-filename [name].js +--output-chunk-filename [id].chunk.js +--target async-node diff --git a/test/binCases/entry/non-hyphenated-args/test.opts b/test/binCases/entry/non-hyphenated-args/test.opts index 777a4a4b9..6b8499d52 100644 --- a/test/binCases/entry/non-hyphenated-args/test.opts +++ b/test/binCases/entry/non-hyphenated-args/test.opts @@ -1 +1,6 @@ ./a.js +--entry ./index.js +--config ./webpack.config.js +--output-filename [name].js +--output-chunk-filename [id].chunk.js +--target async-node diff --git a/test/binCases/plugins/uglifyjsplugin-empty-args/test.opts b/test/binCases/plugins/uglifyjsplugin-empty-args/test.opts index 9c67444ed..edc5ab3dc 100644 --- a/test/binCases/plugins/uglifyjsplugin-empty-args/test.opts +++ b/test/binCases/plugins/uglifyjsplugin-empty-args/test.opts @@ -1 +1,6 @@ +--entry ./index.js +--config ./webpack.config.js +--output-filename [name].js +--output-chunk-filename [id].chunk.js +--target async-node --plugin webpack/lib/optimize/UglifyJsPlugin diff --git a/test/binCases/stats/custom-preset/index.js b/test/binCases/stats/custom-preset/index.js new file mode 100644 index 000000000..e7134e700 --- /dev/null +++ b/test/binCases/stats/custom-preset/index.js @@ -0,0 +1 @@ +module.exports = "foo"; diff --git a/test/binCases/stats/custom-preset/test.js b/test/binCases/stats/custom-preset/test.js new file mode 100644 index 000000000..0b93dfe3c --- /dev/null +++ b/test/binCases/stats/custom-preset/test.js @@ -0,0 +1,8 @@ +"use strict"; + +module.exports = function testAssertions(code, stdout, stderr) { + stderr.should.be.empty(); + code.should.be.eql(0); + + stdout.should.be.empty(); +}; diff --git a/test/binCases/stats/custom-preset/test.opts b/test/binCases/stats/custom-preset/test.opts new file mode 100644 index 000000000..4747dc2f3 --- /dev/null +++ b/test/binCases/stats/custom-preset/test.opts @@ -0,0 +1,5 @@ +--entry ./index.js +--output-filename [name].js +--output-chunk-filename [id].chunk.js +--target async-node +--display none diff --git a/test/binCases/stats/none/index.js b/test/binCases/stats/none/index.js new file mode 100644 index 000000000..e7134e700 --- /dev/null +++ b/test/binCases/stats/none/index.js @@ -0,0 +1 @@ +module.exports = "foo"; diff --git a/test/binCases/stats/none/test.js b/test/binCases/stats/none/test.js new file mode 100644 index 000000000..ee38bdcc2 --- /dev/null +++ b/test/binCases/stats/none/test.js @@ -0,0 +1,8 @@ +"use strict"; + +module.exports = function testAssertions(code, stdout, stderr) { + code.should.be.eql(0); + + stdout.should.be.empty(); + stderr.should.be.empty(); +}; diff --git a/test/binCases/stats/none/webpack.config.js b/test/binCases/stats/none/webpack.config.js new file mode 100644 index 000000000..40a6ae807 --- /dev/null +++ b/test/binCases/stats/none/webpack.config.js @@ -0,0 +1,6 @@ +var path = require("path"); + +module.exports = { + entry: path.resolve(__dirname, "./index"), + stats: "none" +}; diff --git a/test/binCases/stats/single-config/test.js b/test/binCases/stats/single-config/test.js index 02dc1de94..a961bcd51 100644 --- a/test/binCases/stats/single-config/test.js +++ b/test/binCases/stats/single-config/test.js @@ -8,9 +8,10 @@ module.exports = function testAssertions(code, stdout, stderr) { stdout[1].should.containEql("Version: "); stdout[2].should.containEql("Time: "); stdout[4].should.containEql("\u001b[1m\u001b[32mnull.js\u001b[39m\u001b[22m"); - stdout[5].should.not.containEql("./index.js"); - stdout[5].should.not.containEql("[built]"); - stdout[5].should.containEql("1 hidden module"); + stdout[5].should.containEql("chunk"); + stdout[6].should.not.containEql("./index.js"); + stdout[6].should.not.containEql("[built]"); + stdout[6].should.containEql("1 module"); stderr.should.be.empty(); }; diff --git a/test/binCases/watch/multi-config-watch-opt/test.opts b/test/binCases/watch/multi-config-watch-opt/test.opts index c4b4d4f8b..38534ad57 100644 --- a/test/binCases/watch/multi-config-watch-opt/test.opts +++ b/test/binCases/watch/multi-config-watch-opt/test.opts @@ -1 +1,6 @@ +--entry ./index.js +--config ./webpack.config.js +--output-filename [name].js +--output-chunk-filename [id].chunk.js +--target async-node --watch diff --git a/test/binCases/watch/single-config-watch-opt/test.opts b/test/binCases/watch/single-config-watch-opt/test.opts index c4b4d4f8b..38534ad57 100644 --- a/test/binCases/watch/single-config-watch-opt/test.opts +++ b/test/binCases/watch/single-config-watch-opt/test.opts @@ -1 +1,6 @@ +--entry ./index.js +--config ./webpack.config.js +--output-filename [name].js +--output-chunk-filename [id].chunk.js +--target async-node --watch diff --git a/test/statsCases/aggressive-splitting-entry/webpack.config.js b/test/statsCases/aggressive-splitting-entry/webpack.config.js index 4e58f335e..4a7dbe532 100644 --- a/test/statsCases/aggressive-splitting-entry/webpack.config.js +++ b/test/statsCases/aggressive-splitting-entry/webpack.config.js @@ -16,18 +16,11 @@ module.exports = { recordsInputPath: __dirname + "/input-records.json", //recordsOutputPath: __dirname + "/records.json", stats: { - reasons: false, + chunks: true, chunkModules: true, chunkOrigins: true, entrypoints: true, modules: false, - cached: true, - cachedAssets: true, - source: true, - errorDetails: true, - publicPath: true, - excludeModules: [ - /e\.js/ - ] + publicPath: true } }; diff --git a/test/statsCases/aggressive-splitting-on-demand/webpack.config.js b/test/statsCases/aggressive-splitting-on-demand/webpack.config.js index 4e58f335e..4a7dbe532 100644 --- a/test/statsCases/aggressive-splitting-on-demand/webpack.config.js +++ b/test/statsCases/aggressive-splitting-on-demand/webpack.config.js @@ -16,18 +16,11 @@ module.exports = { recordsInputPath: __dirname + "/input-records.json", //recordsOutputPath: __dirname + "/records.json", stats: { - reasons: false, + chunks: true, chunkModules: true, chunkOrigins: true, entrypoints: true, modules: false, - cached: true, - cachedAssets: true, - source: true, - errorDetails: true, - publicPath: true, - excludeModules: [ - /e\.js/ - ] + publicPath: true } }; diff --git a/test/statsCases/chunks/expected.txt b/test/statsCases/chunks/expected.txt index c31376a9a..e1236ea15 100644 --- a/test/statsCases/chunks/expected.txt +++ b/test/statsCases/chunks/expected.txt @@ -29,21 +29,4 @@ chunk {3} bundle.js (main) 73 bytes [entry] [rendered] cjs require ./a [5] (webpack)/test/statsCases/chunks/index.js 1:0-14 [] -> factory:Xms building:Xms = Xms [5] (webpack)/test/statsCases/chunks/index.js 51 bytes {3} [built] - factory:Xms building:Xms = Xms - [0] (webpack)/test/statsCases/chunks/a.js 22 bytes {3} [built] - cjs require ./a [5] (webpack)/test/statsCases/chunks/index.js 1:0-14 - [] -> factory:Xms building:Xms = Xms - [1] (webpack)/test/statsCases/chunks/b.js 22 bytes {1} [built] - amd require ./b [5] (webpack)/test/statsCases/chunks/index.js 2:0-16 - [] -> factory:Xms building:Xms = Xms - [2] (webpack)/test/statsCases/chunks/c.js 54 bytes {0} [built] - amd require ./c [5] (webpack)/test/statsCases/chunks/index.js 3:0-16 - [] -> factory:Xms building:Xms = Xms - [3] (webpack)/test/statsCases/chunks/d.js 22 bytes {2} [built] - require.ensure item ./d [2] (webpack)/test/statsCases/chunks/c.js 1:0-52 - [] -> factory:Xms building:Xms = Xms - [4] (webpack)/test/statsCases/chunks/e.js 22 bytes {2} [built] - require.ensure item ./e [2] (webpack)/test/statsCases/chunks/c.js 1:0-52 - [] -> factory:Xms building:Xms = Xms - [5] (webpack)/test/statsCases/chunks/index.js 51 bytes {3} [built] - factory:Xms building:Xms = Xms \ No newline at end of file + factory:Xms building:Xms = Xms \ No newline at end of file diff --git a/test/statsCases/chunks/webpack.config.js b/test/statsCases/chunks/webpack.config.js index 78a5b433e..ac4b79411 100644 --- a/test/statsCases/chunks/webpack.config.js +++ b/test/statsCases/chunks/webpack.config.js @@ -6,16 +6,10 @@ module.exports = { profile: true, stats: { reasons: true, + chunks: true, chunkModules: true, chunkOrigins: true, - modules: true, - cached: true, - cachedAssets: true, - source: true, - errorDetails: true, - publicPath: true, - excludeModules: [ - /e\.js/ - ] + modules: false, + publicPath: true } }; diff --git a/test/statsCases/color-disabled/expected.txt b/test/statsCases/color-disabled/expected.txt index bfdc113eb..9e18644ea 100644 --- a/test/statsCases/color-disabled/expected.txt +++ b/test/statsCases/color-disabled/expected.txt @@ -2,5 +2,4 @@ Hash: 6c781fe6bf412ba6435b Time: Xms Asset Size Chunks Chunk Names main.js 2.47 kB 0 [emitted] main -chunk {0} main.js (main) 0 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/color-disabled/index.js 0 bytes {0} [built] \ No newline at end of file + [0] (webpack)/test/statsCases/color-disabled/index.js 0 bytes {0} [built] \ No newline at end of file diff --git a/test/statsCases/color-enabled-custom/expected.txt b/test/statsCases/color-enabled-custom/expected.txt index 4ece616c4..f14fd735e 100644 --- a/test/statsCases/color-enabled-custom/expected.txt +++ b/test/statsCases/color-enabled-custom/expected.txt @@ -2,5 +2,4 @@ Hash: 6c781fe6bf412ba6435b Time: Xms Asset Size Chunks Chunk Names main.js 2.47 kB 0 [emitted] main -chunk {0} main.js (main) 0 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/color-enabled-custom/index.js 0 bytes {0} [built] \ No newline at end of file + [0] (webpack)/test/statsCases/color-enabled-custom/index.js 0 bytes {0} [built] \ No newline at end of file diff --git a/test/statsCases/color-enabled/expected.txt b/test/statsCases/color-enabled/expected.txt index b835db9f1..a9ee8d254 100644 --- a/test/statsCases/color-enabled/expected.txt +++ b/test/statsCases/color-enabled/expected.txt @@ -2,5 +2,4 @@ Hash: 6c781fe6bf412ba6435b Time: Xms Asset Size Chunks Chunk Names main.js 2.47 kB 0 [emitted] main -chunk {0} main.js (main) 0 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/color-enabled/index.js 0 bytes {0} [built] \ No newline at end of file + [0] (webpack)/test/statsCases/color-enabled/index.js 0 bytes {0} [built] \ No newline at end of file diff --git a/test/statsCases/commons-chunk-min-size-0/expected.txt b/test/statsCases/commons-chunk-min-size-0/expected.txt index f265ca90a..0673e9ea2 100644 --- a/test/statsCases/commons-chunk-min-size-0/expected.txt +++ b/test/statsCases/commons-chunk-min-size-0/expected.txt @@ -3,13 +3,11 @@ Time: Xms Asset Size Chunks Chunk Names entry-1.js 25 bytes 0 [emitted] entry-1 vendor-1.js 6.76 kB 1 [emitted] vendor-1 -chunk {0} entry-1.js (entry-1) 0 bytes {1} [initial] [rendered] -chunk {1} vendor-1.js (vendor-1) 329 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/commons-chunk-min-size-0/modules/a.js 22 bytes {1} [built] - [1] (webpack)/test/statsCases/commons-chunk-min-size-0/modules/b.js 22 bytes {1} [built] - [2] (webpack)/test/statsCases/commons-chunk-min-size-0/modules/c.js 22 bytes {1} [built] - [3] (webpack)/test/statsCases/commons-chunk-min-size-0/modules/d.js 22 bytes {1} [built] - [4] (webpack)/test/statsCases/commons-chunk-min-size-0/modules/e.js 22 bytes {1} [built] - [5] (webpack)/test/statsCases/commons-chunk-min-size-0/modules/f.js 22 bytes {1} [built] - [6] multi ./modules/a ./modules/b ./modules/c 52 bytes {1} [built] - [7] (webpack)/test/statsCases/commons-chunk-min-size-0/entry-1.js 145 bytes {1} [built] \ No newline at end of file + [0] (webpack)/test/statsCases/commons-chunk-min-size-0/modules/a.js 22 bytes {1} [built] + [1] (webpack)/test/statsCases/commons-chunk-min-size-0/modules/b.js 22 bytes {1} [built] + [2] (webpack)/test/statsCases/commons-chunk-min-size-0/modules/c.js 22 bytes {1} [built] + [3] (webpack)/test/statsCases/commons-chunk-min-size-0/modules/d.js 22 bytes {1} [built] + [4] (webpack)/test/statsCases/commons-chunk-min-size-0/modules/e.js 22 bytes {1} [built] + [5] (webpack)/test/statsCases/commons-chunk-min-size-0/modules/f.js 22 bytes {1} [built] + [6] multi ./modules/a ./modules/b ./modules/c 52 bytes {1} [built] + [7] (webpack)/test/statsCases/commons-chunk-min-size-0/entry-1.js 145 bytes {1} [built] \ No newline at end of file diff --git a/test/statsCases/commons-chunk-min-size-Infinity/expected.txt b/test/statsCases/commons-chunk-min-size-Infinity/expected.txt index 71a9b135a..604973f76 100644 --- a/test/statsCases/commons-chunk-min-size-Infinity/expected.txt +++ b/test/statsCases/commons-chunk-min-size-Infinity/expected.txt @@ -3,16 +3,11 @@ Time: Xms Asset Size Chunks Chunk Names entry-1.js 3.11 kB 0 [emitted] entry-1 vendor-1.js 2.85 kB 1 [emitted] vendor-1 -chunk {0} entry-1.js (entry-1) 277 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/a.js 22 bytes {0} {1} [built] - [1] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/b.js 22 bytes {0} {1} [built] - [2] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/c.js 22 bytes {0} {1} [built] - [3] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/entry-1.js 145 bytes {0} [built] - [4] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/d.js 22 bytes {0} [built] - [5] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/e.js 22 bytes {0} [built] - [6] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/f.js 22 bytes {0} [built] -chunk {1} vendor-1.js (vendor-1) 118 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/a.js 22 bytes {0} {1} [built] - [1] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/b.js 22 bytes {0} {1} [built] - [2] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/c.js 22 bytes {0} {1} [built] - [7] multi ./modules/a ./modules/b ./modules/c 52 bytes {1} [built] \ No newline at end of file + [0] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/a.js 22 bytes {0} {1} [built] + [1] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/b.js 22 bytes {0} {1} [built] + [2] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/c.js 22 bytes {0} {1} [built] + [3] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/entry-1.js 145 bytes {0} [built] + [4] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/d.js 22 bytes {0} [built] + [5] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/e.js 22 bytes {0} [built] + [6] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/f.js 22 bytes {0} [built] + [7] multi ./modules/a ./modules/b ./modules/c 52 bytes {1} [built] \ No newline at end of file diff --git a/test/statsCases/define-plugin/expected.txt b/test/statsCases/define-plugin/expected.txt index 2305b3e70..bc25d5d7a 100644 --- a/test/statsCases/define-plugin/expected.txt +++ b/test/statsCases/define-plugin/expected.txt @@ -4,12 +4,10 @@ Child Time: Xms Asset Size Chunks Chunk Names main.js 2.52 kB 0 [emitted] main - chunk {0} main.js (main) 24 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/define-plugin/index.js 24 bytes {0} [built] + [0] (webpack)/test/statsCases/define-plugin/index.js 24 bytes {0} [built] Child Hash: eb3ff8e5a88b9234d04f Time: Xms Asset Size Chunks Chunk Names main.js 2.52 kB 0 [emitted] main - chunk {0} main.js (main) 24 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/define-plugin/index.js 24 bytes {0} [built] \ No newline at end of file + [0] (webpack)/test/statsCases/define-plugin/index.js 24 bytes {0} [built] \ No newline at end of file diff --git a/test/statsCases/exclude-with-loader/expected.txt b/test/statsCases/exclude-with-loader/expected.txt index a0562e5b1..ed85ee6da 100644 --- a/test/statsCases/exclude-with-loader/expected.txt +++ b/test/statsCases/exclude-with-loader/expected.txt @@ -2,7 +2,6 @@ Hash: 7ab067a6a9fc61623ae0 Time: Xms Asset Size Chunks Chunk Names bundle.js 2.74 kB 0 [emitted] main -chunk {0} bundle.js (main) 132 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/exclude-with-loader/a.txt 43 bytes {0} [built] - [2] (webpack)/test/statsCases/exclude-with-loader/index.js 46 bytes {0} [built] - + 1 hidden modules \ No newline at end of file + [0] (webpack)/test/statsCases/exclude-with-loader/a.txt 43 bytes {0} [built] + [2] (webpack)/test/statsCases/exclude-with-loader/index.js 46 bytes {0} [built] + + 1 hidden module \ No newline at end of file diff --git a/test/statsCases/external/expected.txt b/test/statsCases/external/expected.txt index 671cbcc3e..155880576 100644 --- a/test/statsCases/external/expected.txt +++ b/test/statsCases/external/expected.txt @@ -2,6 +2,5 @@ Hash: 86950abf8dcf924d9cc1 Time: Xms Asset Size Chunks Chunk Names main.js 2.61 kB 0 [emitted] main -chunk {0} main.js (main) 59 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/external/index.js 17 bytes {0} [built] - [1] external "test" 42 bytes {0} [not cacheable] \ No newline at end of file + [0] (webpack)/test/statsCases/external/index.js 17 bytes {0} [built] + [1] external "test" 42 bytes {0} [not cacheable] \ No newline at end of file diff --git a/test/statsCases/filter-warnings/expected.txt b/test/statsCases/filter-warnings/expected.txt index 0d4b13cb0..6e943c68d 100644 --- a/test/statsCases/filter-warnings/expected.txt +++ b/test/statsCases/filter-warnings/expected.txt @@ -4,7 +4,6 @@ Child Time: Xms Asset Size Chunks Chunk Names bundle.js 2.1 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] WARNING in bundle.js from UglifyJs Dropping unused function someRemoteUnUsedFunction1 [./a.js:3,0] @@ -23,43 +22,36 @@ Child Time: Xms Asset Size Chunks Chunk Names bundle.js 2.1 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] Child Hash: e4d2b189bb205589ee1e Time: Xms Asset Size Chunks Chunk Names bundle.js 2.1 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] Child Hash: e4d2b189bb205589ee1e Time: Xms Asset Size Chunks Chunk Names bundle.js 2.1 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] Child Hash: e4d2b189bb205589ee1e Time: Xms Asset Size Chunks Chunk Names bundle.js 2.1 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] Child Hash: e4d2b189bb205589ee1e Time: Xms Asset Size Chunks Chunk Names bundle.js 2.1 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] Child Hash: e4d2b189bb205589ee1e Time: Xms Asset Size Chunks Chunk Names bundle.js 2.1 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] Child Hash: e4d2b189bb205589ee1e Time: Xms Asset Size Chunks Chunk Names bundle.js 2.1 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] WARNING in bundle.js from UglifyJs Dropping unused function someRemoteUnUsedFunction1 [./a.js:3,0] @@ -78,7 +70,6 @@ Child Time: Xms Asset Size Chunks Chunk Names bundle.js 2.1 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] WARNING in bundle.js from UglifyJs Dropping unused function someRemoteUnUsedFunction1 [./a.js:3,0] @@ -97,7 +88,6 @@ Child Time: Xms Asset Size Chunks Chunk Names bundle.js 2.1 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] WARNING in bundle.js from UglifyJs Dropping unused function someRemoteUnUsedFunction1 [./a.js:3,0] @@ -116,7 +106,6 @@ Child Time: Xms Asset Size Chunks Chunk Names bundle.js 2.1 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] WARNING in bundle.js from UglifyJs Dropping unused function someRemoteUnUsedFunction1 [./a.js:3,0] @@ -135,7 +124,6 @@ Child Time: Xms Asset Size Chunks Chunk Names bundle.js 2.1 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] WARNING in bundle.js from UglifyJs Dropping unused function someRemoteUnUsedFunction1 [./a.js:3,0] @@ -154,7 +142,6 @@ Child Time: Xms Asset Size Chunks Chunk Names bundle.js 2.1 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] WARNING in bundle.js from UglifyJs Dropping unused function someRemoteUnUsedFunction1 [./a.js:3,0] diff --git a/test/statsCases/max-modules-default/expected.txt b/test/statsCases/max-modules-default/expected.txt index 28d7d6790..5a1edc02a 100644 --- a/test/statsCases/max-modules-default/expected.txt +++ b/test/statsCases/max-modules-default/expected.txt @@ -2,20 +2,19 @@ Hash: 8f4b66734cb63e0581be Time: Xms Asset Size Chunks Chunk Names main.js 5.79 kB 0 [emitted] main -chunk {0} main.js (main) 1.18 kB [entry] [rendered] - [0] (webpack)/test/statsCases/max-modules-default/a.js?1 33 bytes {0} [built] - [1] (webpack)/test/statsCases/max-modules-default/a.js?10 33 bytes {0} [built] - [2] (webpack)/test/statsCases/max-modules-default/a.js?2 33 bytes {0} [built] - [3] (webpack)/test/statsCases/max-modules-default/a.js?3 33 bytes {0} [built] - [4] (webpack)/test/statsCases/max-modules-default/a.js?4 33 bytes {0} [built] - [5] (webpack)/test/statsCases/max-modules-default/a.js?5 33 bytes {0} [built] - [6] (webpack)/test/statsCases/max-modules-default/a.js?6 33 bytes {0} [built] - [7] (webpack)/test/statsCases/max-modules-default/a.js?7 33 bytes {0} [built] - [8] (webpack)/test/statsCases/max-modules-default/a.js?8 33 bytes {0} [built] - [9] (webpack)/test/statsCases/max-modules-default/a.js?9 33 bytes {0} [built] - [20] (webpack)/test/statsCases/max-modules-default/c.js?1 33 bytes {0} [built] - [21] (webpack)/test/statsCases/max-modules-default/c.js?10 33 bytes {0} [built] - [22] (webpack)/test/statsCases/max-modules-default/c.js?2 33 bytes {0} [built] - [23] (webpack)/test/statsCases/max-modules-default/c.js?3 33 bytes {0} [built] - [30] (webpack)/test/statsCases/max-modules-default/index.js 181 bytes {0} [built] - + 16 hidden modules \ No newline at end of file + [0] (webpack)/test/statsCases/max-modules-default/a.js?1 33 bytes {0} [built] + [1] (webpack)/test/statsCases/max-modules-default/a.js?10 33 bytes {0} [built] + [2] (webpack)/test/statsCases/max-modules-default/a.js?2 33 bytes {0} [built] + [3] (webpack)/test/statsCases/max-modules-default/a.js?3 33 bytes {0} [built] + [4] (webpack)/test/statsCases/max-modules-default/a.js?4 33 bytes {0} [built] + [5] (webpack)/test/statsCases/max-modules-default/a.js?5 33 bytes {0} [built] + [6] (webpack)/test/statsCases/max-modules-default/a.js?6 33 bytes {0} [built] + [7] (webpack)/test/statsCases/max-modules-default/a.js?7 33 bytes {0} [built] + [8] (webpack)/test/statsCases/max-modules-default/a.js?8 33 bytes {0} [built] + [9] (webpack)/test/statsCases/max-modules-default/a.js?9 33 bytes {0} [built] + [20] (webpack)/test/statsCases/max-modules-default/c.js?1 33 bytes {0} [built] + [21] (webpack)/test/statsCases/max-modules-default/c.js?10 33 bytes {0} [built] + [22] (webpack)/test/statsCases/max-modules-default/c.js?2 33 bytes {0} [built] + [23] (webpack)/test/statsCases/max-modules-default/c.js?3 33 bytes {0} [built] + [30] (webpack)/test/statsCases/max-modules-default/index.js 181 bytes {0} [built] + + 16 hidden modules \ No newline at end of file diff --git a/test/statsCases/max-modules/expected.txt b/test/statsCases/max-modules/expected.txt index c8d3f2d2a..f3e1e8d17 100644 --- a/test/statsCases/max-modules/expected.txt +++ b/test/statsCases/max-modules/expected.txt @@ -2,25 +2,24 @@ Hash: 8f4b66734cb63e0581be Time: Xms Asset Size Chunks Chunk Names main.js 5.79 kB 0 [emitted] main -chunk {0} main.js (main) 1.18 kB [entry] [rendered] - [0] (webpack)/test/statsCases/max-modules/a.js?1 33 bytes {0} [built] - [1] (webpack)/test/statsCases/max-modules/a.js?10 33 bytes {0} [built] - [2] (webpack)/test/statsCases/max-modules/a.js?2 33 bytes {0} [built] - [3] (webpack)/test/statsCases/max-modules/a.js?3 33 bytes {0} [built] - [4] (webpack)/test/statsCases/max-modules/a.js?4 33 bytes {0} [built] - [5] (webpack)/test/statsCases/max-modules/a.js?5 33 bytes {0} [built] - [6] (webpack)/test/statsCases/max-modules/a.js?6 33 bytes {0} [built] - [7] (webpack)/test/statsCases/max-modules/a.js?7 33 bytes {0} [built] - [8] (webpack)/test/statsCases/max-modules/a.js?8 33 bytes {0} [built] - [9] (webpack)/test/statsCases/max-modules/a.js?9 33 bytes {0} [built] - [20] (webpack)/test/statsCases/max-modules/c.js?1 33 bytes {0} [built] - [21] (webpack)/test/statsCases/max-modules/c.js?10 33 bytes {0} [built] - [22] (webpack)/test/statsCases/max-modules/c.js?2 33 bytes {0} [built] - [23] (webpack)/test/statsCases/max-modules/c.js?3 33 bytes {0} [built] - [24] (webpack)/test/statsCases/max-modules/c.js?4 33 bytes {0} [built] - [25] (webpack)/test/statsCases/max-modules/c.js?5 33 bytes {0} [built] - [26] (webpack)/test/statsCases/max-modules/c.js?6 33 bytes {0} [built] - [27] (webpack)/test/statsCases/max-modules/c.js?7 33 bytes {0} [built] - [28] (webpack)/test/statsCases/max-modules/c.js?8 33 bytes {0} [built] - [30] (webpack)/test/statsCases/max-modules/index.js 181 bytes {0} [built] - + 11 hidden modules \ No newline at end of file + [0] (webpack)/test/statsCases/max-modules/a.js?1 33 bytes {0} [built] + [1] (webpack)/test/statsCases/max-modules/a.js?10 33 bytes {0} [built] + [2] (webpack)/test/statsCases/max-modules/a.js?2 33 bytes {0} [built] + [3] (webpack)/test/statsCases/max-modules/a.js?3 33 bytes {0} [built] + [4] (webpack)/test/statsCases/max-modules/a.js?4 33 bytes {0} [built] + [5] (webpack)/test/statsCases/max-modules/a.js?5 33 bytes {0} [built] + [6] (webpack)/test/statsCases/max-modules/a.js?6 33 bytes {0} [built] + [7] (webpack)/test/statsCases/max-modules/a.js?7 33 bytes {0} [built] + [8] (webpack)/test/statsCases/max-modules/a.js?8 33 bytes {0} [built] + [9] (webpack)/test/statsCases/max-modules/a.js?9 33 bytes {0} [built] + [20] (webpack)/test/statsCases/max-modules/c.js?1 33 bytes {0} [built] + [21] (webpack)/test/statsCases/max-modules/c.js?10 33 bytes {0} [built] + [22] (webpack)/test/statsCases/max-modules/c.js?2 33 bytes {0} [built] + [23] (webpack)/test/statsCases/max-modules/c.js?3 33 bytes {0} [built] + [24] (webpack)/test/statsCases/max-modules/c.js?4 33 bytes {0} [built] + [25] (webpack)/test/statsCases/max-modules/c.js?5 33 bytes {0} [built] + [26] (webpack)/test/statsCases/max-modules/c.js?6 33 bytes {0} [built] + [27] (webpack)/test/statsCases/max-modules/c.js?7 33 bytes {0} [built] + [28] (webpack)/test/statsCases/max-modules/c.js?8 33 bytes {0} [built] + [30] (webpack)/test/statsCases/max-modules/index.js 181 bytes {0} [built] + + 11 hidden modules \ No newline at end of file diff --git a/test/statsCases/module-trace-disabled-in-error/expected.txt b/test/statsCases/module-trace-disabled-in-error/expected.txt index 1f9b72f65..4a1cecf00 100644 --- a/test/statsCases/module-trace-disabled-in-error/expected.txt +++ b/test/statsCases/module-trace-disabled-in-error/expected.txt @@ -2,8 +2,7 @@ Hash: 6e950f2e83663cb6e9a6 Time: Xms Asset Size Chunks Chunk Names main.js 2.65 kB 0 [emitted] main -chunk {0} main.js (main) 25 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/module-trace-disabled-in-error/index.js 25 bytes {0} [built] + [0] (webpack)/test/statsCases/module-trace-disabled-in-error/index.js 25 bytes {0} [built] ERROR in (webpack)/test/statsCases/module-trace-disabled-in-error/index.js Module not found: Error: Can't resolve 'does-not-exist' in 'Xdir/module-trace-disabled-in-error' \ No newline at end of file diff --git a/test/statsCases/module-trace-enabled-in-error/expected.txt b/test/statsCases/module-trace-enabled-in-error/expected.txt index e5ad8c65a..f5b134c2e 100644 --- a/test/statsCases/module-trace-enabled-in-error/expected.txt +++ b/test/statsCases/module-trace-enabled-in-error/expected.txt @@ -2,8 +2,7 @@ Hash: 6e950f2e83663cb6e9a6 Time: Xms Asset Size Chunks Chunk Names main.js 2.65 kB 0 [emitted] main -chunk {0} main.js (main) 25 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/module-trace-enabled-in-error/index.js 25 bytes {0} [built] + [0] (webpack)/test/statsCases/module-trace-enabled-in-error/index.js 25 bytes {0} [built] ERROR in (webpack)/test/statsCases/module-trace-enabled-in-error/index.js Module not found: Error: Can't resolve 'does-not-exist' in 'Xdir/module-trace-enabled-in-error' diff --git a/test/statsCases/named-chunks-plugin-async/expected.txt b/test/statsCases/named-chunks-plugin-async/expected.txt index 16ad228b5..809ff0492 100644 --- a/test/statsCases/named-chunks-plugin-async/expected.txt +++ b/test/statsCases/named-chunks-plugin-async/expected.txt @@ -4,9 +4,6 @@ Time: Xms chunk-containing-__a_js.js 266 bytes chunk-containing-__a_js [emitted] chunk-containing-__b_js.js 123 bytes chunk-containing-__b_js [emitted] entry.js 5.99 kB entry [emitted] entry -chunk {chunk-containing-__a_js} chunk-containing-__a_js.js 37 bytes {entry} [rendered] - [2] (webpack)/test/statsCases/named-chunks-plugin-async/modules/a.js 37 bytes {chunk-containing-__a_js} [built] -chunk {chunk-containing-__b_js} chunk-containing-__b_js.js 22 bytes {chunk-containing-__a_js} {entry} [rendered] - [0] (webpack)/test/statsCases/named-chunks-plugin-async/modules/b.js 22 bytes {chunk-containing-__b_js} [built] -chunk {entry} entry.js (entry) 47 bytes [entry] [rendered] - [1] (webpack)/test/statsCases/named-chunks-plugin-async/entry.js 47 bytes {entry} [built] \ No newline at end of file + [0] (webpack)/test/statsCases/named-chunks-plugin-async/modules/b.js 22 bytes {chunk-containing-__b_js} [built] + [1] (webpack)/test/statsCases/named-chunks-plugin-async/entry.js 47 bytes {entry} [built] + [2] (webpack)/test/statsCases/named-chunks-plugin-async/modules/a.js 37 bytes {chunk-containing-__a_js} [built] \ No newline at end of file diff --git a/test/statsCases/named-chunks-plugin/expected.txt b/test/statsCases/named-chunks-plugin/expected.txt index 503a569d9..e19f2054f 100644 --- a/test/statsCases/named-chunks-plugin/expected.txt +++ b/test/statsCases/named-chunks-plugin/expected.txt @@ -4,11 +4,8 @@ Time: Xms entry.js 345 bytes entry [emitted] entry manifest.js 5.78 kB manifest [emitted] manifest vendor.js 397 bytes vendor [emitted] vendor -chunk {entry} entry.js (entry) 94 bytes {vendor} [initial] [rendered] - [./entry.js] (webpack)/test/statsCases/named-chunks-plugin/entry.js 72 bytes {entry} [built] - [./modules/c.js] (webpack)/test/statsCases/named-chunks-plugin/modules/c.js 22 bytes {entry} [built] -chunk {manifest} manifest.js (manifest) 0 bytes [entry] [rendered] -chunk {vendor} vendor.js (vendor) 84 bytes {manifest} [initial] [rendered] - [./modules/a.js] (webpack)/test/statsCases/named-chunks-plugin/modules/a.js 22 bytes {vendor} [built] - [./modules/b.js] (webpack)/test/statsCases/named-chunks-plugin/modules/b.js 22 bytes {vendor} [built] - [0] multi ./modules/a ./modules/b 40 bytes {vendor} [built] \ No newline at end of file + [0] multi ./modules/a ./modules/b 40 bytes {vendor} [built] +[./entry.js] (webpack)/test/statsCases/named-chunks-plugin/entry.js 72 bytes {entry} [built] +[./modules/a.js] (webpack)/test/statsCases/named-chunks-plugin/modules/a.js 22 bytes {vendor} [built] +[./modules/b.js] (webpack)/test/statsCases/named-chunks-plugin/modules/b.js 22 bytes {vendor} [built] +[./modules/c.js] (webpack)/test/statsCases/named-chunks-plugin/modules/c.js 22 bytes {entry} [built] \ No newline at end of file diff --git a/test/statsCases/optimize-chunks/webpack.config.js b/test/statsCases/optimize-chunks/webpack.config.js index aaf6056a2..1af7de230 100644 --- a/test/statsCases/optimize-chunks/webpack.config.js +++ b/test/statsCases/optimize-chunks/webpack.config.js @@ -2,6 +2,9 @@ module.exports = { entry: "./index", stats: { reasons: false, + modules: false, + chunks: true, + chunkModules: true, chunkOrigins: true } }; diff --git a/test/statsCases/performance-disabled/expected.txt b/test/statsCases/performance-disabled/expected.txt index fd629bff5..fa88a9465 100644 --- a/test/statsCases/performance-disabled/expected.txt +++ b/test/statsCases/performance-disabled/expected.txt @@ -5,13 +5,9 @@ Time: Xms 2.js 204 bytes 2 [emitted] main.js 306 kB 3 [emitted] main Entrypoint main = main.js -chunk {0} 0.js 54 bytes {3} [rendered] - [2] (webpack)/test/statsCases/performance-disabled/c.js 54 bytes {0} [built] -chunk {1} 1.js 22 bytes {3} [rendered] - [1] (webpack)/test/statsCases/performance-disabled/b.js 22 bytes {1} [built] -chunk {2} 2.js 44 bytes {0} [rendered] - [3] (webpack)/test/statsCases/performance-disabled/d.js 22 bytes {2} [built] - [4] (webpack)/test/statsCases/performance-disabled/e.js 22 bytes {2} [built] -chunk {3} main.js (main) 300 kB [entry] [rendered] - [0] (webpack)/test/statsCases/performance-disabled/a.js 300 kB {3} [built] - [5] (webpack)/test/statsCases/performance-disabled/index.js 52 bytes {3} [built] \ No newline at end of file + [0] (webpack)/test/statsCases/performance-disabled/a.js 300 kB {3} [built] + [1] (webpack)/test/statsCases/performance-disabled/b.js 22 bytes {1} [built] + [2] (webpack)/test/statsCases/performance-disabled/c.js 54 bytes {0} [built] + [3] (webpack)/test/statsCases/performance-disabled/d.js 22 bytes {2} [built] + [4] (webpack)/test/statsCases/performance-disabled/e.js 22 bytes {2} [built] + [5] (webpack)/test/statsCases/performance-disabled/index.js 52 bytes {3} [built] \ No newline at end of file diff --git a/test/statsCases/performance-error/expected.txt b/test/statsCases/performance-error/expected.txt index 35daf3e17..fbb37c5d0 100644 --- a/test/statsCases/performance-error/expected.txt +++ b/test/statsCases/performance-error/expected.txt @@ -5,16 +5,12 @@ Time: Xms 2.js 204 bytes 2 [emitted] main.js 306 kB 3 [emitted] [big] main Entrypoint main [big] = main.js -chunk {0} 0.js 54 bytes {3} [rendered] - [2] (webpack)/test/statsCases/performance-error/c.js 54 bytes {0} [built] -chunk {1} 1.js 22 bytes {3} [rendered] - [1] (webpack)/test/statsCases/performance-error/b.js 22 bytes {1} [built] -chunk {2} 2.js 44 bytes {0} [rendered] - [3] (webpack)/test/statsCases/performance-error/d.js 22 bytes {2} [built] - [4] (webpack)/test/statsCases/performance-error/e.js 22 bytes {2} [built] -chunk {3} main.js (main) 300 kB [entry] [rendered] - [0] (webpack)/test/statsCases/performance-error/a.js 300 kB {3} [built] - [5] (webpack)/test/statsCases/performance-error/index.js 52 bytes {3} [built] + [0] (webpack)/test/statsCases/performance-error/a.js 300 kB {3} [built] + [1] (webpack)/test/statsCases/performance-error/b.js 22 bytes {1} [built] + [2] (webpack)/test/statsCases/performance-error/c.js 54 bytes {0} [built] + [3] (webpack)/test/statsCases/performance-error/d.js 22 bytes {2} [built] + [4] (webpack)/test/statsCases/performance-error/e.js 22 bytes {2} [built] + [5] (webpack)/test/statsCases/performance-error/index.js 52 bytes {3} [built] ERROR in asset size limit: The following asset(s) exceed the recommended size limit (250 kB). This can impact web performance. diff --git a/test/statsCases/performance-no-async-chunks-shown/expected.txt b/test/statsCases/performance-no-async-chunks-shown/expected.txt index ed7cf6e5c..637c33610 100644 --- a/test/statsCases/performance-no-async-chunks-shown/expected.txt +++ b/test/statsCases/performance-no-async-chunks-shown/expected.txt @@ -4,15 +4,12 @@ Time: Xms main.js 303 kB 1 [emitted] [big] main Entrypoint main [big] = main.js Entrypoint sec = sec.js -chunk {0} sec.js (sec) 114 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/performance-no-async-chunks-shown/b.js 22 bytes {0} {1} [built] - [2] (webpack)/test/statsCases/performance-no-async-chunks-shown/c.js 22 bytes {0} [built] - [3] (webpack)/test/statsCases/performance-no-async-chunks-shown/d.js 22 bytes {0} [built] - [5] (webpack)/test/statsCases/performance-no-async-chunks-shown/index2.js 48 bytes {0} [built] -chunk {1} main.js (main) 300 kB [entry] [rendered] - [0] (webpack)/test/statsCases/performance-no-async-chunks-shown/b.js 22 bytes {0} {1} [built] - [1] (webpack)/test/statsCases/performance-no-async-chunks-shown/a.js 300 kB {1} [built] - [4] (webpack)/test/statsCases/performance-no-async-chunks-shown/index.js 32 bytes {1} [built] + [0] (webpack)/test/statsCases/performance-no-async-chunks-shown/b.js 22 bytes {0} {1} [built] + [1] (webpack)/test/statsCases/performance-no-async-chunks-shown/a.js 300 kB {1} [built] + [2] (webpack)/test/statsCases/performance-no-async-chunks-shown/c.js 22 bytes {0} [built] + [3] (webpack)/test/statsCases/performance-no-async-chunks-shown/d.js 22 bytes {0} [built] + [4] (webpack)/test/statsCases/performance-no-async-chunks-shown/index.js 32 bytes {1} [built] + [5] (webpack)/test/statsCases/performance-no-async-chunks-shown/index2.js 48 bytes {0} [built] WARNING in asset size limit: The following asset(s) exceed the recommended size limit (250 kB). This can impact web performance. diff --git a/test/statsCases/performance-no-hints/expected.txt b/test/statsCases/performance-no-hints/expected.txt index 1fd21e405..040e1cf16 100644 --- a/test/statsCases/performance-no-hints/expected.txt +++ b/test/statsCases/performance-no-hints/expected.txt @@ -5,13 +5,9 @@ Time: Xms 2.js 204 bytes 2 [emitted] main.js 306 kB 3 [emitted] [big] main Entrypoint main [big] = main.js -chunk {0} 0.js 54 bytes {3} [rendered] - [2] (webpack)/test/statsCases/performance-no-hints/c.js 54 bytes {0} [built] -chunk {1} 1.js 22 bytes {3} [rendered] - [1] (webpack)/test/statsCases/performance-no-hints/b.js 22 bytes {1} [built] -chunk {2} 2.js 44 bytes {0} [rendered] - [3] (webpack)/test/statsCases/performance-no-hints/d.js 22 bytes {2} [built] - [4] (webpack)/test/statsCases/performance-no-hints/e.js 22 bytes {2} [built] -chunk {3} main.js (main) 300 kB [entry] [rendered] - [0] (webpack)/test/statsCases/performance-no-hints/a.js 300 kB {3} [built] - [5] (webpack)/test/statsCases/performance-no-hints/index.js 52 bytes {3} [built] \ No newline at end of file + [0] (webpack)/test/statsCases/performance-no-hints/a.js 300 kB {3} [built] + [1] (webpack)/test/statsCases/performance-no-hints/b.js 22 bytes {1} [built] + [2] (webpack)/test/statsCases/performance-no-hints/c.js 54 bytes {0} [built] + [3] (webpack)/test/statsCases/performance-no-hints/d.js 22 bytes {2} [built] + [4] (webpack)/test/statsCases/performance-no-hints/e.js 22 bytes {2} [built] + [5] (webpack)/test/statsCases/performance-no-hints/index.js 52 bytes {3} [built] \ No newline at end of file diff --git a/test/statsCases/performance-oversize-limit-error/expected.txt b/test/statsCases/performance-oversize-limit-error/expected.txt index 92f30846f..200eedb07 100644 --- a/test/statsCases/performance-oversize-limit-error/expected.txt +++ b/test/statsCases/performance-oversize-limit-error/expected.txt @@ -4,12 +4,9 @@ Time: Xms main.js 303 kB 1 [emitted] [big] main Entrypoint main [big] = main.js Entrypoint sec [big] = sec.js -chunk {0} sec.js (sec) 300 kB [entry] [rendered] - [0] (webpack)/test/statsCases/performance-oversize-limit-error/a.js 300 kB {0} {1} [built] - [2] (webpack)/test/statsCases/performance-oversize-limit-error/index2.js 16 bytes {0} [built] -chunk {1} main.js (main) 300 kB [entry] [rendered] - [0] (webpack)/test/statsCases/performance-oversize-limit-error/a.js 300 kB {0} {1} [built] - [1] (webpack)/test/statsCases/performance-oversize-limit-error/index.js 16 bytes {1} [built] + [0] (webpack)/test/statsCases/performance-oversize-limit-error/a.js 300 kB {0} {1} [built] + [1] (webpack)/test/statsCases/performance-oversize-limit-error/index.js 16 bytes {1} [built] + [2] (webpack)/test/statsCases/performance-oversize-limit-error/index2.js 16 bytes {0} [built] ERROR in asset size limit: The following asset(s) exceed the recommended size limit (250 kB). This can impact web performance. diff --git a/test/statsCases/preset-detailed/a.js b/test/statsCases/preset-detailed/a.js new file mode 100644 index 000000000..6cd1d0075 --- /dev/null +++ b/test/statsCases/preset-detailed/a.js @@ -0,0 +1 @@ +module.exports = "a"; diff --git a/test/statsCases/preset-detailed/b.js b/test/statsCases/preset-detailed/b.js new file mode 100644 index 000000000..dfbbeb621 --- /dev/null +++ b/test/statsCases/preset-detailed/b.js @@ -0,0 +1 @@ +module.exports = "b"; diff --git a/test/statsCases/preset-detailed/c.js b/test/statsCases/preset-detailed/c.js new file mode 100644 index 000000000..84bdba76f --- /dev/null +++ b/test/statsCases/preset-detailed/c.js @@ -0,0 +1 @@ +require.ensure(["./d", "./e"], function(require) {}); diff --git a/test/statsCases/preset-detailed/d.js b/test/statsCases/preset-detailed/d.js new file mode 100644 index 000000000..0a281018c --- /dev/null +++ b/test/statsCases/preset-detailed/d.js @@ -0,0 +1 @@ +module.exports = "d"; diff --git a/test/statsCases/preset-detailed/e.js b/test/statsCases/preset-detailed/e.js new file mode 100644 index 000000000..7884d62f7 --- /dev/null +++ b/test/statsCases/preset-detailed/e.js @@ -0,0 +1 @@ +module.exports = "e"; diff --git a/test/statsCases/preset-detailed/expected.txt b/test/statsCases/preset-detailed/expected.txt new file mode 100644 index 000000000..e92c607c7 --- /dev/null +++ b/test/statsCases/preset-detailed/expected.txt @@ -0,0 +1,22 @@ +Hash: c5a6856b43905ae12f17 +Time: Xms + Asset Size Chunks Chunk Names + 0.js 238 bytes 0 [emitted] + 1.js 108 bytes 1 [emitted] + 2.js 204 bytes 2 [emitted] +main.js 6.1 kB 3 [emitted] main +Entrypoint main = main.js +chunk {0} 0.js 54 bytes {3} [rendered] + > [5] (webpack)/test/statsCases/preset-detailed/index.js 3:0-16 +chunk {1} 1.js 22 bytes {3} [rendered] + > [5] (webpack)/test/statsCases/preset-detailed/index.js 2:0-16 +chunk {2} 2.js 44 bytes {0} [rendered] + > [2] (webpack)/test/statsCases/preset-detailed/c.js 1:0-52 +chunk {3} main.js (main) 73 bytes [entry] [rendered] + > main [5] (webpack)/test/statsCases/preset-detailed/index.js + [0] (webpack)/test/statsCases/preset-detailed/a.js 22 bytes {3} [depth 1] [built] + [1] (webpack)/test/statsCases/preset-detailed/b.js 22 bytes {1} [depth 1] [built] + [2] (webpack)/test/statsCases/preset-detailed/c.js 54 bytes {0} [depth 1] [built] + [3] (webpack)/test/statsCases/preset-detailed/d.js 22 bytes {2} [depth 2] [built] + [4] (webpack)/test/statsCases/preset-detailed/e.js 22 bytes {2} [depth 2] [built] + [5] (webpack)/test/statsCases/preset-detailed/index.js 51 bytes {3} [depth 0] [built] \ No newline at end of file diff --git a/test/statsCases/preset-detailed/index.js b/test/statsCases/preset-detailed/index.js new file mode 100644 index 000000000..86b979b0d --- /dev/null +++ b/test/statsCases/preset-detailed/index.js @@ -0,0 +1,3 @@ +require("./a"); +require(["./b"]); +require(["./c"]); \ No newline at end of file diff --git a/test/statsCases/preset-detailed/webpack.config.js b/test/statsCases/preset-detailed/webpack.config.js new file mode 100644 index 000000000..0557c0405 --- /dev/null +++ b/test/statsCases/preset-detailed/webpack.config.js @@ -0,0 +1,4 @@ +module.exports = { + entry: "./index", + stats: "detailed" +}; diff --git a/test/statsCases/preset-minimal-simple/expected.txt b/test/statsCases/preset-minimal-simple/expected.txt index 21bb031a2..2ba6dec13 100644 --- a/test/statsCases/preset-minimal-simple/expected.txt +++ b/test/statsCases/preset-minimal-simple/expected.txt @@ -1 +1 @@ -chunk {0} main.js (main) 0 bytes [entry] [rendered] \ No newline at end of file + 1 module \ No newline at end of file diff --git a/test/statsCases/preset-minimal/expected.txt b/test/statsCases/preset-minimal/expected.txt index b5228183e..fb8d2244f 100644 --- a/test/statsCases/preset-minimal/expected.txt +++ b/test/statsCases/preset-minimal/expected.txt @@ -1,4 +1 @@ -chunk {0} 0.js 54 bytes {3} [rendered] -chunk {1} 1.js 22 bytes {3} [rendered] -chunk {2} 2.js 44 bytes {0} [rendered] -chunk {3} main.js (main) 73 bytes [entry] [rendered] \ No newline at end of file + 6 modules \ No newline at end of file diff --git a/test/statsCases/preset-mixed-array/expected.txt b/test/statsCases/preset-mixed-array/expected.txt index 3665b12d1..e355ec4b6 100644 --- a/test/statsCases/preset-mixed-array/expected.txt +++ b/test/statsCases/preset-mixed-array/expected.txt @@ -1,4 +1,5 @@ Child minimal: - chunk {0} main.js (main) 8 bytes [entry] [rendered] + 1 module Child verbose: - Entrypoint main = main.js \ No newline at end of file + Entrypoint main = main.js + [0] (webpack)/test/statsCases/preset-mixed-array/index.js 8 bytes {0} [built] \ No newline at end of file diff --git a/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/expected.txt b/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/expected.txt index 3ccf98a42..a25857c2c 100644 --- a/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/expected.txt +++ b/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/expected.txt @@ -8,16 +8,12 @@ Time: Xms 1.js.map 250 bytes 1 [emitted] 2.js.map 405 bytes 2 [emitted] main.js.map 1.81 MB 3 [emitted] main -chunk {0} 0.js, 0.js.map 54 bytes {3} [rendered] - [2] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/c.js 54 bytes {0} [built] -chunk {1} 1.js, 1.js.map 22 bytes {3} [rendered] - [1] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/b.js 22 bytes {1} [built] -chunk {2} 2.js, 2.js.map 44 bytes {0} [rendered] - [3] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/d.js 22 bytes {2} [built] - [4] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/e.js 22 bytes {2} [built] -chunk {3} main.js, main.js.map (main) 300 kB [entry] [rendered] - [0] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/a.js 300 kB {3} [built] - [5] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/index.js 52 bytes {3} [built] + [0] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/a.js 300 kB {3} [built] + [1] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/b.js 22 bytes {1} [built] + [2] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/c.js 54 bytes {0} [built] + [3] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/d.js 22 bytes {2} [built] + [4] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/e.js 22 bytes {2} [built] + [5] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/index.js 52 bytes {3} [built] WARNING in asset size limit: The following asset(s) exceed the recommended size limit (250 kB). This can impact web performance. diff --git a/test/statsCases/preset-normal-performance/expected.txt b/test/statsCases/preset-normal-performance/expected.txt index 044000957..73861de5a 100644 --- a/test/statsCases/preset-normal-performance/expected.txt +++ b/test/statsCases/preset-normal-performance/expected.txt @@ -4,16 +4,12 @@ Time: Xms 1.js 108 bytes 1 [emitted] 2.js 204 bytes 2 [emitted] main.js 306 kB 3 [emitted] [big] main -chunk {0} 0.js 54 bytes {3} [rendered] - [2] (webpack)/test/statsCases/preset-normal-performance/c.js 54 bytes {0} [built] -chunk {1} 1.js 22 bytes {3} [rendered] - [1] (webpack)/test/statsCases/preset-normal-performance/b.js 22 bytes {1} [built] -chunk {2} 2.js 44 bytes {0} [rendered] - [3] (webpack)/test/statsCases/preset-normal-performance/d.js 22 bytes {2} [built] - [4] (webpack)/test/statsCases/preset-normal-performance/e.js 22 bytes {2} [built] -chunk {3} main.js (main) 300 kB [entry] [rendered] - [0] (webpack)/test/statsCases/preset-normal-performance/a.js 300 kB {3} [built] - [5] (webpack)/test/statsCases/preset-normal-performance/index.js 52 bytes {3} [built] + [0] (webpack)/test/statsCases/preset-normal-performance/a.js 300 kB {3} [built] + [1] (webpack)/test/statsCases/preset-normal-performance/b.js 22 bytes {1} [built] + [2] (webpack)/test/statsCases/preset-normal-performance/c.js 54 bytes {0} [built] + [3] (webpack)/test/statsCases/preset-normal-performance/d.js 22 bytes {2} [built] + [4] (webpack)/test/statsCases/preset-normal-performance/e.js 22 bytes {2} [built] + [5] (webpack)/test/statsCases/preset-normal-performance/index.js 52 bytes {3} [built] WARNING in asset size limit: The following asset(s) exceed the recommended size limit (250 kB). This can impact web performance. diff --git a/test/statsCases/preset-normal/expected.txt b/test/statsCases/preset-normal/expected.txt index a10567f8b..6cf626423 100644 --- a/test/statsCases/preset-normal/expected.txt +++ b/test/statsCases/preset-normal/expected.txt @@ -1,6 +1,13 @@ Hash: c5a6856b43905ae12f17 Time: Xms -chunk {0} 0.js 54 bytes {3} [rendered] -chunk {1} 1.js 22 bytes {3} [rendered] -chunk {2} 2.js 44 bytes {0} [rendered] -chunk {3} main.js (main) 73 bytes [entry] [rendered] \ No newline at end of file + Asset Size Chunks Chunk Names + 0.js 238 bytes 0 [emitted] + 1.js 108 bytes 1 [emitted] + 2.js 204 bytes 2 [emitted] +main.js 6.1 kB 3 [emitted] main + [0] (webpack)/test/statsCases/preset-normal/a.js 22 bytes {3} [built] + [1] (webpack)/test/statsCases/preset-normal/b.js 22 bytes {1} [built] + [2] (webpack)/test/statsCases/preset-normal/c.js 54 bytes {0} [built] + [3] (webpack)/test/statsCases/preset-normal/d.js 22 bytes {2} [built] + [4] (webpack)/test/statsCases/preset-normal/e.js 22 bytes {2} [built] + [5] (webpack)/test/statsCases/preset-normal/index.js 51 bytes {3} [built] \ No newline at end of file diff --git a/test/statsCases/preset-verbose/expected.txt b/test/statsCases/preset-verbose/expected.txt index 5ad626004..be9a576cc 100644 --- a/test/statsCases/preset-verbose/expected.txt +++ b/test/statsCases/preset-verbose/expected.txt @@ -7,14 +7,17 @@ Time: Xms main.js 6.1 kB 3 [emitted] main Entrypoint main = main.js chunk {0} 0.js 54 bytes {3} [rendered] + > [5] (webpack)/test/statsCases/preset-verbose/index.js 3:0-16 [2] (webpack)/test/statsCases/preset-verbose/c.js 54 bytes {0} [depth 1] [built] amd require ./c [5] (webpack)/test/statsCases/preset-verbose/index.js 3:0-16 [] -> factory:Xms building:Xms = Xms chunk {1} 1.js 22 bytes {3} [rendered] + > [5] (webpack)/test/statsCases/preset-verbose/index.js 2:0-16 [1] (webpack)/test/statsCases/preset-verbose/b.js 22 bytes {1} [depth 1] [built] amd require ./b [5] (webpack)/test/statsCases/preset-verbose/index.js 2:0-16 [] -> factory:Xms building:Xms = Xms chunk {2} 2.js 44 bytes {0} [rendered] + > [2] (webpack)/test/statsCases/preset-verbose/c.js 1:0-52 [3] (webpack)/test/statsCases/preset-verbose/d.js 22 bytes {2} [depth 2] [built] require.ensure item ./d [2] (webpack)/test/statsCases/preset-verbose/c.js 1:0-52 [] -> factory:Xms building:Xms = Xms @@ -22,6 +25,7 @@ chunk {2} 2.js 44 bytes {0} [rendered] require.ensure item ./e [2] (webpack)/test/statsCases/preset-verbose/c.js 1:0-52 [] -> factory:Xms building:Xms = Xms chunk {3} main.js (main) 73 bytes [entry] [rendered] + > main [5] (webpack)/test/statsCases/preset-verbose/index.js [0] (webpack)/test/statsCases/preset-verbose/a.js 22 bytes {3} [depth 1] [built] cjs require ./a [5] (webpack)/test/statsCases/preset-verbose/index.js 1:0-14 [] -> factory:Xms building:Xms = Xms diff --git a/test/statsCases/resolve-plugin-context/expected.txt b/test/statsCases/resolve-plugin-context/expected.txt index a6da5097f..033a761bd 100644 --- a/test/statsCases/resolve-plugin-context/expected.txt +++ b/test/statsCases/resolve-plugin-context/expected.txt @@ -2,7 +2,6 @@ Hash: 94e1d97f3e1cf37e753f Time: Xms Asset Size Chunks Chunk Names bundle.js 2.88 kB 0 [emitted] main -chunk {0} bundle.js (main) 80 bytes [entry] [rendered] [0] (webpack)/test/statsCases/resolve-plugin-context/node_modules/xyz/index.js 0 bytes {0} [built] [1] (webpack)/test/statsCases/resolve-plugin-context/index.js 48 bytes {0} [built] [2] (webpack)/test/statsCases/resolve-plugin-context/node_modules/abc/index.js 16 bytes {0} [built] diff --git a/test/statsCases/reverse-sort-modules/expected.txt b/test/statsCases/reverse-sort-modules/expected.txt index 710321d88..12a361f8e 100644 --- a/test/statsCases/reverse-sort-modules/expected.txt +++ b/test/statsCases/reverse-sort-modules/expected.txt @@ -2,25 +2,24 @@ Hash: 8f4b66734cb63e0581be Time: Xms Asset Size Chunks Chunk Names main.js 5.79 kB 0 [emitted] main -chunk {0} main.js (main) 1.18 kB [entry] [rendered] - [30] (webpack)/test/statsCases/reverse-sort-modules/index.js 181 bytes {0} [built] - [28] (webpack)/test/statsCases/reverse-sort-modules/c.js?8 33 bytes {0} [built] - [27] (webpack)/test/statsCases/reverse-sort-modules/c.js?7 33 bytes {0} [built] - [26] (webpack)/test/statsCases/reverse-sort-modules/c.js?6 33 bytes {0} [built] - [25] (webpack)/test/statsCases/reverse-sort-modules/c.js?5 33 bytes {0} [built] - [24] (webpack)/test/statsCases/reverse-sort-modules/c.js?4 33 bytes {0} [built] - [23] (webpack)/test/statsCases/reverse-sort-modules/c.js?3 33 bytes {0} [built] - [22] (webpack)/test/statsCases/reverse-sort-modules/c.js?2 33 bytes {0} [built] - [21] (webpack)/test/statsCases/reverse-sort-modules/c.js?10 33 bytes {0} [built] - [20] (webpack)/test/statsCases/reverse-sort-modules/c.js?1 33 bytes {0} [built] - [9] (webpack)/test/statsCases/reverse-sort-modules/a.js?9 33 bytes {0} [built] - [8] (webpack)/test/statsCases/reverse-sort-modules/a.js?8 33 bytes {0} [built] - [7] (webpack)/test/statsCases/reverse-sort-modules/a.js?7 33 bytes {0} [built] - [6] (webpack)/test/statsCases/reverse-sort-modules/a.js?6 33 bytes {0} [built] - [5] (webpack)/test/statsCases/reverse-sort-modules/a.js?5 33 bytes {0} [built] - [4] (webpack)/test/statsCases/reverse-sort-modules/a.js?4 33 bytes {0} [built] - [3] (webpack)/test/statsCases/reverse-sort-modules/a.js?3 33 bytes {0} [built] - [2] (webpack)/test/statsCases/reverse-sort-modules/a.js?2 33 bytes {0} [built] - [1] (webpack)/test/statsCases/reverse-sort-modules/a.js?10 33 bytes {0} [built] - [0] (webpack)/test/statsCases/reverse-sort-modules/a.js?1 33 bytes {0} [built] - + 11 hidden modules \ No newline at end of file + [30] (webpack)/test/statsCases/reverse-sort-modules/index.js 181 bytes {0} [built] + [28] (webpack)/test/statsCases/reverse-sort-modules/c.js?8 33 bytes {0} [built] + [27] (webpack)/test/statsCases/reverse-sort-modules/c.js?7 33 bytes {0} [built] + [26] (webpack)/test/statsCases/reverse-sort-modules/c.js?6 33 bytes {0} [built] + [25] (webpack)/test/statsCases/reverse-sort-modules/c.js?5 33 bytes {0} [built] + [24] (webpack)/test/statsCases/reverse-sort-modules/c.js?4 33 bytes {0} [built] + [23] (webpack)/test/statsCases/reverse-sort-modules/c.js?3 33 bytes {0} [built] + [22] (webpack)/test/statsCases/reverse-sort-modules/c.js?2 33 bytes {0} [built] + [21] (webpack)/test/statsCases/reverse-sort-modules/c.js?10 33 bytes {0} [built] + [20] (webpack)/test/statsCases/reverse-sort-modules/c.js?1 33 bytes {0} [built] + [9] (webpack)/test/statsCases/reverse-sort-modules/a.js?9 33 bytes {0} [built] + [8] (webpack)/test/statsCases/reverse-sort-modules/a.js?8 33 bytes {0} [built] + [7] (webpack)/test/statsCases/reverse-sort-modules/a.js?7 33 bytes {0} [built] + [6] (webpack)/test/statsCases/reverse-sort-modules/a.js?6 33 bytes {0} [built] + [5] (webpack)/test/statsCases/reverse-sort-modules/a.js?5 33 bytes {0} [built] + [4] (webpack)/test/statsCases/reverse-sort-modules/a.js?4 33 bytes {0} [built] + [3] (webpack)/test/statsCases/reverse-sort-modules/a.js?3 33 bytes {0} [built] + [2] (webpack)/test/statsCases/reverse-sort-modules/a.js?2 33 bytes {0} [built] + [1] (webpack)/test/statsCases/reverse-sort-modules/a.js?10 33 bytes {0} [built] + [0] (webpack)/test/statsCases/reverse-sort-modules/a.js?1 33 bytes {0} [built] + + 11 hidden modules \ No newline at end of file diff --git a/test/statsCases/separate-css-bundle/expected.txt b/test/statsCases/separate-css-bundle/expected.txt index 41c9683d1..43cafb321 100644 --- a/test/statsCases/separate-css-bundle/expected.txt +++ b/test/statsCases/separate-css-bundle/expected.txt @@ -5,23 +5,25 @@ Child Asset Size Chunks Chunk Names c7ab11336573e45dc51e.js 2.62 kB 0 [emitted] main c815cf440254d4f3bba4e7041db00a28.css 26 bytes 0 [emitted] main - chunk {0} c7ab11336573e45dc51e.js, c815cf440254d4f3bba4e7041db00a28.css (main) 64 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/separate-css-bundle/a/file.css 41 bytes {0} [built] - [1] (webpack)/test/statsCases/separate-css-bundle/a/index.js 23 bytes {0} [built] + [0] (webpack)/test/statsCases/separate-css-bundle/a/file.css 41 bytes {0} [built] + [1] (webpack)/test/statsCases/separate-css-bundle/a/index.js 23 bytes {0} [built] + [2] (webpack)/node_modules/css-loader!(webpack)/test/statsCases/separate-css-bundle/a/file.css 190 bytes [built] + [3] (webpack)/node_modules/css-loader/lib/css-base.js 1.46 kB [built] + [4] (webpack)/node_modules/style-loader/addStyles.js 6.91 kB [built] Child extract-text-webpack-plugin: - chunk {0} extract-text-webpack-plugin-output-filename 1.65 kB [entry] [rendered] - [0] (webpack)/node_modules/css-loader!(webpack)/test/statsCases/separate-css-bundle/a/file.css 190 bytes {0} [built] - [1] (webpack)/node_modules/css-loader/lib/css-base.js 1.46 kB {0} [built] + [0] (webpack)/node_modules/css-loader!(webpack)/test/statsCases/separate-css-bundle/a/file.css 190 bytes {0} [built] + [1] (webpack)/node_modules/css-loader/lib/css-base.js 1.46 kB {0} [built] Child Hash: 1139e89514abc13454ce Time: Xms Asset Size Chunks Chunk Names c7ab11336573e45dc51e.js 2.62 kB 0 [emitted] main a3f385680aef7a9bb2a517699532cc34.css 28 bytes 0 [emitted] main - chunk {0} c7ab11336573e45dc51e.js, a3f385680aef7a9bb2a517699532cc34.css (main) 64 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/separate-css-bundle/b/file.css 41 bytes {0} [built] - [1] (webpack)/test/statsCases/separate-css-bundle/b/index.js 23 bytes {0} [built] + [0] (webpack)/test/statsCases/separate-css-bundle/b/file.css 41 bytes {0} [built] + [1] (webpack)/test/statsCases/separate-css-bundle/b/index.js 23 bytes {0} [built] + [2] (webpack)/node_modules/css-loader!(webpack)/test/statsCases/separate-css-bundle/b/file.css 192 bytes [built] + [3] (webpack)/node_modules/css-loader/lib/css-base.js 1.46 kB [built] + [4] (webpack)/node_modules/style-loader/addStyles.js 6.91 kB [built] Child extract-text-webpack-plugin: - chunk {0} extract-text-webpack-plugin-output-filename 1.65 kB [entry] [rendered] - [0] (webpack)/node_modules/css-loader!(webpack)/test/statsCases/separate-css-bundle/b/file.css 192 bytes {0} [built] - [1] (webpack)/node_modules/css-loader/lib/css-base.js 1.46 kB {0} [built] \ No newline at end of file + [0] (webpack)/node_modules/css-loader!(webpack)/test/statsCases/separate-css-bundle/b/file.css 192 bytes {0} [built] + [1] (webpack)/node_modules/css-loader/lib/css-base.js 1.46 kB {0} [built] \ No newline at end of file diff --git a/test/statsCases/simple-more-info/expected.txt b/test/statsCases/simple-more-info/expected.txt index dc090aaae..ecf254996 100644 --- a/test/statsCases/simple-more-info/expected.txt +++ b/test/statsCases/simple-more-info/expected.txt @@ -2,9 +2,5 @@ Hash: 0bd4f09244f0e8c60354 Time: Xms Asset Size Chunks Chunk Names bundle.js 2.47 kB 0 [emitted] main -chunk {0} bundle.js (main) 0 bytes [entry] [rendered] - > main [0] (webpack)/test/statsCases/simple-more-info/index.js - [0] (webpack)/test/statsCases/simple-more-info/index.js 0 bytes {0} [built] - factory:Xms building:Xms = Xms [0] (webpack)/test/statsCases/simple-more-info/index.js 0 bytes {0} [built] factory:Xms building:Xms = Xms \ No newline at end of file diff --git a/test/statsCases/simple/expected.txt b/test/statsCases/simple/expected.txt index 082e6d4d7..4974e2530 100644 --- a/test/statsCases/simple/expected.txt +++ b/test/statsCases/simple/expected.txt @@ -2,5 +2,4 @@ Hash: 0bd4f09244f0e8c60354 Time: Xms Asset Size Chunks Chunk Names bundle.js 2.47 kB 0 [emitted] main -chunk {0} bundle.js (main) 0 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/simple/index.js 0 bytes {0} [built] \ No newline at end of file + [0] (webpack)/test/statsCases/simple/index.js 0 bytes {0} [built] \ No newline at end of file diff --git a/test/statsCases/tree-shaking/expected.txt b/test/statsCases/tree-shaking/expected.txt index daaca66cc..e91d3a2c1 100644 --- a/test/statsCases/tree-shaking/expected.txt +++ b/test/statsCases/tree-shaking/expected.txt @@ -2,7 +2,6 @@ Hash: 347e6d2384c1a580ac4d Time: Xms Asset Size Chunks Chunk Names bundle.js 7.33 kB 0 [emitted] main -chunk {0} bundle.js (main) 588 bytes [entry] [rendered] [0] (webpack)/test/statsCases/tree-shaking/a.js 13 bytes {0} [built] [exports: a] [only some exports used: a] diff --git a/test/statsCases/warnings-uglifyjs/expected.txt b/test/statsCases/warnings-uglifyjs/expected.txt index 45d780b2f..88e885015 100644 --- a/test/statsCases/warnings-uglifyjs/expected.txt +++ b/test/statsCases/warnings-uglifyjs/expected.txt @@ -2,7 +2,6 @@ Hash: 4beee256fa6b8f69eae8 Time: Xms Asset Size Chunks Chunk Names bundle.js 2.1 kB 0 [emitted] main -chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] [0] (webpack)/buildin/module.js 495 bytes {0} [built] [1] (webpack)/test/statsCases/warnings-uglifyjs/a.js 249 bytes {0} [built] [2] (webpack)/test/statsCases/warnings-uglifyjs/index.js 299 bytes {0} [built] From b08762b729fd09ffd5b386754bfd343968c6f0c7 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Thu, 1 Jun 2017 16:10:27 +0200 Subject: [PATCH 31/40] optimize optimization plugins --- lib/Chunk.js | 9 +++++++++ lib/optimize/EnsureChunkConditionsPlugin.js | 7 +++++-- lib/optimize/MergeDuplicateChunksPlugin.js | 15 +++++---------- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/lib/Chunk.js b/lib/Chunk.js index cd7f2fa84..a7939b050 100644 --- a/lib/Chunk.js +++ b/lib/Chunk.js @@ -195,6 +195,15 @@ class Chunk { return Array.from(this._modules); } + getModulesIdent() { + this._ensureModulesSorted(); + let str = ""; + this._modules.forEach(m => { + str += m.identifier() + "#"; + }); + return str; + } + remove(reason) { // cleanup modules // Array.from is used here to create a clone, because removeChunk modifies this._modules diff --git a/lib/optimize/EnsureChunkConditionsPlugin.js b/lib/optimize/EnsureChunkConditionsPlugin.js index 8c2f401d2..07b9756b8 100644 --- a/lib/optimize/EnsureChunkConditionsPlugin.js +++ b/lib/optimize/EnsureChunkConditionsPlugin.js @@ -8,16 +8,19 @@ class EnsureChunkConditionsPlugin { apply(compiler) { compiler.plugin("compilation", (compilation) => { + const triesMap = new Map(); compilation.plugin(["optimize-chunks-basic", "optimize-extracted-chunks-basic"], (chunks) => { let changed = false; chunks.forEach((chunk) => { chunk.forEachModule((module) => { if(!module.chunkCondition) return; if(!module.chunkCondition(chunk)) { - const usedChunks = module._EnsureChunkConditionsPlugin_usedChunks = (module._EnsureChunkConditionsPlugin_usedChunks || []).concat(chunk); + let usedChunks = triesMap.get(module); + if(!usedChunks) triesMap.set(module, usedChunks = new Set()); + usedChunks.add(chunk); const newChunks = []; chunk.parents.forEach((parent) => { - if(usedChunks.indexOf(parent) < 0) { + if(!usedChunks.has(parent)) { parent.addModule(module); newChunks.push(parent); } diff --git a/lib/optimize/MergeDuplicateChunksPlugin.js b/lib/optimize/MergeDuplicateChunksPlugin.js index aaf0acc7d..a37ab3c2e 100644 --- a/lib/optimize/MergeDuplicateChunksPlugin.js +++ b/lib/optimize/MergeDuplicateChunksPlugin.js @@ -4,23 +4,18 @@ */ "use strict"; -function getChunkIdentifier(chunk) { - return chunk.mapModules((m) => { - return m.identifier(); - }).sort().join(", "); -} - class MergeDuplicateChunksPlugin { apply(compiler) { compiler.plugin("compilation", (compilation) => { compilation.plugin("optimize-chunks-basic", (chunks) => { - const map = {}; + const map = Object.create(null); chunks.slice().forEach((chunk) => { if(chunk.hasRuntime() || chunk.hasEntryModule()) return; - const ident = getChunkIdentifier(chunk); - if(map[ident]) { - if(map[ident].integrate(chunk, "duplicate")) + const ident = chunk.getModulesIdent(); + const otherChunk = map[ident]; + if(otherChunk) { + if(otherChunk.integrate(chunk, "duplicate")) chunks.splice(chunks.indexOf(chunk), 1); return; } From 890a507b08c0f7537ccf33ec823f67fbc5994422 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Thu, 1 Jun 2017 15:42:57 +0200 Subject: [PATCH 32/40] optimize OccurenceOrderPlugin --- lib/optimize/OccurrenceOrderPlugin.js | 104 ++++++------ test/Compiler-caching.test.js | 48 +++--- test/Compiler.test.js | 2 +- test/binCases/entry/multi-file/test.js | 4 +- .../entry/non-hyphenated-args/test.js | 4 +- .../code-generation/use-strict/index.js | 4 +- test/configCases/records/issue-2991/test.js | 8 +- .../records/issue-2991/webpack.config.js | 2 +- test/statsCases/chunks/expected.txt | 42 ++--- .../exclude-with-loader/expected.txt | 6 +- test/statsCases/filter-warnings/expected.txt | 160 +++++++++--------- .../limit-chunk-count-plugin/expected.txt | 68 ++++---- .../max-modules-default/expected.txt | 30 ++-- test/statsCases/max-modules/expected.txt | 40 ++--- test/statsCases/optimize-chunks/expected.txt | 26 +-- .../performance-disabled/expected.txt | 16 +- .../statsCases/performance-error/expected.txt | 16 +- .../expected.txt | 10 +- .../performance-no-hints/expected.txt | 16 +- test/statsCases/preset-detailed/expected.txt | 26 +-- .../expected.txt | 18 +- .../preset-normal-performance/expected.txt | 16 +- test/statsCases/preset-normal/expected.txt | 18 +- test/statsCases/preset-verbose/expected.txt | 40 ++--- .../reverse-sort-modules/expected.txt | 40 ++--- .../separate-css-bundle/expected.txt | 18 +- test/statsCases/tree-shaking/expected.txt | 16 +- .../statsCases/warnings-uglifyjs/expected.txt | 6 +- 28 files changed, 400 insertions(+), 404 deletions(-) diff --git a/lib/optimize/OccurrenceOrderPlugin.js b/lib/optimize/OccurrenceOrderPlugin.js index 43f9b497a..66d650a00 100644 --- a/lib/optimize/OccurrenceOrderPlugin.js +++ b/lib/optimize/OccurrenceOrderPlugin.js @@ -15,77 +15,77 @@ class OccurrenceOrderPlugin { const preferEntry = this.preferEntry; compiler.plugin("compilation", (compilation) => { compilation.plugin("optimize-module-order", (modules) => { - function entryChunks(m) { - let total = 0; + const occursInInitialChunksMap = new Map(); + const occursInAllChunksMap = new Map(); + + const initialChunkChunkMap = new Map(); + const entryCountMap = new Map(); + modules.forEach(m => { + let initial = 0; + let entry = 0; m.forEachChunk(c => { - const sum = (c.isInitial() ? 1 : 0) + (c.entryModule === m ? 1 : 0); - total += sum; + if(c.isInitial()) initial++; + if(c.entryModule === m) entry++; + }); + initialChunkChunkMap.set(m, initial); + entryCountMap.set(m, entry); + }); + + const countOccursInEntry = (sum, r) => { + if(!r.module) return sum; + return sum + initialChunkChunkMap.get(r.module); + }; + const countOccurs = (sum, r) => { + if(!r.module) return sum; + return sum + r.module.getNumberOfChunks(); + }; + + if(preferEntry) { + modules.forEach(m => { + const result = m.reasons.reduce(countOccursInEntry, 0) + initialChunkChunkMap.get(m) + entryCountMap.get(m); + occursInInitialChunksMap.set(m, result); }); - return total; } - function occursInEntry(m) { - if(typeof m.__OccurenceOrderPlugin_occursInEntry === "number") return m.__OccurenceOrderPlugin_occursInEntry; - const result = m.reasons.map((r) => { - if(!r.module) return 0; - return entryChunks(r.module); - }).reduce((a, b) => { - return a + b; - }, 0) + entryChunks(m); - return m.__OccurenceOrderPlugin_occursInEntry = result; - } + modules.forEach(m => { + const result = m.reasons.reduce(countOccurs, 0) + m.getNumberOfChunks() + entryCountMap.get(m); + occursInAllChunksMap.set(m, result); + }); - function occurs(m) { - if(typeof m.__OccurenceOrderPlugin_occurs === "number") return m.__OccurenceOrderPlugin_occurs; - let numberEntry = 0; - m.forEachChunk(c => { - if(c.entryModule === m) - numberEntry++; - }); - const result = m.reasons.map((r) => { - if(!r.module) return 0; - return r.module.getNumberOfChunks(); - }).reduce((a, b) => { - return a + b; - }, 0) + m.getNumberOfChunks() + numberEntry; - return m.__OccurenceOrderPlugin_occurs = result; - } modules.sort((a, b) => { if(preferEntry) { - const aEntryOccurs = occursInEntry(a); - const bEntryOccurs = occursInEntry(b); + const aEntryOccurs = occursInInitialChunksMap.get(a); + const bEntryOccurs = occursInInitialChunksMap.get(b); if(aEntryOccurs > bEntryOccurs) return -1; if(aEntryOccurs < bEntryOccurs) return 1; } - const aOccurs = occurs(a); - const bOccurs = occurs(b); + const aOccurs = occursInAllChunksMap.get(a); + const bOccurs = occursInAllChunksMap.get(b); if(aOccurs > bOccurs) return -1; if(aOccurs < bOccurs) return 1; - if(a.identifier() > b.identifier()) return 1; - if(a.identifier() < b.identifier()) return -1; + if(a.index > b.index) return 1; + if(a.index < b.index) return -1; return 0; }); - // TODO refactor to Map - modules.forEach((m) => { - m.__OccurenceOrderPlugin_occursInEntry = undefined; - m.__OccurenceOrderPlugin_occurs = undefined; - }); }); compilation.plugin("optimize-chunk-order", (chunks) => { - function occursInEntry(c) { - if(typeof c.__OccurenceOrderPlugin_occursInEntry === "number") return c.__OccurenceOrderPlugin_occursInEntry; - const result = c.parents.filter((p) => { - return p.isInitial(); - }).length; - return c.__OccurenceOrderPlugin_occursInEntry = result; - } + const occursInInitialChunksMap = new Map(); + + chunks.forEach(c => { + const result = c.parents.reduce((sum, p) => { + if(p.isInitial()) return sum + 1; + return sum; + }, 0); + return occursInInitialChunksMap.set(c, result); + }); function occurs(c) { return c.blocks.length; } + chunks.sort((a, b) => { - const aEntryOccurs = occursInEntry(a); - const bEntryOccurs = occursInEntry(b); + const aEntryOccurs = occursInInitialChunksMap.get(a); + const bEntryOccurs = occursInInitialChunksMap.get(b); if(aEntryOccurs > bEntryOccurs) return -1; if(aEntryOccurs < bEntryOccurs) return 1; const aOccurs = occurs(a); @@ -94,10 +94,6 @@ class OccurrenceOrderPlugin { if(aOccurs < bOccurs) return 1; return a.compareTo(b); }); - // TODO refactor to Map - chunks.forEach((c) => { - c.__OccurenceOrderPlugin_occursInEntry = undefined; - }); }); }); } diff --git a/test/Compiler-caching.test.js b/test/Compiler-caching.test.js index d532978ed..82a91bccb 100644 --- a/test/Compiler-caching.test.js +++ b/test/Compiler-caching.test.js @@ -223,21 +223,21 @@ describe("Compiler (caching)", function() { const helper = compile("./temp-cache-fixture/c", options, (stats, files) => { // Built the first time - stats.modules[0].name.should.containEql("a.js"); - stats.modules[0].built.should.be.exactly(true, "a.js should have been built"); + stats.modules[0].name.should.containEql("c.js"); + stats.modules[0].built.should.be.exactly(true, "c.js should have been built"); - stats.modules[1].name.should.containEql("c.js"); - stats.modules[1].built.should.be.exactly(true, "c.js should have been built"); + stats.modules[1].name.should.containEql("a.js"); + stats.modules[1].built.should.be.exactly(true, "a.js should have been built"); setTimeout(() => { helper.runAgain((stats, files, iteration) => { // Not built when cached the second run - stats.modules[0].name.should.containEql("a.js"); - //stats.modules[0].built.should.be.exactly(false, "a.js should not have built"); + stats.modules[0].name.should.containEql("c.js"); + //stats.modules[0].built.should.be.exactly(false, "c.js should not have built"); - stats.modules[1].name.should.containEql("c.js"); - //stats.modules[1].built.should.be.exactly(false, "c.js should not have built"); + stats.modules[1].name.should.containEql("a.js"); + //stats.modules[1].built.should.be.exactly(false, "a.js should not have built"); const aContent = fs.readFileSync(tempFixture.aFilepath).toString().replace("This is a", "This is a MODIFIED"); @@ -247,11 +247,11 @@ describe("Compiler (caching)", function() { helper.runAgain((stats, files, iteration) => { // And only a.js built after it was modified - stats.modules[0].name.should.containEql("a.js"); - stats.modules[0].built.should.be.exactly(true, "a.js should have been built"); + stats.modules[0].name.should.containEql("c.js"); + stats.modules[0].built.should.be.exactly(false, "c.js should not have built"); - stats.modules[1].name.should.containEql("c.js"); - stats.modules[1].built.should.be.exactly(false, "c.js should not have built"); + stats.modules[1].name.should.containEql("a.js"); + stats.modules[1].built.should.be.exactly(true, "a.js should have been built"); done(); }); @@ -269,20 +269,20 @@ describe("Compiler (caching)", function() { const helper = compile("./temp-cache-fixture/c", options, (stats, files) => { // Built the first time - stats.modules[0].name.should.containEql("a.js"); - stats.modules[0].built.should.be.exactly(true, "a.js should have been built"); + stats.modules[0].name.should.containEql("c.js"); + stats.modules[0].built.should.be.exactly(true, "c.js should have been built"); - stats.modules[1].name.should.containEql("c.js"); - stats.modules[1].built.should.be.exactly(true, "c.js should have been built"); + stats.modules[1].name.should.containEql("a.js"); + stats.modules[1].built.should.be.exactly(true, "a.js should have been built"); helper.runAgain((stats, files, iteration) => { // Not built when cached the second run - stats.modules[0].name.should.containEql("a.js"); - //stats.modules[0].built.should.be.exactly(false, "a.js should not have built"); + stats.modules[0].name.should.containEql("c.js"); + //stats.modules[0].built.should.be.exactly(false, "c.js should not have built"); - stats.modules[1].name.should.containEql("c.js"); - //stats.modules[1].built.should.be.exactly(false, "c.js should not have built"); + stats.modules[1].name.should.containEql("a.js"); + //stats.modules[1].built.should.be.exactly(false, "a.js should not have built"); const aContent = fs.readFileSync(tempFixture.aFilepath).toString().replace("This is a", "This is a MODIFIED"); @@ -291,11 +291,11 @@ describe("Compiler (caching)", function() { helper.runAgain((stats, files, iteration) => { // And only a.js built after it was modified - stats.modules[0].name.should.containEql("a.js"); - stats.modules[0].built.should.be.exactly(true, "a.js should have been built"); + stats.modules[0].name.should.containEql("c.js"); + //stats.modules[0].built.should.be.exactly(false, "c.js should not have built"); - stats.modules[1].name.should.containEql("c.js"); - //stats.modules[1].built.should.be.exactly(false, "c.js should not have built"); + stats.modules[1].name.should.containEql("a.js"); + stats.modules[1].built.should.be.exactly(true, "a.js should have been built"); done(); }); diff --git a/test/Compiler.test.js b/test/Compiler.test.js index b1872e37d..7a7d9eaea 100644 --- a/test/Compiler.test.js +++ b/test/Compiler.test.js @@ -78,7 +78,7 @@ describe("Compiler", () => { Object.keys(files).should.be.eql(["/main.js"]); const bundle = files["/main.js"]; bundle.should.containEql("function __webpack_require__("); - bundle.should.containEql("__webpack_require__(/*! ./a */ 0);"); + bundle.should.containEql("__webpack_require__(/*! ./a */ 1);"); bundle.should.containEql("./c.js"); bundle.should.containEql("./a.js"); bundle.should.containEql("This is a"); diff --git a/test/binCases/entry/multi-file/test.js b/test/binCases/entry/multi-file/test.js index 2fec036be..be912a01e 100644 --- a/test/binCases/entry/multi-file/test.js +++ b/test/binCases/entry/multi-file/test.js @@ -5,9 +5,9 @@ module.exports = function testAssertions(code, stdout, stderr) { stdout.should.be.ok(); stdout[4].should.containEql("null.js"); - stdout[5].should.match(/a\.js.*\{0\}/); + stdout[5].should.match(/multi.*index\.js.*a\.js/); // should have multi-file entry stdout[6].should.match(/index\.js.*\{0\}/); - stdout[7].should.match(/multi.*index\.js.*a\.js/); // should have multi-file entry + stdout[7].should.match(/a\.js.*\{0\}/); stderr.should.be.empty(); }; diff --git a/test/binCases/entry/non-hyphenated-args/test.js b/test/binCases/entry/non-hyphenated-args/test.js index a94b8a518..2b4c30827 100644 --- a/test/binCases/entry/non-hyphenated-args/test.js +++ b/test/binCases/entry/non-hyphenated-args/test.js @@ -6,8 +6,8 @@ module.exports = function testAssertions(code, stdout, stderr) { stdout.should.be.ok(); stdout[4].should.containEql("null.js"); stdout[5].should.containEql("main.js"); // non-hyphenated arg ./a.js should create chunk "main" - stdout[6].should.match(/a\.js.*\{1\}/); // a.js should be in chunk 1 - stdout[7].should.match(/index\.js.*\{0\}/); // index.js should be in chunk 0 + stdout[6].should.match(/index\.js.*\{0\}/); // index.js should be in chunk 0 + stdout[7].should.match(/a\.js.*\{1\}/); // a.js should be in chunk 1 stderr.should.be.empty(); }; diff --git a/test/configCases/code-generation/use-strict/index.js b/test/configCases/code-generation/use-strict/index.js index 1cd3a884c..5f259784a 100644 --- a/test/configCases/code-generation/use-strict/index.js +++ b/test/configCases/code-generation/use-strict/index.js @@ -16,11 +16,11 @@ it("should include only one use strict per module", function() { } matches.should.be.eql([ + "it(\"should include only one use strict per module\", function() {", + "Object.defineProperty(__webpack_exports__, \"__esModule\", { value: true });", "Object.defineProperty(__webpack_exports__, \"__esModule\", { value: true });", "Object.defineProperty(__webpack_exports__, \"__esModule\", { value: true });", "Object.defineProperty(__webpack_exports__, \"__esModule\", { value: true });", "/* unused harmony default export */ var _unused_webpack_default_export = (\"a\");", - "Object.defineProperty(__webpack_exports__, \"__esModule\", { value: true });", - "it(\"should include only one use strict per module\", function() {" ]); }); diff --git a/test/configCases/records/issue-2991/test.js b/test/configCases/records/issue-2991/test.js index 48ae7d80d..b8c209e31 100644 --- a/test/configCases/records/issue-2991/test.js +++ b/test/configCases/records/issue-2991/test.js @@ -9,10 +9,10 @@ it("should write relative paths to records", function() { content.should.eql(`{ "modules": { "byIdentifier": { - "external \\"fs\\"": 0, - "external \\"path\\"": 1, - "ignored pkgs/somepackage/foo": 2, - "test.js": 3 + "test.js": 0, + "ignored pkgs/somepackage/foo": 1, + "external \\"fs\\"": 2, + "external \\"path\\"": 3 }, "usedIds": { "0": 0, diff --git a/test/configCases/records/issue-2991/webpack.config.js b/test/configCases/records/issue-2991/webpack.config.js index 9da472364..dea32c760 100644 --- a/test/configCases/records/issue-2991/webpack.config.js +++ b/test/configCases/records/issue-2991/webpack.config.js @@ -2,7 +2,7 @@ var path = require("path"); module.exports = { entry: "./test", - recordsPath: path.resolve(__dirname, "../../../js/config/records/issue-2991/records.json"), + recordsOutputPath: path.resolve(__dirname, "../../../js/config/records/issue-2991/records.json"), target: "node", node: { __dirname: false diff --git a/test/statsCases/chunks/expected.txt b/test/statsCases/chunks/expected.txt index e1236ea15..4d539f6d9 100644 --- a/test/statsCases/chunks/expected.txt +++ b/test/statsCases/chunks/expected.txt @@ -1,32 +1,32 @@ -Hash: 6ab76347dbbefb99c3c5 +Hash: 458904e7e19c8ce28066 Time: Xms Asset Size Chunks Chunk Names 0.bundle.js 238 bytes 0 [emitted] -1.bundle.js 108 bytes 1 [emitted] -2.bundle.js 204 bytes 2 [emitted] - bundle.js 6.11 kB 3 [emitted] main +1.bundle.js 102 bytes 1 [emitted] +2.bundle.js 182 bytes 2 [emitted] + bundle.js 6.1 kB 3 [emitted] main chunk {0} 0.bundle.js 54 bytes {3} [rendered] - > [5] (webpack)/test/statsCases/chunks/index.js 3:0-16 - [2] (webpack)/test/statsCases/chunks/c.js 54 bytes {0} [built] - amd require ./c [5] (webpack)/test/statsCases/chunks/index.js 3:0-16 + > [0] (webpack)/test/statsCases/chunks/index.js 3:0-16 + [3] (webpack)/test/statsCases/chunks/c.js 54 bytes {0} [built] + amd require ./c [0] (webpack)/test/statsCases/chunks/index.js 3:0-16 [] -> factory:Xms building:Xms = Xms chunk {1} 1.bundle.js 22 bytes {3} [rendered] - > [5] (webpack)/test/statsCases/chunks/index.js 2:0-16 - [1] (webpack)/test/statsCases/chunks/b.js 22 bytes {1} [built] - amd require ./b [5] (webpack)/test/statsCases/chunks/index.js 2:0-16 + > [0] (webpack)/test/statsCases/chunks/index.js 2:0-16 + [2] (webpack)/test/statsCases/chunks/b.js 22 bytes {1} [built] + amd require ./b [0] (webpack)/test/statsCases/chunks/index.js 2:0-16 [] -> factory:Xms building:Xms = Xms chunk {2} 2.bundle.js 44 bytes {0} [rendered] - > [2] (webpack)/test/statsCases/chunks/c.js 1:0-52 - [3] (webpack)/test/statsCases/chunks/d.js 22 bytes {2} [built] - require.ensure item ./d [2] (webpack)/test/statsCases/chunks/c.js 1:0-52 + > [3] (webpack)/test/statsCases/chunks/c.js 1:0-52 + [4] (webpack)/test/statsCases/chunks/d.js 22 bytes {2} [built] + require.ensure item ./d [3] (webpack)/test/statsCases/chunks/c.js 1:0-52 [] -> factory:Xms building:Xms = Xms - [4] (webpack)/test/statsCases/chunks/e.js 22 bytes {2} [built] - require.ensure item ./e [2] (webpack)/test/statsCases/chunks/c.js 1:0-52 + [5] (webpack)/test/statsCases/chunks/e.js 22 bytes {2} [built] + require.ensure item ./e [3] (webpack)/test/statsCases/chunks/c.js 1:0-52 [] -> factory:Xms building:Xms = Xms chunk {3} bundle.js (main) 73 bytes [entry] [rendered] - > main [5] (webpack)/test/statsCases/chunks/index.js - [0] (webpack)/test/statsCases/chunks/a.js 22 bytes {3} [built] - cjs require ./a [5] (webpack)/test/statsCases/chunks/index.js 1:0-14 - [] -> factory:Xms building:Xms = Xms - [5] (webpack)/test/statsCases/chunks/index.js 51 bytes {3} [built] - factory:Xms building:Xms = Xms \ No newline at end of file + > main [0] (webpack)/test/statsCases/chunks/index.js + [0] (webpack)/test/statsCases/chunks/index.js 51 bytes {3} [built] + factory:Xms building:Xms = Xms + [1] (webpack)/test/statsCases/chunks/a.js 22 bytes {3} [built] + cjs require ./a [0] (webpack)/test/statsCases/chunks/index.js 1:0-14 + [] -> factory:Xms building:Xms = Xms \ No newline at end of file diff --git a/test/statsCases/exclude-with-loader/expected.txt b/test/statsCases/exclude-with-loader/expected.txt index ed85ee6da..b7e8b830f 100644 --- a/test/statsCases/exclude-with-loader/expected.txt +++ b/test/statsCases/exclude-with-loader/expected.txt @@ -1,7 +1,7 @@ -Hash: 7ab067a6a9fc61623ae0 +Hash: 9a949e8727d0583cb1c4 Time: Xms Asset Size Chunks Chunk Names bundle.js 2.74 kB 0 [emitted] main - [0] (webpack)/test/statsCases/exclude-with-loader/a.txt 43 bytes {0} [built] - [2] (webpack)/test/statsCases/exclude-with-loader/index.js 46 bytes {0} [built] + [0] (webpack)/test/statsCases/exclude-with-loader/index.js 46 bytes {0} [built] + [1] (webpack)/test/statsCases/exclude-with-loader/a.txt 43 bytes {0} [built] + 1 hidden module \ No newline at end of file diff --git a/test/statsCases/filter-warnings/expected.txt b/test/statsCases/filter-warnings/expected.txt index 6e943c68d..37608dea4 100644 --- a/test/statsCases/filter-warnings/expected.txt +++ b/test/statsCases/filter-warnings/expected.txt @@ -1,157 +1,157 @@ -Hash: e4d2b189bb205589ee1ee4d2b189bb205589ee1ee4d2b189bb205589ee1ee4d2b189bb205589ee1ee4d2b189bb205589ee1ee4d2b189bb205589ee1ee4d2b189bb205589ee1ee4d2b189bb205589ee1ee4d2b189bb205589ee1ee4d2b189bb205589ee1ee4d2b189bb205589ee1ee4d2b189bb205589ee1ee4d2b189bb205589ee1e +Hash: 3cc7bf529a74b021bee53cc7bf529a74b021bee53cc7bf529a74b021bee53cc7bf529a74b021bee53cc7bf529a74b021bee53cc7bf529a74b021bee53cc7bf529a74b021bee53cc7bf529a74b021bee53cc7bf529a74b021bee53cc7bf529a74b021bee53cc7bf529a74b021bee53cc7bf529a74b021bee53cc7bf529a74b021bee5 Child - Hash: e4d2b189bb205589ee1e + Hash: 3cc7bf529a74b021bee5 Time: Xms Asset Size Chunks Chunk Names bundle.js 2.1 kB 0 [emitted] main WARNING in bundle.js from UglifyJs - Dropping unused function someRemoteUnUsedFunction1 [./a.js:3,0] - Dropping unused function someRemoteUnUsedFunction2 [./a.js:4,0] - Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] - Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] - Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] Dropping side-effect-free statement [./index.js:6,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] Dropping unused function someUnUsedFunction4 [./index.js:11,0] Dropping unused function someUnUsedFunction5 [./index.js:12,0] -Child - Hash: e4d2b189bb205589ee1e - Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.1 kB 0 [emitted] main -Child - Hash: e4d2b189bb205589ee1e - Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.1 kB 0 [emitted] main -Child - Hash: e4d2b189bb205589ee1e - Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.1 kB 0 [emitted] main -Child - Hash: e4d2b189bb205589ee1e - Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.1 kB 0 [emitted] main -Child - Hash: e4d2b189bb205589ee1e - Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.1 kB 0 [emitted] main -Child - Hash: e4d2b189bb205589ee1e - Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.1 kB 0 [emitted] main -Child - Hash: e4d2b189bb205589ee1e - Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.1 kB 0 [emitted] main - - WARNING in bundle.js from UglifyJs Dropping unused function someRemoteUnUsedFunction1 [./a.js:3,0] Dropping unused function someRemoteUnUsedFunction2 [./a.js:4,0] Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] +Child + Hash: 3cc7bf529a74b021bee5 + Time: Xms + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main +Child + Hash: 3cc7bf529a74b021bee5 + Time: Xms + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main +Child + Hash: 3cc7bf529a74b021bee5 + Time: Xms + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main +Child + Hash: 3cc7bf529a74b021bee5 + Time: Xms + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main +Child + Hash: 3cc7bf529a74b021bee5 + Time: Xms + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main +Child + Hash: 3cc7bf529a74b021bee5 + Time: Xms + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main +Child + Hash: 3cc7bf529a74b021bee5 + Time: Xms + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main + + WARNING in bundle.js from UglifyJs Dropping side-effect-free statement [./index.js:6,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] Dropping unused function someUnUsedFunction4 [./index.js:11,0] Dropping unused function someUnUsedFunction5 [./index.js:12,0] -Child - Hash: e4d2b189bb205589ee1e - Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.1 kB 0 [emitted] main - - WARNING in bundle.js from UglifyJs Dropping unused function someRemoteUnUsedFunction1 [./a.js:3,0] Dropping unused function someRemoteUnUsedFunction2 [./a.js:4,0] Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] +Child + Hash: 3cc7bf529a74b021bee5 + Time: Xms + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main + + WARNING in bundle.js from UglifyJs Dropping side-effect-free statement [./index.js:6,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] Dropping unused function someUnUsedFunction4 [./index.js:11,0] Dropping unused function someUnUsedFunction5 [./index.js:12,0] -Child - Hash: e4d2b189bb205589ee1e - Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.1 kB 0 [emitted] main - - WARNING in bundle.js from UglifyJs Dropping unused function someRemoteUnUsedFunction1 [./a.js:3,0] Dropping unused function someRemoteUnUsedFunction2 [./a.js:4,0] Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] +Child + Hash: 3cc7bf529a74b021bee5 + Time: Xms + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main + + WARNING in bundle.js from UglifyJs Dropping side-effect-free statement [./index.js:6,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] Dropping unused function someUnUsedFunction4 [./index.js:11,0] Dropping unused function someUnUsedFunction5 [./index.js:12,0] -Child - Hash: e4d2b189bb205589ee1e - Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.1 kB 0 [emitted] main - - WARNING in bundle.js from UglifyJs Dropping unused function someRemoteUnUsedFunction1 [./a.js:3,0] Dropping unused function someRemoteUnUsedFunction2 [./a.js:4,0] Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] +Child + Hash: 3cc7bf529a74b021bee5 + Time: Xms + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main + + WARNING in bundle.js from UglifyJs Dropping side-effect-free statement [./index.js:6,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] Dropping unused function someUnUsedFunction4 [./index.js:11,0] Dropping unused function someUnUsedFunction5 [./index.js:12,0] -Child - Hash: e4d2b189bb205589ee1e - Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.1 kB 0 [emitted] main - - WARNING in bundle.js from UglifyJs Dropping unused function someRemoteUnUsedFunction1 [./a.js:3,0] Dropping unused function someRemoteUnUsedFunction2 [./a.js:4,0] Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] +Child + Hash: 3cc7bf529a74b021bee5 + Time: Xms + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main + + WARNING in bundle.js from UglifyJs Dropping side-effect-free statement [./index.js:6,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] Dropping unused function someUnUsedFunction4 [./index.js:11,0] Dropping unused function someUnUsedFunction5 [./index.js:12,0] -Child - Hash: e4d2b189bb205589ee1e - Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.1 kB 0 [emitted] main - - WARNING in bundle.js from UglifyJs Dropping unused function someRemoteUnUsedFunction1 [./a.js:3,0] Dropping unused function someRemoteUnUsedFunction2 [./a.js:4,0] Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] +Child + Hash: 3cc7bf529a74b021bee5 + Time: Xms + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main + + WARNING in bundle.js from UglifyJs Dropping side-effect-free statement [./index.js:6,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] Dropping unused function someUnUsedFunction4 [./index.js:11,0] - Dropping unused function someUnUsedFunction5 [./index.js:12,0] \ No newline at end of file + Dropping unused function someUnUsedFunction5 [./index.js:12,0] + Dropping unused function someRemoteUnUsedFunction1 [./a.js:3,0] + Dropping unused function someRemoteUnUsedFunction2 [./a.js:4,0] + Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] + Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] + Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] \ No newline at end of file diff --git a/test/statsCases/limit-chunk-count-plugin/expected.txt b/test/statsCases/limit-chunk-count-plugin/expected.txt index 0f81a20d2..e020942cc 100644 --- a/test/statsCases/limit-chunk-count-plugin/expected.txt +++ b/test/statsCases/limit-chunk-count-plugin/expected.txt @@ -1,61 +1,61 @@ -Hash: 7785ad0c3d45a94a3238a8178dd1adacd47a6b70043f3d1f8be496acf7a6e0df24380874d11a123a +Hash: e0c3e190f6cf11c37f15b34fa5f72acbbc9cbd9a404c277a8869b8a6a62e5c32ec6fc2ff40a3b587 Child - Hash: 7785ad0c3d45a94a3238 + Hash: e0c3e190f6cf11c37f15 Time: Xms Asset Size Chunks Chunk Names bundle.js 3.4 kB 0 [emitted] main chunk {0} bundle.js (main) 191 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/limit-chunk-count-plugin/a.js 22 bytes {0} [built] - [1] (webpack)/test/statsCases/limit-chunk-count-plugin/b.js 22 bytes {0} [built] - [2] (webpack)/test/statsCases/limit-chunk-count-plugin/c.js 30 bytes {0} [built] - [3] (webpack)/test/statsCases/limit-chunk-count-plugin/d.js 22 bytes {0} [built] - [4] (webpack)/test/statsCases/limit-chunk-count-plugin/e.js 22 bytes {0} [built] - [5] (webpack)/test/statsCases/limit-chunk-count-plugin/index.js 73 bytes {0} [built] + [0] (webpack)/test/statsCases/limit-chunk-count-plugin/index.js 73 bytes {0} [built] + [1] (webpack)/test/statsCases/limit-chunk-count-plugin/a.js 22 bytes {0} [built] + [2] (webpack)/test/statsCases/limit-chunk-count-plugin/b.js 22 bytes {0} [built] + [3] (webpack)/test/statsCases/limit-chunk-count-plugin/c.js 30 bytes {0} [built] + [4] (webpack)/test/statsCases/limit-chunk-count-plugin/d.js 22 bytes {0} [built] + [5] (webpack)/test/statsCases/limit-chunk-count-plugin/e.js 22 bytes {0} [built] Child - Hash: a8178dd1adacd47a6b70 + Hash: b34fa5f72acbbc9cbd9a Time: Xms Asset Size Chunks Chunk Names - 0.bundle.js 592 bytes 0 [emitted] + 0.bundle.js 601 bytes 0 [emitted] bundle.js 6.12 kB 1 [emitted] main chunk {0} 0.bundle.js 118 bytes {1} [rendered] - [0] (webpack)/test/statsCases/limit-chunk-count-plugin/a.js 22 bytes {0} [built] - [1] (webpack)/test/statsCases/limit-chunk-count-plugin/b.js 22 bytes {0} [built] - [2] (webpack)/test/statsCases/limit-chunk-count-plugin/c.js 30 bytes {0} [built] - [3] (webpack)/test/statsCases/limit-chunk-count-plugin/d.js 22 bytes {0} [built] - [4] (webpack)/test/statsCases/limit-chunk-count-plugin/e.js 22 bytes {0} [built] + [1] (webpack)/test/statsCases/limit-chunk-count-plugin/a.js 22 bytes {0} [built] + [2] (webpack)/test/statsCases/limit-chunk-count-plugin/b.js 22 bytes {0} [built] + [3] (webpack)/test/statsCases/limit-chunk-count-plugin/c.js 30 bytes {0} [built] + [4] (webpack)/test/statsCases/limit-chunk-count-plugin/d.js 22 bytes {0} [built] + [5] (webpack)/test/statsCases/limit-chunk-count-plugin/e.js 22 bytes {0} [built] chunk {1} bundle.js (main) 73 bytes [entry] [rendered] - [5] (webpack)/test/statsCases/limit-chunk-count-plugin/index.js 73 bytes {1} [built] + [0] (webpack)/test/statsCases/limit-chunk-count-plugin/index.js 73 bytes {1} [built] Child - Hash: 043f3d1f8be496acf7a6 + Hash: 404c277a8869b8a6a62e Time: Xms Asset Size Chunks Chunk Names - 0.bundle.js 445 bytes 0 [emitted] - 1.bundle.js 204 bytes 1 [emitted] + 0.bundle.js 454 bytes 0 [emitted] + 1.bundle.js 182 bytes 1 [emitted] bundle.js 6.11 kB 2 [emitted] main chunk {0} 0.bundle.js 74 bytes {2} [rendered] - [0] (webpack)/test/statsCases/limit-chunk-count-plugin/a.js 22 bytes {0} [built] - [2] (webpack)/test/statsCases/limit-chunk-count-plugin/c.js 30 bytes {0} [built] - [3] (webpack)/test/statsCases/limit-chunk-count-plugin/d.js 22 bytes {0} [built] + [1] (webpack)/test/statsCases/limit-chunk-count-plugin/a.js 22 bytes {0} [built] + [3] (webpack)/test/statsCases/limit-chunk-count-plugin/c.js 30 bytes {0} [built] + [4] (webpack)/test/statsCases/limit-chunk-count-plugin/d.js 22 bytes {0} [built] chunk {1} 1.bundle.js 44 bytes {0} {2} [rendered] - [1] (webpack)/test/statsCases/limit-chunk-count-plugin/b.js 22 bytes {1} [built] - [4] (webpack)/test/statsCases/limit-chunk-count-plugin/e.js 22 bytes {1} [built] + [2] (webpack)/test/statsCases/limit-chunk-count-plugin/b.js 22 bytes {1} [built] + [5] (webpack)/test/statsCases/limit-chunk-count-plugin/e.js 22 bytes {1} [built] chunk {2} bundle.js (main) 73 bytes [entry] [rendered] - [5] (webpack)/test/statsCases/limit-chunk-count-plugin/index.js 73 bytes {2} [built] + [0] (webpack)/test/statsCases/limit-chunk-count-plugin/index.js 73 bytes {2} [built] Child - Hash: e0df24380874d11a123a + Hash: 5c32ec6fc2ff40a3b587 Time: Xms Asset Size Chunks Chunk Names - 0.bundle.js 204 bytes 0 [emitted] - 1.bundle.js 195 bytes 1 [emitted] + 0.bundle.js 182 bytes 0 [emitted] + 1.bundle.js 204 bytes 1 [emitted] 2.bundle.js 283 bytes 2 [emitted] bundle.js 6.1 kB 3 [emitted] main chunk {0} 0.bundle.js 44 bytes {2} {3} [rendered] - [1] (webpack)/test/statsCases/limit-chunk-count-plugin/b.js 22 bytes {0} [built] - [4] (webpack)/test/statsCases/limit-chunk-count-plugin/e.js 22 bytes {0} [built] + [2] (webpack)/test/statsCases/limit-chunk-count-plugin/b.js 22 bytes {0} [built] + [5] (webpack)/test/statsCases/limit-chunk-count-plugin/e.js 22 bytes {0} [built] chunk {1} 1.bundle.js 44 bytes {2} {3} [rendered] - [0] (webpack)/test/statsCases/limit-chunk-count-plugin/a.js 22 bytes {1} [built] - [3] (webpack)/test/statsCases/limit-chunk-count-plugin/d.js 22 bytes {1} [built] + [1] (webpack)/test/statsCases/limit-chunk-count-plugin/a.js 22 bytes {1} [built] + [4] (webpack)/test/statsCases/limit-chunk-count-plugin/d.js 22 bytes {1} [built] chunk {2} 2.bundle.js 30 bytes {3} [rendered] - [2] (webpack)/test/statsCases/limit-chunk-count-plugin/c.js 30 bytes {2} [built] + [3] (webpack)/test/statsCases/limit-chunk-count-plugin/c.js 30 bytes {2} [built] chunk {3} bundle.js (main) 73 bytes [entry] [rendered] - [5] (webpack)/test/statsCases/limit-chunk-count-plugin/index.js 73 bytes {3} [built] \ No newline at end of file + [0] (webpack)/test/statsCases/limit-chunk-count-plugin/index.js 73 bytes {3} [built] \ No newline at end of file diff --git a/test/statsCases/max-modules-default/expected.txt b/test/statsCases/max-modules-default/expected.txt index 5a1edc02a..e4cee1b02 100644 --- a/test/statsCases/max-modules-default/expected.txt +++ b/test/statsCases/max-modules-default/expected.txt @@ -1,20 +1,20 @@ -Hash: 8f4b66734cb63e0581be +Hash: b70eb677e8a8b3694c25 Time: Xms Asset Size Chunks Chunk Names main.js 5.79 kB 0 [emitted] main [0] (webpack)/test/statsCases/max-modules-default/a.js?1 33 bytes {0} [built] - [1] (webpack)/test/statsCases/max-modules-default/a.js?10 33 bytes {0} [built] - [2] (webpack)/test/statsCases/max-modules-default/a.js?2 33 bytes {0} [built] - [3] (webpack)/test/statsCases/max-modules-default/a.js?3 33 bytes {0} [built] - [4] (webpack)/test/statsCases/max-modules-default/a.js?4 33 bytes {0} [built] - [5] (webpack)/test/statsCases/max-modules-default/a.js?5 33 bytes {0} [built] - [6] (webpack)/test/statsCases/max-modules-default/a.js?6 33 bytes {0} [built] - [7] (webpack)/test/statsCases/max-modules-default/a.js?7 33 bytes {0} [built] - [8] (webpack)/test/statsCases/max-modules-default/a.js?8 33 bytes {0} [built] - [9] (webpack)/test/statsCases/max-modules-default/a.js?9 33 bytes {0} [built] - [20] (webpack)/test/statsCases/max-modules-default/c.js?1 33 bytes {0} [built] - [21] (webpack)/test/statsCases/max-modules-default/c.js?10 33 bytes {0} [built] - [22] (webpack)/test/statsCases/max-modules-default/c.js?2 33 bytes {0} [built] - [23] (webpack)/test/statsCases/max-modules-default/c.js?3 33 bytes {0} [built] - [30] (webpack)/test/statsCases/max-modules-default/index.js 181 bytes {0} [built] + [1] (webpack)/test/statsCases/max-modules-default/a.js?2 33 bytes {0} [built] + [2] (webpack)/test/statsCases/max-modules-default/a.js?3 33 bytes {0} [built] + [3] (webpack)/test/statsCases/max-modules-default/a.js?4 33 bytes {0} [built] + [4] (webpack)/test/statsCases/max-modules-default/a.js?5 33 bytes {0} [built] + [5] (webpack)/test/statsCases/max-modules-default/a.js?6 33 bytes {0} [built] + [6] (webpack)/test/statsCases/max-modules-default/a.js?7 33 bytes {0} [built] + [7] (webpack)/test/statsCases/max-modules-default/a.js?8 33 bytes {0} [built] + [8] (webpack)/test/statsCases/max-modules-default/a.js?9 33 bytes {0} [built] + [9] (webpack)/test/statsCases/max-modules-default/a.js?10 33 bytes {0} [built] + [10] (webpack)/test/statsCases/max-modules-default/index.js 181 bytes {0} [built] + [11] (webpack)/test/statsCases/max-modules-default/c.js?1 33 bytes {0} [built] + [13] (webpack)/test/statsCases/max-modules-default/c.js?2 33 bytes {0} [built] + [27] (webpack)/test/statsCases/max-modules-default/c.js?9 33 bytes {0} [built] + [29] (webpack)/test/statsCases/max-modules-default/c.js?10 33 bytes {0} [built] + 16 hidden modules \ No newline at end of file diff --git a/test/statsCases/max-modules/expected.txt b/test/statsCases/max-modules/expected.txt index f3e1e8d17..9303956d2 100644 --- a/test/statsCases/max-modules/expected.txt +++ b/test/statsCases/max-modules/expected.txt @@ -1,25 +1,25 @@ -Hash: 8f4b66734cb63e0581be +Hash: b70eb677e8a8b3694c25 Time: Xms Asset Size Chunks Chunk Names main.js 5.79 kB 0 [emitted] main [0] (webpack)/test/statsCases/max-modules/a.js?1 33 bytes {0} [built] - [1] (webpack)/test/statsCases/max-modules/a.js?10 33 bytes {0} [built] - [2] (webpack)/test/statsCases/max-modules/a.js?2 33 bytes {0} [built] - [3] (webpack)/test/statsCases/max-modules/a.js?3 33 bytes {0} [built] - [4] (webpack)/test/statsCases/max-modules/a.js?4 33 bytes {0} [built] - [5] (webpack)/test/statsCases/max-modules/a.js?5 33 bytes {0} [built] - [6] (webpack)/test/statsCases/max-modules/a.js?6 33 bytes {0} [built] - [7] (webpack)/test/statsCases/max-modules/a.js?7 33 bytes {0} [built] - [8] (webpack)/test/statsCases/max-modules/a.js?8 33 bytes {0} [built] - [9] (webpack)/test/statsCases/max-modules/a.js?9 33 bytes {0} [built] - [20] (webpack)/test/statsCases/max-modules/c.js?1 33 bytes {0} [built] - [21] (webpack)/test/statsCases/max-modules/c.js?10 33 bytes {0} [built] - [22] (webpack)/test/statsCases/max-modules/c.js?2 33 bytes {0} [built] - [23] (webpack)/test/statsCases/max-modules/c.js?3 33 bytes {0} [built] - [24] (webpack)/test/statsCases/max-modules/c.js?4 33 bytes {0} [built] - [25] (webpack)/test/statsCases/max-modules/c.js?5 33 bytes {0} [built] - [26] (webpack)/test/statsCases/max-modules/c.js?6 33 bytes {0} [built] - [27] (webpack)/test/statsCases/max-modules/c.js?7 33 bytes {0} [built] - [28] (webpack)/test/statsCases/max-modules/c.js?8 33 bytes {0} [built] - [30] (webpack)/test/statsCases/max-modules/index.js 181 bytes {0} [built] + [1] (webpack)/test/statsCases/max-modules/a.js?2 33 bytes {0} [built] + [2] (webpack)/test/statsCases/max-modules/a.js?3 33 bytes {0} [built] + [3] (webpack)/test/statsCases/max-modules/a.js?4 33 bytes {0} [built] + [4] (webpack)/test/statsCases/max-modules/a.js?5 33 bytes {0} [built] + [5] (webpack)/test/statsCases/max-modules/a.js?6 33 bytes {0} [built] + [6] (webpack)/test/statsCases/max-modules/a.js?7 33 bytes {0} [built] + [7] (webpack)/test/statsCases/max-modules/a.js?8 33 bytes {0} [built] + [8] (webpack)/test/statsCases/max-modules/a.js?9 33 bytes {0} [built] + [9] (webpack)/test/statsCases/max-modules/a.js?10 33 bytes {0} [built] + [10] (webpack)/test/statsCases/max-modules/index.js 181 bytes {0} [built] + [11] (webpack)/test/statsCases/max-modules/c.js?1 33 bytes {0} [built] + [13] (webpack)/test/statsCases/max-modules/c.js?2 33 bytes {0} [built] + [15] (webpack)/test/statsCases/max-modules/c.js?3 33 bytes {0} [built] + [17] (webpack)/test/statsCases/max-modules/c.js?4 33 bytes {0} [built] + [19] (webpack)/test/statsCases/max-modules/c.js?5 33 bytes {0} [built] + [23] (webpack)/test/statsCases/max-modules/c.js?7 33 bytes {0} [built] + [25] (webpack)/test/statsCases/max-modules/c.js?8 33 bytes {0} [built] + [27] (webpack)/test/statsCases/max-modules/c.js?9 33 bytes {0} [built] + [29] (webpack)/test/statsCases/max-modules/c.js?10 33 bytes {0} [built] + 11 hidden modules \ No newline at end of file diff --git a/test/statsCases/optimize-chunks/expected.txt b/test/statsCases/optimize-chunks/expected.txt index 4f4efd372..9a932b565 100644 --- a/test/statsCases/optimize-chunks/expected.txt +++ b/test/statsCases/optimize-chunks/expected.txt @@ -1,43 +1,43 @@ -Hash: 999ae28af33cdfa6ec93 +Hash: 9a598b7aa486cde5256a Time: Xms Asset Size Chunks Chunk Names 0.js 231 bytes 0 [emitted] cir1 - 1.js 218 bytes 1, 2 [emitted] abd + 1.js 209 bytes 1, 2 [emitted] abd 2.js 133 bytes 2 [emitted] ab 3.js 246 bytes 3 [emitted] cir2 - 4.js 140 bytes 4, 6 [emitted] chunk + 4.js 162 bytes 4, 6 [emitted] chunk 5.js 306 bytes 5, 3 [emitted] cir2 from cir1 6.js 80 bytes 6 [emitted] ac in ab main.js 6.78 kB 7 [emitted] main chunk {0} 0.js (cir1) 81 bytes {3} {5} {7} [rendered] - > duplicate cir1 from cir2 [3] (webpack)/test/statsCases/optimize-chunks/circular2.js 1:0-79 + > duplicate cir1 from cir2 [6] (webpack)/test/statsCases/optimize-chunks/circular2.js 1:0-79 > duplicate cir1 [7] (webpack)/test/statsCases/optimize-chunks/index.js 13:0-54 - [2] (webpack)/test/statsCases/optimize-chunks/circular1.js 81 bytes {0} [built] + [5] (webpack)/test/statsCases/optimize-chunks/circular1.js 81 bytes {0} [built] chunk {1} 1.js (abd) 0 bytes {7} [rendered] > abd [7] (webpack)/test/statsCases/optimize-chunks/index.js 8:0-11:9 [0] (webpack)/test/statsCases/optimize-chunks/modules/a.js 0 bytes {1} {2} [built] [1] (webpack)/test/statsCases/optimize-chunks/modules/b.js 0 bytes {1} {2} [built] - [5] (webpack)/test/statsCases/optimize-chunks/modules/d.js 0 bytes {1} {4} [built] + [4] (webpack)/test/statsCases/optimize-chunks/modules/d.js 0 bytes {1} {4} [built] chunk {2} 2.js (ab) 0 bytes {7} [rendered] > ab [7] (webpack)/test/statsCases/optimize-chunks/index.js 1:0-6:8 [0] (webpack)/test/statsCases/optimize-chunks/modules/a.js 0 bytes {1} {2} [built] [1] (webpack)/test/statsCases/optimize-chunks/modules/b.js 0 bytes {1} {2} [built] chunk {3} 3.js (cir2) 81 bytes {7} [rendered] > cir2 [7] (webpack)/test/statsCases/optimize-chunks/index.js 14:0-54 - [3] (webpack)/test/statsCases/optimize-chunks/circular2.js 81 bytes {3} {5} [built] + [6] (webpack)/test/statsCases/optimize-chunks/circular2.js 81 bytes {3} {5} [built] chunk {4} 4.js (chunk) 0 bytes {1} {6} [rendered] > chunk [7] (webpack)/test/statsCases/optimize-chunks/index.js 3:2-4:13 > chunk [7] (webpack)/test/statsCases/optimize-chunks/index.js 9:1-10:12 - [4] (webpack)/test/statsCases/optimize-chunks/modules/c.js 0 bytes {4} {6} [built] - [5] (webpack)/test/statsCases/optimize-chunks/modules/d.js 0 bytes {1} {4} [built] + [3] (webpack)/test/statsCases/optimize-chunks/modules/c.js 0 bytes {4} {6} [built] + [4] (webpack)/test/statsCases/optimize-chunks/modules/d.js 0 bytes {1} {4} [built] chunk {5} 5.js (cir2 from cir1) 81 bytes {0} [rendered] - > cir2 from cir1 [2] (webpack)/test/statsCases/optimize-chunks/circular1.js 1:0-79 - [3] (webpack)/test/statsCases/optimize-chunks/circular2.js 81 bytes {3} {5} [built] + > cir2 from cir1 [5] (webpack)/test/statsCases/optimize-chunks/circular1.js 1:0-79 + [6] (webpack)/test/statsCases/optimize-chunks/circular2.js 81 bytes {3} {5} [built] [8] (webpack)/test/statsCases/optimize-chunks/modules/e.js 0 bytes {5} [built] chunk {6} 6.js (ac in ab) 0 bytes {2} [rendered] > ac in ab [7] (webpack)/test/statsCases/optimize-chunks/index.js 2:1-5:15 - [4] (webpack)/test/statsCases/optimize-chunks/modules/c.js 0 bytes {4} {6} [built] + [3] (webpack)/test/statsCases/optimize-chunks/modules/c.js 0 bytes {4} {6} [built] chunk {7} main.js (main) 523 bytes [entry] [rendered] > main [7] (webpack)/test/statsCases/optimize-chunks/index.js - [6] (webpack)/test/statsCases/optimize-chunks/modules/f.js 0 bytes {7} [built] + [2] (webpack)/test/statsCases/optimize-chunks/modules/f.js 0 bytes {7} [built] [7] (webpack)/test/statsCases/optimize-chunks/index.js 523 bytes {7} [built] \ No newline at end of file diff --git a/test/statsCases/performance-disabled/expected.txt b/test/statsCases/performance-disabled/expected.txt index fa88a9465..8c700e931 100644 --- a/test/statsCases/performance-disabled/expected.txt +++ b/test/statsCases/performance-disabled/expected.txt @@ -1,13 +1,13 @@ Time: Xms Asset Size Chunks Chunk Names 0.js 238 bytes 0 [emitted] - 1.js 108 bytes 1 [emitted] - 2.js 204 bytes 2 [emitted] + 1.js 102 bytes 1 [emitted] + 2.js 182 bytes 2 [emitted] main.js 306 kB 3 [emitted] main Entrypoint main = main.js - [0] (webpack)/test/statsCases/performance-disabled/a.js 300 kB {3} [built] - [1] (webpack)/test/statsCases/performance-disabled/b.js 22 bytes {1} [built] - [2] (webpack)/test/statsCases/performance-disabled/c.js 54 bytes {0} [built] - [3] (webpack)/test/statsCases/performance-disabled/d.js 22 bytes {2} [built] - [4] (webpack)/test/statsCases/performance-disabled/e.js 22 bytes {2} [built] - [5] (webpack)/test/statsCases/performance-disabled/index.js 52 bytes {3} [built] \ No newline at end of file + [0] (webpack)/test/statsCases/performance-disabled/index.js 52 bytes {3} [built] + [1] (webpack)/test/statsCases/performance-disabled/a.js 300 kB {3} [built] + [2] (webpack)/test/statsCases/performance-disabled/b.js 22 bytes {1} [built] + [3] (webpack)/test/statsCases/performance-disabled/c.js 54 bytes {0} [built] + [4] (webpack)/test/statsCases/performance-disabled/d.js 22 bytes {2} [built] + [5] (webpack)/test/statsCases/performance-disabled/e.js 22 bytes {2} [built] \ No newline at end of file diff --git a/test/statsCases/performance-error/expected.txt b/test/statsCases/performance-error/expected.txt index fbb37c5d0..57c4f2d85 100644 --- a/test/statsCases/performance-error/expected.txt +++ b/test/statsCases/performance-error/expected.txt @@ -1,16 +1,16 @@ Time: Xms Asset Size Chunks Chunk Names 0.js 238 bytes 0 [emitted] - 1.js 108 bytes 1 [emitted] - 2.js 204 bytes 2 [emitted] + 1.js 102 bytes 1 [emitted] + 2.js 182 bytes 2 [emitted] main.js 306 kB 3 [emitted] [big] main Entrypoint main [big] = main.js - [0] (webpack)/test/statsCases/performance-error/a.js 300 kB {3} [built] - [1] (webpack)/test/statsCases/performance-error/b.js 22 bytes {1} [built] - [2] (webpack)/test/statsCases/performance-error/c.js 54 bytes {0} [built] - [3] (webpack)/test/statsCases/performance-error/d.js 22 bytes {2} [built] - [4] (webpack)/test/statsCases/performance-error/e.js 22 bytes {2} [built] - [5] (webpack)/test/statsCases/performance-error/index.js 52 bytes {3} [built] + [0] (webpack)/test/statsCases/performance-error/index.js 52 bytes {3} [built] + [1] (webpack)/test/statsCases/performance-error/a.js 300 kB {3} [built] + [2] (webpack)/test/statsCases/performance-error/b.js 22 bytes {1} [built] + [3] (webpack)/test/statsCases/performance-error/c.js 54 bytes {0} [built] + [4] (webpack)/test/statsCases/performance-error/d.js 22 bytes {2} [built] + [5] (webpack)/test/statsCases/performance-error/e.js 22 bytes {2} [built] ERROR in asset size limit: The following asset(s) exceed the recommended size limit (250 kB). This can impact web performance. diff --git a/test/statsCases/performance-no-async-chunks-shown/expected.txt b/test/statsCases/performance-no-async-chunks-shown/expected.txt index 637c33610..8ed34c516 100644 --- a/test/statsCases/performance-no-async-chunks-shown/expected.txt +++ b/test/statsCases/performance-no-async-chunks-shown/expected.txt @@ -5,11 +5,11 @@ Time: Xms Entrypoint main [big] = main.js Entrypoint sec = sec.js [0] (webpack)/test/statsCases/performance-no-async-chunks-shown/b.js 22 bytes {0} {1} [built] - [1] (webpack)/test/statsCases/performance-no-async-chunks-shown/a.js 300 kB {1} [built] - [2] (webpack)/test/statsCases/performance-no-async-chunks-shown/c.js 22 bytes {0} [built] - [3] (webpack)/test/statsCases/performance-no-async-chunks-shown/d.js 22 bytes {0} [built] - [4] (webpack)/test/statsCases/performance-no-async-chunks-shown/index.js 32 bytes {1} [built] - [5] (webpack)/test/statsCases/performance-no-async-chunks-shown/index2.js 48 bytes {0} [built] + [1] (webpack)/test/statsCases/performance-no-async-chunks-shown/index.js 32 bytes {1} [built] + [2] (webpack)/test/statsCases/performance-no-async-chunks-shown/a.js 300 kB {1} [built] + [3] (webpack)/test/statsCases/performance-no-async-chunks-shown/index2.js 48 bytes {0} [built] + [4] (webpack)/test/statsCases/performance-no-async-chunks-shown/c.js 22 bytes {0} [built] + [5] (webpack)/test/statsCases/performance-no-async-chunks-shown/d.js 22 bytes {0} [built] WARNING in asset size limit: The following asset(s) exceed the recommended size limit (250 kB). This can impact web performance. diff --git a/test/statsCases/performance-no-hints/expected.txt b/test/statsCases/performance-no-hints/expected.txt index 040e1cf16..e044be0ff 100644 --- a/test/statsCases/performance-no-hints/expected.txt +++ b/test/statsCases/performance-no-hints/expected.txt @@ -1,13 +1,13 @@ Time: Xms Asset Size Chunks Chunk Names 0.js 238 bytes 0 [emitted] - 1.js 108 bytes 1 [emitted] - 2.js 204 bytes 2 [emitted] + 1.js 102 bytes 1 [emitted] + 2.js 182 bytes 2 [emitted] main.js 306 kB 3 [emitted] [big] main Entrypoint main [big] = main.js - [0] (webpack)/test/statsCases/performance-no-hints/a.js 300 kB {3} [built] - [1] (webpack)/test/statsCases/performance-no-hints/b.js 22 bytes {1} [built] - [2] (webpack)/test/statsCases/performance-no-hints/c.js 54 bytes {0} [built] - [3] (webpack)/test/statsCases/performance-no-hints/d.js 22 bytes {2} [built] - [4] (webpack)/test/statsCases/performance-no-hints/e.js 22 bytes {2} [built] - [5] (webpack)/test/statsCases/performance-no-hints/index.js 52 bytes {3} [built] \ No newline at end of file + [0] (webpack)/test/statsCases/performance-no-hints/index.js 52 bytes {3} [built] + [1] (webpack)/test/statsCases/performance-no-hints/a.js 300 kB {3} [built] + [2] (webpack)/test/statsCases/performance-no-hints/b.js 22 bytes {1} [built] + [3] (webpack)/test/statsCases/performance-no-hints/c.js 54 bytes {0} [built] + [4] (webpack)/test/statsCases/performance-no-hints/d.js 22 bytes {2} [built] + [5] (webpack)/test/statsCases/performance-no-hints/e.js 22 bytes {2} [built] \ No newline at end of file diff --git a/test/statsCases/preset-detailed/expected.txt b/test/statsCases/preset-detailed/expected.txt index e92c607c7..d4b48f326 100644 --- a/test/statsCases/preset-detailed/expected.txt +++ b/test/statsCases/preset-detailed/expected.txt @@ -1,22 +1,22 @@ -Hash: c5a6856b43905ae12f17 +Hash: fd034b07589b0d56afb3 Time: Xms Asset Size Chunks Chunk Names 0.js 238 bytes 0 [emitted] - 1.js 108 bytes 1 [emitted] - 2.js 204 bytes 2 [emitted] + 1.js 102 bytes 1 [emitted] + 2.js 182 bytes 2 [emitted] main.js 6.1 kB 3 [emitted] main Entrypoint main = main.js chunk {0} 0.js 54 bytes {3} [rendered] - > [5] (webpack)/test/statsCases/preset-detailed/index.js 3:0-16 + > [0] (webpack)/test/statsCases/preset-detailed/index.js 3:0-16 chunk {1} 1.js 22 bytes {3} [rendered] - > [5] (webpack)/test/statsCases/preset-detailed/index.js 2:0-16 + > [0] (webpack)/test/statsCases/preset-detailed/index.js 2:0-16 chunk {2} 2.js 44 bytes {0} [rendered] - > [2] (webpack)/test/statsCases/preset-detailed/c.js 1:0-52 + > [3] (webpack)/test/statsCases/preset-detailed/c.js 1:0-52 chunk {3} main.js (main) 73 bytes [entry] [rendered] - > main [5] (webpack)/test/statsCases/preset-detailed/index.js - [0] (webpack)/test/statsCases/preset-detailed/a.js 22 bytes {3} [depth 1] [built] - [1] (webpack)/test/statsCases/preset-detailed/b.js 22 bytes {1} [depth 1] [built] - [2] (webpack)/test/statsCases/preset-detailed/c.js 54 bytes {0} [depth 1] [built] - [3] (webpack)/test/statsCases/preset-detailed/d.js 22 bytes {2} [depth 2] [built] - [4] (webpack)/test/statsCases/preset-detailed/e.js 22 bytes {2} [depth 2] [built] - [5] (webpack)/test/statsCases/preset-detailed/index.js 51 bytes {3} [depth 0] [built] \ No newline at end of file + > main [0] (webpack)/test/statsCases/preset-detailed/index.js + [0] (webpack)/test/statsCases/preset-detailed/index.js 51 bytes {3} [depth 0] [built] + [1] (webpack)/test/statsCases/preset-detailed/a.js 22 bytes {3} [depth 1] [built] + [2] (webpack)/test/statsCases/preset-detailed/b.js 22 bytes {1} [depth 1] [built] + [3] (webpack)/test/statsCases/preset-detailed/c.js 54 bytes {0} [depth 1] [built] + [4] (webpack)/test/statsCases/preset-detailed/d.js 22 bytes {2} [depth 2] [built] + [5] (webpack)/test/statsCases/preset-detailed/e.js 22 bytes {2} [depth 2] [built] \ No newline at end of file diff --git a/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/expected.txt b/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/expected.txt index a25857c2c..33bec0f02 100644 --- a/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/expected.txt +++ b/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/expected.txt @@ -1,19 +1,19 @@ Time: Xms Asset Size Chunks Chunk Names 0.js 268 bytes 0 [emitted] - 1.js 138 bytes 1 [emitted] - 2.js 234 bytes 2 [emitted] + 1.js 132 bytes 1 [emitted] + 2.js 212 bytes 2 [emitted] main.js 306 kB 3 [emitted] [big] main 0.js.map 291 bytes 0 [emitted] 1.js.map 250 bytes 1 [emitted] - 2.js.map 405 bytes 2 [emitted] + 2.js.map 404 bytes 2 [emitted] main.js.map 1.81 MB 3 [emitted] main - [0] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/a.js 300 kB {3} [built] - [1] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/b.js 22 bytes {1} [built] - [2] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/c.js 54 bytes {0} [built] - [3] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/d.js 22 bytes {2} [built] - [4] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/e.js 22 bytes {2} [built] - [5] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/index.js 52 bytes {3} [built] + [0] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/index.js 52 bytes {3} [built] + [1] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/a.js 300 kB {3} [built] + [2] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/b.js 22 bytes {1} [built] + [3] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/c.js 54 bytes {0} [built] + [4] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/d.js 22 bytes {2} [built] + [5] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/e.js 22 bytes {2} [built] WARNING in asset size limit: The following asset(s) exceed the recommended size limit (250 kB). This can impact web performance. diff --git a/test/statsCases/preset-normal-performance/expected.txt b/test/statsCases/preset-normal-performance/expected.txt index 73861de5a..b7d797ecb 100644 --- a/test/statsCases/preset-normal-performance/expected.txt +++ b/test/statsCases/preset-normal-performance/expected.txt @@ -1,15 +1,15 @@ Time: Xms Asset Size Chunks Chunk Names 0.js 238 bytes 0 [emitted] - 1.js 108 bytes 1 [emitted] - 2.js 204 bytes 2 [emitted] + 1.js 102 bytes 1 [emitted] + 2.js 182 bytes 2 [emitted] main.js 306 kB 3 [emitted] [big] main - [0] (webpack)/test/statsCases/preset-normal-performance/a.js 300 kB {3} [built] - [1] (webpack)/test/statsCases/preset-normal-performance/b.js 22 bytes {1} [built] - [2] (webpack)/test/statsCases/preset-normal-performance/c.js 54 bytes {0} [built] - [3] (webpack)/test/statsCases/preset-normal-performance/d.js 22 bytes {2} [built] - [4] (webpack)/test/statsCases/preset-normal-performance/e.js 22 bytes {2} [built] - [5] (webpack)/test/statsCases/preset-normal-performance/index.js 52 bytes {3} [built] + [0] (webpack)/test/statsCases/preset-normal-performance/index.js 52 bytes {3} [built] + [1] (webpack)/test/statsCases/preset-normal-performance/a.js 300 kB {3} [built] + [2] (webpack)/test/statsCases/preset-normal-performance/b.js 22 bytes {1} [built] + [3] (webpack)/test/statsCases/preset-normal-performance/c.js 54 bytes {0} [built] + [4] (webpack)/test/statsCases/preset-normal-performance/d.js 22 bytes {2} [built] + [5] (webpack)/test/statsCases/preset-normal-performance/e.js 22 bytes {2} [built] WARNING in asset size limit: The following asset(s) exceed the recommended size limit (250 kB). This can impact web performance. diff --git a/test/statsCases/preset-normal/expected.txt b/test/statsCases/preset-normal/expected.txt index 6cf626423..80a51e555 100644 --- a/test/statsCases/preset-normal/expected.txt +++ b/test/statsCases/preset-normal/expected.txt @@ -1,13 +1,13 @@ -Hash: c5a6856b43905ae12f17 +Hash: fd034b07589b0d56afb3 Time: Xms Asset Size Chunks Chunk Names 0.js 238 bytes 0 [emitted] - 1.js 108 bytes 1 [emitted] - 2.js 204 bytes 2 [emitted] + 1.js 102 bytes 1 [emitted] + 2.js 182 bytes 2 [emitted] main.js 6.1 kB 3 [emitted] main - [0] (webpack)/test/statsCases/preset-normal/a.js 22 bytes {3} [built] - [1] (webpack)/test/statsCases/preset-normal/b.js 22 bytes {1} [built] - [2] (webpack)/test/statsCases/preset-normal/c.js 54 bytes {0} [built] - [3] (webpack)/test/statsCases/preset-normal/d.js 22 bytes {2} [built] - [4] (webpack)/test/statsCases/preset-normal/e.js 22 bytes {2} [built] - [5] (webpack)/test/statsCases/preset-normal/index.js 51 bytes {3} [built] \ No newline at end of file + [0] (webpack)/test/statsCases/preset-normal/index.js 51 bytes {3} [built] + [1] (webpack)/test/statsCases/preset-normal/a.js 22 bytes {3} [built] + [2] (webpack)/test/statsCases/preset-normal/b.js 22 bytes {1} [built] + [3] (webpack)/test/statsCases/preset-normal/c.js 54 bytes {0} [built] + [4] (webpack)/test/statsCases/preset-normal/d.js 22 bytes {2} [built] + [5] (webpack)/test/statsCases/preset-normal/e.js 22 bytes {2} [built] \ No newline at end of file diff --git a/test/statsCases/preset-verbose/expected.txt b/test/statsCases/preset-verbose/expected.txt index be9a576cc..686bf3a65 100644 --- a/test/statsCases/preset-verbose/expected.txt +++ b/test/statsCases/preset-verbose/expected.txt @@ -1,33 +1,33 @@ -Hash: c5a6856b43905ae12f17 +Hash: fd034b07589b0d56afb3 Time: Xms Asset Size Chunks Chunk Names 0.js 238 bytes 0 [emitted] - 1.js 108 bytes 1 [emitted] - 2.js 204 bytes 2 [emitted] + 1.js 102 bytes 1 [emitted] + 2.js 182 bytes 2 [emitted] main.js 6.1 kB 3 [emitted] main Entrypoint main = main.js chunk {0} 0.js 54 bytes {3} [rendered] - > [5] (webpack)/test/statsCases/preset-verbose/index.js 3:0-16 - [2] (webpack)/test/statsCases/preset-verbose/c.js 54 bytes {0} [depth 1] [built] - amd require ./c [5] (webpack)/test/statsCases/preset-verbose/index.js 3:0-16 + > [0] (webpack)/test/statsCases/preset-verbose/index.js 3:0-16 + [3] (webpack)/test/statsCases/preset-verbose/c.js 54 bytes {0} [depth 1] [built] + amd require ./c [0] (webpack)/test/statsCases/preset-verbose/index.js 3:0-16 [] -> factory:Xms building:Xms = Xms chunk {1} 1.js 22 bytes {3} [rendered] - > [5] (webpack)/test/statsCases/preset-verbose/index.js 2:0-16 - [1] (webpack)/test/statsCases/preset-verbose/b.js 22 bytes {1} [depth 1] [built] - amd require ./b [5] (webpack)/test/statsCases/preset-verbose/index.js 2:0-16 + > [0] (webpack)/test/statsCases/preset-verbose/index.js 2:0-16 + [2] (webpack)/test/statsCases/preset-verbose/b.js 22 bytes {1} [depth 1] [built] + amd require ./b [0] (webpack)/test/statsCases/preset-verbose/index.js 2:0-16 [] -> factory:Xms building:Xms = Xms chunk {2} 2.js 44 bytes {0} [rendered] - > [2] (webpack)/test/statsCases/preset-verbose/c.js 1:0-52 - [3] (webpack)/test/statsCases/preset-verbose/d.js 22 bytes {2} [depth 2] [built] - require.ensure item ./d [2] (webpack)/test/statsCases/preset-verbose/c.js 1:0-52 + > [3] (webpack)/test/statsCases/preset-verbose/c.js 1:0-52 + [4] (webpack)/test/statsCases/preset-verbose/d.js 22 bytes {2} [depth 2] [built] + require.ensure item ./d [3] (webpack)/test/statsCases/preset-verbose/c.js 1:0-52 [] -> factory:Xms building:Xms = Xms - [4] (webpack)/test/statsCases/preset-verbose/e.js 22 bytes {2} [depth 2] [built] - require.ensure item ./e [2] (webpack)/test/statsCases/preset-verbose/c.js 1:0-52 + [5] (webpack)/test/statsCases/preset-verbose/e.js 22 bytes {2} [depth 2] [built] + require.ensure item ./e [3] (webpack)/test/statsCases/preset-verbose/c.js 1:0-52 [] -> factory:Xms building:Xms = Xms chunk {3} main.js (main) 73 bytes [entry] [rendered] - > main [5] (webpack)/test/statsCases/preset-verbose/index.js - [0] (webpack)/test/statsCases/preset-verbose/a.js 22 bytes {3} [depth 1] [built] - cjs require ./a [5] (webpack)/test/statsCases/preset-verbose/index.js 1:0-14 - [] -> factory:Xms building:Xms = Xms - [5] (webpack)/test/statsCases/preset-verbose/index.js 51 bytes {3} [depth 0] [built] - factory:Xms building:Xms = Xms \ No newline at end of file + > main [0] (webpack)/test/statsCases/preset-verbose/index.js + [0] (webpack)/test/statsCases/preset-verbose/index.js 51 bytes {3} [depth 0] [built] + factory:Xms building:Xms = Xms + [1] (webpack)/test/statsCases/preset-verbose/a.js 22 bytes {3} [depth 1] [built] + cjs require ./a [0] (webpack)/test/statsCases/preset-verbose/index.js 1:0-14 + [] -> factory:Xms building:Xms = Xms \ No newline at end of file diff --git a/test/statsCases/reverse-sort-modules/expected.txt b/test/statsCases/reverse-sort-modules/expected.txt index 12a361f8e..7ce77ddc3 100644 --- a/test/statsCases/reverse-sort-modules/expected.txt +++ b/test/statsCases/reverse-sort-modules/expected.txt @@ -1,25 +1,25 @@ -Hash: 8f4b66734cb63e0581be +Hash: b70eb677e8a8b3694c25 Time: Xms Asset Size Chunks Chunk Names main.js 5.79 kB 0 [emitted] main - [30] (webpack)/test/statsCases/reverse-sort-modules/index.js 181 bytes {0} [built] - [28] (webpack)/test/statsCases/reverse-sort-modules/c.js?8 33 bytes {0} [built] - [27] (webpack)/test/statsCases/reverse-sort-modules/c.js?7 33 bytes {0} [built] - [26] (webpack)/test/statsCases/reverse-sort-modules/c.js?6 33 bytes {0} [built] - [25] (webpack)/test/statsCases/reverse-sort-modules/c.js?5 33 bytes {0} [built] - [24] (webpack)/test/statsCases/reverse-sort-modules/c.js?4 33 bytes {0} [built] - [23] (webpack)/test/statsCases/reverse-sort-modules/c.js?3 33 bytes {0} [built] - [22] (webpack)/test/statsCases/reverse-sort-modules/c.js?2 33 bytes {0} [built] - [21] (webpack)/test/statsCases/reverse-sort-modules/c.js?10 33 bytes {0} [built] - [20] (webpack)/test/statsCases/reverse-sort-modules/c.js?1 33 bytes {0} [built] - [9] (webpack)/test/statsCases/reverse-sort-modules/a.js?9 33 bytes {0} [built] - [8] (webpack)/test/statsCases/reverse-sort-modules/a.js?8 33 bytes {0} [built] - [7] (webpack)/test/statsCases/reverse-sort-modules/a.js?7 33 bytes {0} [built] - [6] (webpack)/test/statsCases/reverse-sort-modules/a.js?6 33 bytes {0} [built] - [5] (webpack)/test/statsCases/reverse-sort-modules/a.js?5 33 bytes {0} [built] - [4] (webpack)/test/statsCases/reverse-sort-modules/a.js?4 33 bytes {0} [built] - [3] (webpack)/test/statsCases/reverse-sort-modules/a.js?3 33 bytes {0} [built] - [2] (webpack)/test/statsCases/reverse-sort-modules/a.js?2 33 bytes {0} [built] - [1] (webpack)/test/statsCases/reverse-sort-modules/a.js?10 33 bytes {0} [built] + [29] (webpack)/test/statsCases/reverse-sort-modules/c.js?10 33 bytes {0} [built] + [27] (webpack)/test/statsCases/reverse-sort-modules/c.js?9 33 bytes {0} [built] + [25] (webpack)/test/statsCases/reverse-sort-modules/c.js?8 33 bytes {0} [built] + [23] (webpack)/test/statsCases/reverse-sort-modules/c.js?7 33 bytes {0} [built] + [19] (webpack)/test/statsCases/reverse-sort-modules/c.js?5 33 bytes {0} [built] + [17] (webpack)/test/statsCases/reverse-sort-modules/c.js?4 33 bytes {0} [built] + [15] (webpack)/test/statsCases/reverse-sort-modules/c.js?3 33 bytes {0} [built] + [13] (webpack)/test/statsCases/reverse-sort-modules/c.js?2 33 bytes {0} [built] + [11] (webpack)/test/statsCases/reverse-sort-modules/c.js?1 33 bytes {0} [built] + [10] (webpack)/test/statsCases/reverse-sort-modules/index.js 181 bytes {0} [built] + [9] (webpack)/test/statsCases/reverse-sort-modules/a.js?10 33 bytes {0} [built] + [8] (webpack)/test/statsCases/reverse-sort-modules/a.js?9 33 bytes {0} [built] + [7] (webpack)/test/statsCases/reverse-sort-modules/a.js?8 33 bytes {0} [built] + [6] (webpack)/test/statsCases/reverse-sort-modules/a.js?7 33 bytes {0} [built] + [5] (webpack)/test/statsCases/reverse-sort-modules/a.js?6 33 bytes {0} [built] + [4] (webpack)/test/statsCases/reverse-sort-modules/a.js?5 33 bytes {0} [built] + [3] (webpack)/test/statsCases/reverse-sort-modules/a.js?4 33 bytes {0} [built] + [2] (webpack)/test/statsCases/reverse-sort-modules/a.js?3 33 bytes {0} [built] + [1] (webpack)/test/statsCases/reverse-sort-modules/a.js?2 33 bytes {0} [built] [0] (webpack)/test/statsCases/reverse-sort-modules/a.js?1 33 bytes {0} [built] + 11 hidden modules \ No newline at end of file diff --git a/test/statsCases/separate-css-bundle/expected.txt b/test/statsCases/separate-css-bundle/expected.txt index 43cafb321..66d50015d 100644 --- a/test/statsCases/separate-css-bundle/expected.txt +++ b/test/statsCases/separate-css-bundle/expected.txt @@ -1,12 +1,12 @@ -Hash: 0be4035986816982617a1139e89514abc13454ce +Hash: 7e5cb63b7ac6537cf830018a511be5ab8bf1e17b Child - Hash: 0be4035986816982617a + Hash: 7e5cb63b7ac6537cf830 Time: Xms Asset Size Chunks Chunk Names - c7ab11336573e45dc51e.js 2.62 kB 0 [emitted] main + 5a21b890f95ec575ba49.js 2.62 kB 0 [emitted] main c815cf440254d4f3bba4e7041db00a28.css 26 bytes 0 [emitted] main - [0] (webpack)/test/statsCases/separate-css-bundle/a/file.css 41 bytes {0} [built] - [1] (webpack)/test/statsCases/separate-css-bundle/a/index.js 23 bytes {0} [built] + [0] (webpack)/test/statsCases/separate-css-bundle/a/index.js 23 bytes {0} [built] + [1] (webpack)/test/statsCases/separate-css-bundle/a/file.css 41 bytes {0} [built] [2] (webpack)/node_modules/css-loader!(webpack)/test/statsCases/separate-css-bundle/a/file.css 190 bytes [built] [3] (webpack)/node_modules/css-loader/lib/css-base.js 1.46 kB [built] [4] (webpack)/node_modules/style-loader/addStyles.js 6.91 kB [built] @@ -14,13 +14,13 @@ Child [0] (webpack)/node_modules/css-loader!(webpack)/test/statsCases/separate-css-bundle/a/file.css 190 bytes {0} [built] [1] (webpack)/node_modules/css-loader/lib/css-base.js 1.46 kB {0} [built] Child - Hash: 1139e89514abc13454ce + Hash: 018a511be5ab8bf1e17b Time: Xms Asset Size Chunks Chunk Names - c7ab11336573e45dc51e.js 2.62 kB 0 [emitted] main + 5a21b890f95ec575ba49.js 2.62 kB 0 [emitted] main a3f385680aef7a9bb2a517699532cc34.css 28 bytes 0 [emitted] main - [0] (webpack)/test/statsCases/separate-css-bundle/b/file.css 41 bytes {0} [built] - [1] (webpack)/test/statsCases/separate-css-bundle/b/index.js 23 bytes {0} [built] + [0] (webpack)/test/statsCases/separate-css-bundle/b/index.js 23 bytes {0} [built] + [1] (webpack)/test/statsCases/separate-css-bundle/b/file.css 41 bytes {0} [built] [2] (webpack)/node_modules/css-loader!(webpack)/test/statsCases/separate-css-bundle/b/file.css 192 bytes [built] [3] (webpack)/node_modules/css-loader/lib/css-base.js 1.46 kB [built] [4] (webpack)/node_modules/style-loader/addStyles.js 6.91 kB [built] diff --git a/test/statsCases/tree-shaking/expected.txt b/test/statsCases/tree-shaking/expected.txt index e91d3a2c1..6459b0ac8 100644 --- a/test/statsCases/tree-shaking/expected.txt +++ b/test/statsCases/tree-shaking/expected.txt @@ -1,4 +1,4 @@ -Hash: 347e6d2384c1a580ac4d +Hash: d655480cef20a0a12dff Time: Xms Asset Size Chunks Chunk Names bundle.js 7.33 kB 0 [emitted] main @@ -10,19 +10,19 @@ bundle.js 7.33 kB 0 [emitted] main [only some exports used: ] [2] (webpack)/test/statsCases/tree-shaking/unknown.js 0 bytes {0} [built] [only some exports used: c] - [3] (webpack)/test/statsCases/tree-shaking/edge.js 45 bytes {0} [built] - [only some exports used: y] - [4] (webpack)/test/statsCases/tree-shaking/index.js 276 bytes {0} [built] - [5] (webpack)/test/statsCases/tree-shaking/reexport-known.js 49 bytes {0} [built] + [3] (webpack)/test/statsCases/tree-shaking/index.js 276 bytes {0} [built] + [4] (webpack)/test/statsCases/tree-shaking/reexport-known.js 49 bytes {0} [built] [exports: a, b] [only some exports used: a] + [5] (webpack)/test/statsCases/tree-shaking/reexport-unknown.js 83 bytes {0} [built] + [exports: a, b, c, d] + [only some exports used: a, c] [6] (webpack)/test/statsCases/tree-shaking/reexport-star-known.js 41 bytes {0} [built] [exports: a, b] [only some exports used: a] [7] (webpack)/test/statsCases/tree-shaking/reexport-star-unknown.js 68 bytes {0} [built] [only some exports used: a, c] - [8] (webpack)/test/statsCases/tree-shaking/reexport-unknown.js 83 bytes {0} [built] - [exports: a, b, c, d] - [only some exports used: a, c] + [8] (webpack)/test/statsCases/tree-shaking/edge.js 45 bytes {0} [built] + [only some exports used: y] [9] (webpack)/test/statsCases/tree-shaking/unknown2.js 0 bytes {0} [built] [only some exports used: y] \ No newline at end of file diff --git a/test/statsCases/warnings-uglifyjs/expected.txt b/test/statsCases/warnings-uglifyjs/expected.txt index 88e885015..1e79500ce 100644 --- a/test/statsCases/warnings-uglifyjs/expected.txt +++ b/test/statsCases/warnings-uglifyjs/expected.txt @@ -1,10 +1,10 @@ -Hash: 4beee256fa6b8f69eae8 +Hash: 2c9851f0ea4c9778e64a Time: Xms Asset Size Chunks Chunk Names bundle.js 2.1 kB 0 [emitted] main - [0] (webpack)/buildin/module.js 495 bytes {0} [built] + [0] (webpack)/test/statsCases/warnings-uglifyjs/index.js 299 bytes {0} [built] [1] (webpack)/test/statsCases/warnings-uglifyjs/a.js 249 bytes {0} [built] - [2] (webpack)/test/statsCases/warnings-uglifyjs/index.js 299 bytes {0} [built] + [2] (webpack)/buildin/module.js 495 bytes {0} [built] WARNING in bundle.js from UglifyJs Dropping unused function someUnRemoteUsedFunction1 [./a.js:3,0] From e0c524e43116621f5a2938e54ee1d9644b1b467a Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sat, 3 Jun 2017 14:27:04 +0200 Subject: [PATCH 33/40] update webpack-sources --- package.json | 2 +- yarn.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 978fabdf3..200be4728 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "tapable": "~0.2.5", "uglify-js": "^2.8.27", "watchpack": "^1.3.1", - "webpack-sources": "^0.2.3", + "webpack-sources": "^1.0.1", "yargs": "^6.0.0" }, "license": "MIT", diff --git a/yarn.lock b/yarn.lock index ca1f24eb9..ae49d2875 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3728,9 +3728,9 @@ source-list-map@^0.1.4, source-list-map@~0.1.7: version "0.1.8" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.8.tgz#c550b2ab5427f6b3f21f5afead88c4f5587b2106" -source-list-map@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-1.1.2.tgz#9889019d1024cce55cdc069498337ef6186a11a1" +source-list-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" source-map@0.4.x, source-map@^0.4.4: version "0.4.4" @@ -4197,11 +4197,11 @@ webpack-sources@^0.1.0: source-list-map "~0.1.7" source-map "~0.5.3" -webpack-sources@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-0.2.3.tgz#17c62bfaf13c707f9d02c479e0dcdde8380697fb" +webpack-sources@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.0.1.tgz#c7356436a4d13123be2e2426a05d1dad9cbe65cf" dependencies: - source-list-map "^1.1.1" + source-list-map "^2.0.0" source-map "~0.5.3" whatwg-fetch@>=0.10.0: From 4ec0833b50fa0284f5cef231eba0e548c07a76c1 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 5 Jun 2017 10:59:48 +0200 Subject: [PATCH 34/40] fixup test from merge --- .../async-commons-chunk/existing-name/index.js | 10 +++++----- .../existing-name/webpack.config.js | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/test/configCases/async-commons-chunk/existing-name/index.js b/test/configCases/async-commons-chunk/existing-name/index.js index 72e5842dd..455d37ab0 100644 --- a/test/configCases/async-commons-chunk/existing-name/index.js +++ b/test/configCases/async-commons-chunk/existing-name/index.js @@ -1,19 +1,19 @@ require("should"); const sinon = require("sinon"); -const chunkLoadingSpy = sinon.spy(__webpack_require__, 'e'); +const chunkLoadingSpy = sinon.spy(__webpack_require__, "e"); it("should not have duplicate chunks in blocks", function(done) { // This split point should contain: a require.ensure([], function(require) { require("./a").should.be.eql("a"); - }, 'a'); + }, "a"); // This split point should contain: a and b - we use CommonsChunksPlugin to // have it only contain b and make chunk a be an async dependency. require.ensure([], function(require) { require("./a").should.be.eql("a"); require("./b").should.be.eql("b"); - }, 'a+b'); + }, "a+b"); // This split point should contain: a, b and c - we use CommonsChunksPlugin to // have it only contain c and make chunks a and a+b be async dependencies. @@ -21,13 +21,13 @@ it("should not have duplicate chunks in blocks", function(done) { require("./a").should.be.eql("a"); require("./b").should.be.eql("b"); require("./c").should.be.eql("c"); - }, 'a+b+c'); + }, "a+b+c"); // Each of the require.ensures above should end up resolving chunks: // - a // - a, a+b // - a, a+b, a+b+c chunkLoadingSpy.callCount.should.be.eql(6); - chunkLoadingSpy.args.should.be.eql([[0], [0], [1], [0], [1], [2]]); + chunkLoadingSpy.args.should.be.eql([["a"], ["a+b"], ["a"], ["a+b+c"], ["a+b"], ["a"]]); done(); }); diff --git a/test/configCases/async-commons-chunk/existing-name/webpack.config.js b/test/configCases/async-commons-chunk/existing-name/webpack.config.js index 2c8ad555f..14c7f7b35 100644 --- a/test/configCases/async-commons-chunk/existing-name/webpack.config.js +++ b/test/configCases/async-commons-chunk/existing-name/webpack.config.js @@ -10,5 +10,6 @@ module.exports = { chunks: ["a", "a+b"], async: "a", }), + new webpack.NamedChunksPlugin() ] }; From 4372819de1b95cbc4de24b590a29785cfc7a98ea Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 5 Jun 2017 14:01:19 +0200 Subject: [PATCH 35/40] libIdent should be rootModule --- lib/optimize/ConcatenatedModule.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/optimize/ConcatenatedModule.js b/lib/optimize/ConcatenatedModule.js index 5a09da769..e11aaefdb 100644 --- a/lib/optimize/ConcatenatedModule.js +++ b/lib/optimize/ConcatenatedModule.js @@ -110,7 +110,7 @@ class ConcatenatedModule extends Module { } libIdent(options) { - return this.modules.map(m => m.libIdent(options)).join(" "); + return this.rootModule.libIdent(options); } nameForCondition() { From 0fbff4462398a791d075f546588af1f0a1da05c5 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 29 May 2017 00:15:18 +0200 Subject: [PATCH 36/40] update loader dependencies --- package.json | 14 +++--- yarn.lock | 127 ++++++++++++++++++++++----------------------------- 2 files changed, 61 insertions(+), 80 deletions(-) diff --git a/package.json b/package.json index d109a1ccc..0ffa592bd 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "json-loader": "^0.5.4", "json5": "^0.5.1", "loader-runner": "^2.3.0", - "loader-utils": "^0.2.16", + "loader-utils": "^1.1.0", "memory-fs": "~0.4.1", "mkdirp": "~0.5.0", "node-libs-browser": "^2.0.0", @@ -37,20 +37,20 @@ "coffee-loader": "~0.7.1", "coffee-script": "^1.10.0", "coveralls": "^2.11.2", - "css-loader": "~0.25.0", + "css-loader": "^0.28.3", "es6-promise-polyfill": "^1.1.1", "eslint": "3.12.2", "eslint-plugin-node": "^3.0.5", "express": "~4.13.1", "extract-text-webpack-plugin": "^2.0.0-beta", - "file-loader": "~0.9.0", + "file-loader": "^0.11.1", "i18n-webpack-plugin": "^0.3.0", "istanbul": "^0.4.5", "jade": "^1.11.0", "jade-loader": "~0.8.0", "js-beautify": "^1.5.10", "less": "^2.5.1", - "less-loader": "^2.0.0", + "less-loader": "^4.0.3", "lodash": "^4.17.4", "mocha": "^3.2.0", "mocha-lcov-reporter": "^1.0.0", @@ -62,12 +62,12 @@ "should": "^11.1.1", "simple-git": "^1.65.0", "sinon": "^2.3.2", - "style-loader": "~0.13.0", + "style-loader": "^0.18.1", "url-loader": "~0.5.0", - "val-loader": "~0.5.0", + "val-loader": "^1.0.2", "vm-browserify": "~0.0.0", "webpack-dev-middleware": "^1.9.0", - "worker-loader": "~0.7.0" + "worker-loader": "^0.8.0" }, "engines": { "node": ">=4.3.0 <5.0.0 || >=5.10" diff --git a/yarn.lock b/yarn.lock index 99a24738a..b96d948e4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -586,6 +586,10 @@ clone@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149" +clone@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.1.tgz#d217d1e961118e3ac9a4b8bba3285553bf647cdb" + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -828,35 +832,28 @@ css-color-names@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" -css-loader@~0.25.0: - version "0.25.0" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.25.0.tgz#c3febc8ce28f4c83576b6b13707f47f90c390223" +css-loader@^0.28.3: + version "0.28.3" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.3.tgz#9fd5e0b8c405b6df927ba1103887015d360640ce" dependencies: babel-code-frame "^6.11.0" - css-selector-tokenizer "^0.6.0" + css-selector-tokenizer "^0.7.0" cssnano ">=2.6.1 <4" - loader-utils "~0.2.2" - lodash.camelcase "^3.0.1" + loader-utils "^1.0.2" + lodash.camelcase "^4.3.0" object-assign "^4.0.1" postcss "^5.0.6" postcss-modules-extract-imports "^1.0.0" postcss-modules-local-by-default "^1.0.1" postcss-modules-scope "^1.0.0" postcss-modules-values "^1.1.0" - source-list-map "^0.1.4" + postcss-value-parser "^3.3.0" + source-list-map "^0.1.7" css-parse@1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/css-parse/-/css-parse-1.0.4.tgz#38b0503fbf9da9f54e9c1dbda60e145c77117bdd" -css-selector-tokenizer@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.6.0.tgz#6445f582c7930d241dcc5007a43d6fcb8f073152" - dependencies: - cssesc "^0.1.0" - fastparse "^1.1.1" - regexpu-core "^1.0.0" - css-selector-tokenizer@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz#e6988474ae8c953477bf5e7efecfceccd9cf4c86" @@ -1417,11 +1414,11 @@ file-entry-cache@^2.0.0: flat-cache "^1.2.1" object-assign "^4.0.1" -file-loader@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-0.9.0.tgz#1d2daddd424ce6d1b07cfe3f79731bed3617ab42" +file-loader@^0.11.1: + version "0.11.1" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-0.11.1.tgz#6b328ee1234a729e4e47d36375dd6d35c0e1db84" dependencies: - loader-utils "~0.2.5" + loader-utils "^1.0.2" filename-regex@^2.0.0: version "2.0.1" @@ -2218,11 +2215,13 @@ lcov-parse@0.0.10, lcov-parse@0.x: version "0.0.10" resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3" -less-loader@^2.0.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-2.2.3.tgz#b6d8f8139c8493df09d992a93a00734b08f84528" +less-loader@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-4.0.3.tgz#d1e6462ca2f090c11248455e14b8dda4616d0521" dependencies: - loader-utils "^0.2.5" + clone "^2.1.1" + loader-utils "^1.1.0" + pify "^2.3.0" less@^2.5.1: version "2.7.2" @@ -2258,7 +2257,15 @@ loader-runner@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" -loader-utils@0.2.x, loader-utils@^0.2.16, loader-utils@^0.2.5, loader-utils@~0.2.2, loader-utils@~0.2.5: +loader-utils@^1.0.2, loader-utils@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + +loader-utils@~0.2.5: version "0.2.17" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" dependencies: @@ -2267,14 +2274,6 @@ loader-utils@0.2.x, loader-utils@^0.2.16, loader-utils@^0.2.5, loader-utils@~0.2 json5 "^0.5.0" object-assign "^4.0.1" -loader-utils@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" - dependencies: - big.js "^3.1.3" - emojis-list "^2.0.0" - json5 "^0.5.0" - lodash._baseassign@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" @@ -2290,13 +2289,6 @@ lodash._basecreate@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821" -lodash._createcompounder@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._createcompounder/-/lodash._createcompounder-3.0.0.tgz#5dd2cb55372d6e70e0e2392fb2304d6631091075" - dependencies: - lodash.deburr "^3.0.0" - lodash.words "^3.0.0" - lodash._getnative@^3.0.0: version "3.9.1" resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" @@ -2305,15 +2297,9 @@ lodash._isiterateecall@^3.0.0: version "3.0.9" resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" -lodash._root@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" - -lodash.camelcase@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-3.0.1.tgz#932c8b87f8a4377897c67197533282f97aeac298" - dependencies: - lodash._createcompounder "^3.0.0" +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" lodash.create@3.1.1: version "3.1.1" @@ -2323,12 +2309,6 @@ lodash.create@3.1.1: lodash._basecreate "^3.0.0" lodash._isiterateecall "^3.0.0" -lodash.deburr@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lodash.deburr/-/lodash.deburr-3.2.0.tgz#6da8f54334a366a7cf4c4c76ef8d80aa1b365ed5" - dependencies: - lodash._root "^3.0.0" - lodash.isarguments@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" @@ -2353,12 +2333,6 @@ lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" -lodash.words@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lodash.words/-/lodash.words-3.2.0.tgz#4e2a8649bc08745b17c695b1a3ce8fee596623b3" - dependencies: - lodash._root "^3.0.0" - lodash@^3.10.0: version "3.10.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" @@ -2855,7 +2829,7 @@ performance-now@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" -pify@^2.0.0: +pify@^2.0.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -3569,6 +3543,12 @@ sax@~1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.2.tgz#fd8631a23bc7826bef5d871bdb87378c95647828" +schema-utils@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.3.0.tgz#f5877222ce3e931edae039f17eb3716e7137f8cf" + dependencies: + ajv "^5.0.0" + script-loader@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/script-loader/-/script-loader-0.7.0.tgz#685dc7e7069e0dee7a92674f0ebc5b0f55baa5ec" @@ -3738,7 +3718,7 @@ sort-keys@^1.0.0: dependencies: is-plain-obj "^1.0.0" -source-list-map@^0.1.4, source-list-map@~0.1.7: +source-list-map@^0.1.7, source-list-map@~0.1.7: version "0.1.8" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.8.tgz#c550b2ab5427f6b3f21f5afead88c4f5587b2106" @@ -3891,11 +3871,12 @@ strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" -style-loader@~0.13.0: - version "0.13.2" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.13.2.tgz#74533384cf698c7104c7951150b49717adc2f3bb" +style-loader@^0.18.1: + version "0.18.1" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.18.1.tgz#6afca8953c842830e5e2dc84796309880a97f7e8" dependencies: loader-utils "^1.0.2" + schema-utils "^0.3.0" subcommand@^2.0.3: version "2.1.0" @@ -4158,11 +4139,11 @@ uuid@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" -val-loader@~0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/val-loader/-/val-loader-0.5.1.tgz#a20f9d63e4be036f86f4ee4bdcb2a103b85884e7" +val-loader@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/val-loader/-/val-loader-1.0.2.tgz#7909198093b37cba0a96bf4f6d29de970d099d3d" dependencies: - loader-utils "^1.0.2" + loader-utils "^1.1.0" validate-npm-package-license@^3.0.1: version "3.0.1" @@ -4269,11 +4250,11 @@ wordwrap@^1.0.0, wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" -worker-loader@~0.7.0: - version "0.7.1" - resolved "https://registry.yarnpkg.com/worker-loader/-/worker-loader-0.7.1.tgz#91ffd2e2fbf76921a43e8ca3766d12e9537f5d70" +worker-loader@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/worker-loader/-/worker-loader-0.8.0.tgz#13582960dcd7d700dc829d3fd252a7561696167e" dependencies: - loader-utils "0.2.x" + loader-utils "^1.0.2" wrap-ansi@^2.0.0: version "2.1.0" From 5d5303278bc5402821601ab42e79000ea70c3946 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 29 May 2017 11:04:42 +0200 Subject: [PATCH 37/40] fix loader --- .../configCases/loaders/issue-3320/node_modules/any-loader.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/configCases/loaders/issue-3320/node_modules/any-loader.js b/test/configCases/loaders/issue-3320/node_modules/any-loader.js index 8aae39f90..956e65bee 100644 --- a/test/configCases/loaders/issue-3320/node_modules/any-loader.js +++ b/test/configCases/loaders/issue-3320/node_modules/any-loader.js @@ -2,7 +2,7 @@ var loaderUtils = require('loader-utils'); module.exports = function(source) { var loaderContext = this; - var options = loaderUtils.parseQuery(loaderContext.query); + var options = loaderUtils.getOptions(loaderContext); - return "module.exports=" + JSON.stringify(options.foo) + return "module.exports=" + JSON.stringify(options.foo); } From a46e0544536cde14c37b8b48998bda31a699943e Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 31 May 2017 15:29:18 +0200 Subject: [PATCH 38/40] fix for val-loader change --- test/cases/loaders/_css/generateCss.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/cases/loaders/_css/generateCss.js b/test/cases/loaders/_css/generateCss.js index f3adcd1da..b3bf64996 100644 --- a/test/cases/loaders/_css/generateCss.js +++ b/test/cases/loaders/_css/generateCss.js @@ -1,3 +1,7 @@ var fs = require("fs"); var path = require("path"); -module.exports = fs.readFileSync(path.join(path.dirname(__filename), "stylesheet.css"), "utf-8") + "\n.generated { color: red; }"; +module.exports = function() { + return { + code: fs.readFileSync(path.join(path.dirname(__filename), "stylesheet.css"), "utf-8") + "\n.generated { color: red; }" + }; +}; From 65e6e768266df3d152521ae64b31248a2ddf8ef5 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 5 Jun 2017 13:52:45 +0200 Subject: [PATCH 39/40] update yarn lock --- yarn.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index b96d948e4..4b530d5a5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -73,7 +73,7 @@ ajv@^4.11.2, ajv@^4.7.0, ajv@^4.9.1: co "^4.6.0" json-stable-stringify "^1.0.1" -ajv@^5.1.5: +ajv@^5.0.0, ajv@^5.1.5: version "5.1.5" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.1.5.tgz#8734931b601f00d4feef7c65738d77d1b65d1f68" dependencies: From 9a6e85a1197c1db3a4d875814b4910e4efabd3ff Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 5 Jun 2017 14:04:12 +0200 Subject: [PATCH 40/40] update stats snapshot --- .../separate-css-bundle/expected.txt | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/test/statsCases/separate-css-bundle/expected.txt b/test/statsCases/separate-css-bundle/expected.txt index 66d50015d..3afb3b42d 100644 --- a/test/statsCases/separate-css-bundle/expected.txt +++ b/test/statsCases/separate-css-bundle/expected.txt @@ -1,29 +1,31 @@ -Hash: 7e5cb63b7ac6537cf830018a511be5ab8bf1e17b +Hash: a3f5cb0c4f2d75d79214074bc8c917dae9eb215a Child - Hash: 7e5cb63b7ac6537cf830 + Hash: a3f5cb0c4f2d75d79214 Time: Xms Asset Size Chunks Chunk Names 5a21b890f95ec575ba49.js 2.62 kB 0 [emitted] main c815cf440254d4f3bba4e7041db00a28.css 26 bytes 0 [emitted] main [0] (webpack)/test/statsCases/separate-css-bundle/a/index.js 23 bytes {0} [built] [1] (webpack)/test/statsCases/separate-css-bundle/a/file.css 41 bytes {0} [built] - [2] (webpack)/node_modules/css-loader!(webpack)/test/statsCases/separate-css-bundle/a/file.css 190 bytes [built] - [3] (webpack)/node_modules/css-loader/lib/css-base.js 1.46 kB [built] - [4] (webpack)/node_modules/style-loader/addStyles.js 6.91 kB [built] + [2] (webpack)/node_modules/css-loader!(webpack)/test/statsCases/separate-css-bundle/a/file.css 199 bytes [built] + [3] (webpack)/node_modules/css-loader/lib/css-base.js 2.26 kB [built] + [4] (webpack)/node_modules/style-loader/lib/addStyles.js 8.66 kB [built] + [5] (webpack)/node_modules/style-loader/lib/urls.js 3.01 kB [built] Child extract-text-webpack-plugin: - [0] (webpack)/node_modules/css-loader!(webpack)/test/statsCases/separate-css-bundle/a/file.css 190 bytes {0} [built] - [1] (webpack)/node_modules/css-loader/lib/css-base.js 1.46 kB {0} [built] + [0] (webpack)/node_modules/css-loader!(webpack)/test/statsCases/separate-css-bundle/a/file.css 199 bytes {0} [built] + [1] (webpack)/node_modules/css-loader/lib/css-base.js 2.26 kB {0} [built] Child - Hash: 018a511be5ab8bf1e17b + Hash: 074bc8c917dae9eb215a Time: Xms Asset Size Chunks Chunk Names 5a21b890f95ec575ba49.js 2.62 kB 0 [emitted] main a3f385680aef7a9bb2a517699532cc34.css 28 bytes 0 [emitted] main [0] (webpack)/test/statsCases/separate-css-bundle/b/index.js 23 bytes {0} [built] [1] (webpack)/test/statsCases/separate-css-bundle/b/file.css 41 bytes {0} [built] - [2] (webpack)/node_modules/css-loader!(webpack)/test/statsCases/separate-css-bundle/b/file.css 192 bytes [built] - [3] (webpack)/node_modules/css-loader/lib/css-base.js 1.46 kB [built] - [4] (webpack)/node_modules/style-loader/addStyles.js 6.91 kB [built] + [2] (webpack)/node_modules/css-loader!(webpack)/test/statsCases/separate-css-bundle/b/file.css 201 bytes [built] + [3] (webpack)/node_modules/css-loader/lib/css-base.js 2.26 kB [built] + [4] (webpack)/node_modules/style-loader/lib/addStyles.js 8.66 kB [built] + [5] (webpack)/node_modules/style-loader/lib/urls.js 3.01 kB [built] Child extract-text-webpack-plugin: - [0] (webpack)/node_modules/css-loader!(webpack)/test/statsCases/separate-css-bundle/b/file.css 192 bytes {0} [built] - [1] (webpack)/node_modules/css-loader/lib/css-base.js 1.46 kB {0} [built] \ No newline at end of file + [0] (webpack)/node_modules/css-loader!(webpack)/test/statsCases/separate-css-bundle/b/file.css 201 bytes {0} [built] + [1] (webpack)/node_modules/css-loader/lib/css-base.js 2.26 kB {0} [built] \ No newline at end of file