diff --git a/lib/Chunk.js b/lib/Chunk.js index 4745f4a10..9747a7d2c 100644 --- a/lib/Chunk.js +++ b/lib/Chunk.js @@ -137,6 +137,36 @@ Chunk.prototype.updateHash = function(hash) { }); }; +Chunk.prototype.size = function(options) { + var CHUNK_OVERHEAD = options.chunkOverhead || 10000; + var ENTRY_CHUNK_MULTIPLICATOR = options.entryChunkMultiplicator || 10; + + var modulesSize = this.modules.map(function(m) { + return m.size(); + }).reduce(function(a, b) { + return a + b; + }, 0); + return modulesSize * (this.entry ? ENTRY_CHUNK_MULTIPLICATOR : 1) + CHUNK_OVERHEAD; +}; + +Chunk.prototype.integratedSize = function(other, options) { + var CHUNK_OVERHEAD = options.chunkOverhead || 10000; + var ENTRY_CHUNK_MULTIPLICATOR = options.entryChunkMultiplicator || 10; + + var mergedModules = this.modules.slice(); + other.modules.forEach(function(m) { + if(this.modules.indexOf(m) < 0) + mergedModules.push(m); + }, this); + + var modulesSize = mergedModules.map(function(m) { + return m.size(); + }).reduce(function(a, b) { + return a + b; + }, 0); + return modulesSize * (this.entry || other.entry ? ENTRY_CHUNK_MULTIPLICATOR : 1) + CHUNK_OVERHEAD; +}; + Chunk.prototype.toString = function() { return "Chunk[" + this.modules.join() + "]"; }; \ No newline at end of file diff --git a/lib/WebpackOptionsApply.js b/lib/WebpackOptionsApply.js index 03be63d3b..446baa741 100644 --- a/lib/WebpackOptionsApply.js +++ b/lib/WebpackOptionsApply.js @@ -147,7 +147,7 @@ WebpackOptionsApply.prototype.process = function(options, compiler) { compiler.apply(new OccurenceOrderPlugin(options.optimize.occurenceOrderPreferEntry)); if(options.optimize && options.optimize.minChunkSize) - compiler.apply(new MinChunkSizePlugin(options.optimize.minChunkSize)); + compiler.apply(new MinChunkSizePlugin(options.optimize)); if(options.optimize && options.optimize.maxChunks) compiler.apply(new LimitChunkCountPlugin(options.optimize)); diff --git a/lib/optimize/LimitChunkCountPlugin.js b/lib/optimize/LimitChunkCountPlugin.js index 77bbe2d72..f58f1fb68 100644 --- a/lib/optimize/LimitChunkCountPlugin.js +++ b/lib/optimize/LimitChunkCountPlugin.js @@ -2,14 +2,6 @@ MIT License http://www.opensource.org/licenses/mit-license.php Author Tobias Koppers @sokra */ -function chunkSizeWithModules(modules) { - return modules.map(function(m) { - return m.size(); - }).reduce(function(a, b) { - return a + b; - }); -} - function LimitChunkCountPlugin(options) { this.options = options || {}; } @@ -24,9 +16,6 @@ LimitChunkCountPlugin.prototype.apply = function(compiler) { if(maxChunks < 1) return; if(chunks.length <= maxChunks) return; - var CHUNK_OVERHEAD = options.chunkOverhead || 10000; - var ENTRY_CHUNK_MULTIPLICATOR = options.entryChunkMultiplicator || 10; - if(chunks.length > maxChunks) { var combinations = []; chunks.forEach(function(a, idx) { @@ -37,16 +26,9 @@ LimitChunkCountPlugin.prototype.apply = function(compiler) { }); combinations.forEach(function(pair) { - var modulesA = pair[0].modules; - var modulesB = pair[1].modules; - var mergedModules = modulesA.slice(); - modulesB.forEach(function(m) { - if(modulesA.indexOf(m) < 0) - mergedModules.push(m); - }); - var a = chunkSizeWithModules(modulesA) * (pair[0].entry ? ENTRY_CHUNK_MULTIPLICATOR : 1) + CHUNK_OVERHEAD; - var b = chunkSizeWithModules(modulesB) * (pair[1].entry ? ENTRY_CHUNK_MULTIPLICATOR : 1) + CHUNK_OVERHEAD; - var ab = chunkSizeWithModules(mergedModules) * (pair[0].entry || pair[1].entry ? ENTRY_CHUNK_MULTIPLICATOR : 1) + CHUNK_OVERHEAD; + var a = pair[0].size(options); + var b = pair[1].size(options); + var ab = pair[0].integratedSize(pair[1], options); pair.unshift(a + b - ab, ab); }); combinations.sort(function(a,b) { diff --git a/lib/optimize/MinChunkSizePlugin.js b/lib/optimize/MinChunkSizePlugin.js index 38521a6c3..94b8dc007 100644 --- a/lib/optimize/MinChunkSizePlugin.js +++ b/lib/optimize/MinChunkSizePlugin.js @@ -2,49 +2,53 @@ MIT License http://www.opensource.org/licenses/mit-license.php Author Tobias Koppers @sokra */ -function chunkSizeWithModules(modules) { - return modules.map(function(m) { - return m.size(); - }).reduce(function(a, b) { - return a + b; - }); -} - -function MinChunkSizePlugin(minChunkSize) { - this.minChunkSize = minChunkSize; +function MinChunkSizePlugin(options) { + this.options = options; } module.exports = MinChunkSizePlugin; MinChunkSizePlugin.prototype.apply = function(compiler) { - var minChunkSize = this.minChunkSize; + var options = this.options; + var minChunkSize = options.minChunkSize; compiler.plugin("compilation", function(compilation) { compilation.plugin("optimize-chunks", function(chunks) { - var argumentedChunks = chunks.map(function(chunk) { - return { - size: chunkSizeWithModules(chunk.modules), - entry: !!chunk.entry, - chunk: chunk + var combinations = []; + chunks.forEach(function(a, idx) { + for(var i = 0; i < idx; i++) { + var b = chunks[i]; + combinations.push([b, a]); } - }).sort(function(a, b) { - if(a.entry != b.entry) { - return a.entry ? 1 : -1; - } - return a.size - b.size; }); - if(argumentedChunks.length > 0 && argumentedChunks[0].size < minChunkSize && !argumentedChunks[0].entry) { - for(var i = 1; i < argumentedChunks.length; i++) { - if(argumentedChunks[i].size + argumentedChunks[0].size >= minChunkSize) - break; - } - if(i == argumentedChunks.length) i = 1; - if(argumentedChunks[i]) { - argumentedChunks[i].chunk.integrate(argumentedChunks[0].chunk, "min-size"); - chunks.splice(chunks.indexOf(argumentedChunks[0].chunk), 1); - this.restartApplyPlugins(); - } - } + var equalOptions = { + chunkOverhead: 1, + entryChunkMultiplicator: 1 + }; + combinations = combinations.filter(function(pair) { + return pair[0].size(equalOptions) < minChunkSize || pair[1].size(equalOptions) < minChunkSize; + }); + + if(combinations.length == 0) return; + + combinations.forEach(function(pair) { + var a = pair[0].size(options); + var b = pair[1].size(options); + var ab = pair[0].integratedSize(pair[1], options); + pair.unshift(a + b - ab, ab); + }); + + combinations.sort(function(a,b) { + var diff = b[0] - a[0]; + if(diff != 0) return diff; + return a[1] - b[1]; + }); + + var pair = combinations[0]; + + pair[2].integrate(pair[3], "min-size"); + chunks.splice(chunks.indexOf(pair[3]), 1); + this.restartApplyPlugins(); }); }); }; diff --git a/package.json b/package.json index 83c8b3701..2b95517ff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "webpack", - "version": "0.10.0-beta23", + "version": "0.10.0-beta24", "author": "Tobias Koppers @sokra", "description": "Packs CommonJs/AMD/Labeled Modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jade, coffee, css, less, ... and your custom stuff.", "dependencies": {