only add deduplicate code if deduplicated modules are in the chunk.

This commit is contained in:
Tobias Koppers 2013-06-14 15:42:40 +02:00
parent a91cff49b6
commit 47ae6dc211
4 changed files with 66 additions and 28 deletions

View File

@ -87,11 +87,15 @@ require(["../dedupe/b"]);
/******/ } /******/ }
/******/ for(moduleId in moreModules) { /******/ for(moduleId in moreModules) {
/******/ var _m = moreModules[moduleId]; /******/ var _m = moreModules[moduleId];
/******/
/******/ // Check if module is deduplicated
/******/ switch(typeof _m) { /******/ switch(typeof _m) {
/******/ case "number": /******/ case "number":
/******/ // Module is a copy of another module
/******/ modules[moduleId] = modules[_m]; /******/ modules[moduleId] = modules[_m];
/******/ break; /******/ break;
/******/ case "object": /******/ case "object":
/******/ // Module can be created from a template
/******/ modules[moduleId] = (function(_m) { /******/ modules[moduleId] = (function(_m) {
/******/ var args = _m.slice(1), fn = modules[_m[0]]; /******/ var args = _m.slice(1), fn = modules[_m[0]];
/******/ return function (a,b,c) { /******/ return function (a,b,c) {
@ -100,6 +104,7 @@ require(["../dedupe/b"]);
/******/ }(_m)); /******/ }(_m));
/******/ break; /******/ break;
/******/ default: /******/ default:
/******/ // Normal module
/******/ modules[moduleId] = _m; /******/ modules[moduleId] = _m;
/******/ } /******/ }
/******/ } /******/ }
@ -112,12 +117,15 @@ require(["../dedupe/b"]);
/******/ }) /******/ })
/************************************************************************/ /************************************************************************/
/******/ ((function(modules) { /******/ ((function(modules) {
// Check all modules for deduplicated modules
for(var i in modules) { for(var i in modules) {
switch(typeof modules[i]) { switch(typeof modules[i]) {
case "number": case "number":
// Module is a copy of another module
modules[i] = modules[modules[i]]; modules[i] = modules[modules[i]];
break; break;
case "object": case "object":
// Module can be created from a template
modules[i] = (function(_m) { modules[i] = (function(_m) {
var args = _m.slice(1), fn = modules[_m[0]]; var args = _m.slice(1), fn = modules[_m[0]];
return function (a,b,c) { return function (a,b,c) {
@ -360,10 +368,10 @@ webpackJsonp([4],
``` ```
Hash: 46d170ad35acc40bf3ea Hash: 46d170ad35acc40bf3ea
Version: webpack 0.10.0-beta20 Version: webpack 0.10.0-beta22
Time: 101ms Time: 95ms
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
output.js 4645 0 [emitted] main output.js 4972 0 [emitted] main
1.output.js 1485 1, 3 [emitted] 1.output.js 1485 1, 3 [emitted]
2.output.js 877 2, 4 [emitted] 2.output.js 877 2, 4 [emitted]
3.output.js 875 3 [emitted] 3.output.js 875 3 [emitted]
@ -377,8 +385,8 @@ chunk {1} 1.output.js 492 {0} [rendered]
[3] (webpack)/~/bundle-loader?lazy!../dedupe/b/index.js 207 {1} [built] [3] (webpack)/~/bundle-loader?lazy!../dedupe/b/index.js 207 {1} [built]
amd require bundle?lazy!../dedupe/b [0] ./example.js 2:0-51 amd require bundle?lazy!../dedupe/b [0] ./example.js 2:0-51
[4] ../dedupe/z.js 34 {1} {2} {3} [built] [4] ../dedupe/z.js 34 {1} {2} {3} [built]
cjs require ../z [2] ../dedupe/b/index.js 4:4-19
cjs require ../z [1] ../dedupe/a/index.js 4:4-19 cjs require ../z [1] ../dedupe/a/index.js 4:4-19
cjs require ../z [2] ../dedupe/b/index.js 4:4-19
[5] ../dedupe/a/x.js 34 {1} {3} [built] [5] ../dedupe/a/x.js 34 {1} {3} [built]
cjs require ./x [1] ../dedupe/a/index.js 2:4-18 cjs require ./x [1] ../dedupe/a/index.js 2:4-18
[6] ../dedupe/a/y.js 49 {1} {3} [built] [6] ../dedupe/a/y.js 49 {1} {3} [built]
@ -391,8 +399,8 @@ chunk {2} 2.output.js 201 {0} [rendered]
amd require ../dedupe/b [0] ./example.js 6:0-24 amd require ../dedupe/b [0] ./example.js 6:0-24
cjs require !!(webpack)\examples\dedupe\b\index.js [3] (webpack)/~/bundle-loader?lazy!../dedupe/b/index.js 3:5-126 cjs require !!(webpack)\examples\dedupe\b\index.js [3] (webpack)/~/bundle-loader?lazy!../dedupe/b/index.js 3:5-126
[4] ../dedupe/z.js 34 {1} {2} {3} [built] [4] ../dedupe/z.js 34 {1} {2} {3} [built]
cjs require ../z [2] ../dedupe/b/index.js 4:4-19
cjs require ../z [1] ../dedupe/a/index.js 4:4-19 cjs require ../z [1] ../dedupe/a/index.js 4:4-19
cjs require ../z [2] ../dedupe/b/index.js 4:4-19
[7] ../dedupe/b/x.js 34 {2} {4} [built] [7] ../dedupe/b/x.js 34 {2} {4} [built]
cjs require ./x [2] ../dedupe/b/index.js 2:4-18 cjs require ./x [2] ../dedupe/b/index.js 2:4-18
[8] ../dedupe/b/y.js 49 {2} {4} [built] [8] ../dedupe/b/y.js 49 {2} {4} [built]
@ -402,8 +410,8 @@ chunk {3} 3.output.js 201 {0} [rendered]
amd require ../dedupe/a [0] ./example.js 2:0-51 amd require ../dedupe/a [0] ./example.js 2:0-51
amd require ../dedupe/a [0] ./example.js 5:0-24 amd require ../dedupe/a [0] ./example.js 5:0-24
[4] ../dedupe/z.js 34 {1} {2} {3} [built] [4] ../dedupe/z.js 34 {1} {2} {3} [built]
cjs require ../z [2] ../dedupe/b/index.js 4:4-19
cjs require ../z [1] ../dedupe/a/index.js 4:4-19 cjs require ../z [1] ../dedupe/a/index.js 4:4-19
cjs require ../z [2] ../dedupe/b/index.js 4:4-19
[5] ../dedupe/a/x.js 34 {1} {3} [built] [5] ../dedupe/a/x.js 34 {1} {3} [built]
cjs require ./x [1] ../dedupe/a/index.js 2:4-18 cjs require ./x [1] ../dedupe/a/index.js 2:4-18
[6] ../dedupe/a/y.js 49 {1} {3} [built] [6] ../dedupe/a/y.js 49 {1} {3} [built]
@ -422,8 +430,8 @@ chunk {4} 4.output.js 167 {1} [rendered]
``` ```
Hash: 46d170ad35acc40bf3ea Hash: 46d170ad35acc40bf3ea
Version: webpack 0.10.0-beta20 Version: webpack 0.10.0-beta22
Time: 273ms Time: 267ms
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
output.js 1151 0 [emitted] main output.js 1151 0 [emitted] main
1.output.js 294 1, 3 [emitted] 1.output.js 294 1, 3 [emitted]

View File

@ -105,12 +105,15 @@ module.exports = {"this is": "z"};
/******/ }) /******/ })
/************************************************************************/ /************************************************************************/
/******/ ((function(modules) { /******/ ((function(modules) {
// Check all modules for deduplicated modules
for(var i in modules) { for(var i in modules) {
switch(typeof modules[i]) { switch(typeof modules[i]) {
case "number": case "number":
// Module is a copy of another module
modules[i] = modules[modules[i]]; modules[i] = modules[modules[i]];
break; break;
case "object": case "object":
// Module can be created from a template
modules[i] = (function(_m) { modules[i] = (function(_m) {
var args = _m.slice(1), fn = modules[_m[0]]; var args = _m.slice(1), fn = modules[_m[0]];
return function (a,b,c) { return function (a,b,c) {
@ -207,29 +210,29 @@ module.exports = {"this is": "z"};
## Uncompressed ## Uncompressed
``` ```
Hash: 4afc9f4631bed4b86de9 Hash: 15b13398a7aae2eaaec9
Version: webpack 0.10.0-beta20 Version: webpack 0.10.0-beta22
Time: 42ms Time: 54ms
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
output.js 3223 0 [emitted] main output.js 3362 0 [emitted] main
chunk {0} output.js (main) 513 [rendered] chunk {0} output.js (main) 528 [rendered]
[0] ./example.js 73 {0} [built] [0] ./example.js 76 {0} [built]
[1] ./z.js 34 {0} [built] [1] ./z.js 34 {0} [built]
cjs require ../z [2] ./a/index.js 4:4-19 cjs require ../z [2] ./a/index.js 4:4-19
cjs require ../z [5] ./b/index.js 4:4-19 cjs require ../z [5] ./b/index.js 4:4-19
[2] ./a/index.js 80 {0} [built] [2] ./a/index.js 84 {0} [built]
cjs require ./a [0] ./example.js 1:8-22 cjs require ./a [0] ./example.js 1:8-22
[3] ./a/x.js 34 {0} [built] [3] ./a/x.js 34 {0} [built]
cjs require ./x [2] ./a/index.js 2:4-18 cjs require ./x [2] ./a/index.js 2:4-18
[4] ./a/y.js 49 {0} [built] [4] ./a/y.js 49 {0} [built]
cjs require ./y [2] ./a/index.js 3:4-18 cjs require ./y [2] ./a/index.js 3:4-18
[5] ./b/index.js 80 {0} [built] [5] ./b/index.js 84 {0} [built]
cjs require ./b [0] ./example.js 2:8-22 cjs require ./b [0] ./example.js 2:8-22
[6] ./b/x.js 34 {0} [built] [6] ./b/x.js 34 {0} [built]
cjs require ./x [5] ./b/index.js 2:4-18 cjs require ./x [5] ./b/index.js 2:4-18
[7] ./b/y.js 49 {0} [built] [7] ./b/y.js 49 {0} [built]
cjs require ./y [5] ./b/index.js 3:4-18 cjs require ./y [5] ./b/index.js 3:4-18
[8] 80 {0} [not cacheable] [built] [8] 84 {0} [not cacheable] [built]
template 1 [2] ./a/index.js template 1 [2] ./a/index.js
template 1 [5] ./b/index.js template 1 [5] ./b/index.js
``` ```
@ -237,29 +240,29 @@ chunk {0} output.js (main) 513 [rendered]
## Minimized (uglify-js, no zip) ## Minimized (uglify-js, no zip)
``` ```
Hash: 4afc9f4631bed4b86de9 Hash: 15b13398a7aae2eaaec9
Version: webpack 0.10.0-beta20 Version: webpack 0.10.0-beta22
Time: 98ms Time: 137ms
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
output.js 776 0 [emitted] main output.js 777 0 [emitted] main
chunk {0} output.js (main) 513 [rendered] chunk {0} output.js (main) 528 [rendered]
[0] ./example.js 73 {0} [built] [0] ./example.js 76 {0} [built]
[1] ./z.js 34 {0} [built] [1] ./z.js 34 {0} [built]
cjs require ../z [2] ./a/index.js 4:4-19 cjs require ../z [2] ./a/index.js 4:4-19
cjs require ../z [5] ./b/index.js 4:4-19 cjs require ../z [5] ./b/index.js 4:4-19
[2] ./a/index.js 80 {0} [built] [2] ./a/index.js 84 {0} [built]
cjs require ./a [0] ./example.js 1:8-22 cjs require ./a [0] ./example.js 1:8-22
[3] ./a/x.js 34 {0} [built] [3] ./a/x.js 34 {0} [built]
cjs require ./x [2] ./a/index.js 2:4-18 cjs require ./x [2] ./a/index.js 2:4-18
[4] ./a/y.js 49 {0} [built] [4] ./a/y.js 49 {0} [built]
cjs require ./y [2] ./a/index.js 3:4-18 cjs require ./y [2] ./a/index.js 3:4-18
[5] ./b/index.js 80 {0} [built] [5] ./b/index.js 84 {0} [built]
cjs require ./b [0] ./example.js 2:8-22 cjs require ./b [0] ./example.js 2:8-22
[6] ./b/x.js 34 {0} [built] [6] ./b/x.js 34 {0} [built]
cjs require ./x [5] ./b/index.js 2:4-18 cjs require ./x [5] ./b/index.js 2:4-18
[7] ./b/y.js 49 {0} [built] [7] ./b/y.js 49 {0} [built]
cjs require ./y [5] ./b/index.js 3:4-18 cjs require ./y [5] ./b/index.js 3:4-18
[8] 80 {0} [not cacheable] [built] [8] 84 {0} [not cacheable] [built]
template 1 [2] ./a/index.js template 1 [2] ./a/index.js
template 1 [5] ./b/index.js template 1 [5] ./b/index.js
``` ```

View File

@ -36,6 +36,7 @@ DedupePlugin.prototype.apply = function(compiler) {
compilation.plugin("after-optimize-chunks", function(chunks) { compilation.plugin("after-optimize-chunks", function(chunks) {
var entryChunks = chunks.filter(function(c) { return c.entry; }); var entryChunks = chunks.filter(function(c) { return c.entry; });
entryChunks.forEach(function(chunk) { // for each entry chunk entryChunks.forEach(function(chunk) { // for each entry chunk
var hasDeduplicatedModules = false;
(function x(dups, roots, visited, chunk) { (function x(dups, roots, visited, chunk) {
var currentDups = []; var currentDups = [];
var currentRoots = []; var currentRoots = [];
@ -51,6 +52,7 @@ DedupePlugin.prototype.apply = function(compiler) {
module.rootDuplicates[chunkIndex].push(module); module.rootDuplicates[chunkIndex].push(module);
module.rootDuplicates[chunkIndex].commonModules = module.rootDuplicates[chunkIndex].commonModules =
mergeCommonModules(module.rootDuplicates[chunkIndex].commonModules, module.getAllModuleDependencies()); mergeCommonModules(module.rootDuplicates[chunkIndex].commonModules, module.getAllModuleDependencies());
hasDeduplicatedModules = true;
} else { } else {
idx = dups.indexOf(module.duplicates); idx = dups.indexOf(module.duplicates);
if(idx < 0) { if(idx < 0) {
@ -65,6 +67,7 @@ DedupePlugin.prototype.apply = function(compiler) {
module.rootDuplicates[chunkIndex] = roots[idx]; module.rootDuplicates[chunkIndex] = roots[idx];
module.rootDuplicates[chunkIndex].commonModules = module.rootDuplicates[chunkIndex].commonModules =
mergeCommonModules(module.rootDuplicates[chunkIndex].commonModules, module.getAllModuleDependencies()); mergeCommonModules(module.rootDuplicates[chunkIndex].commonModules, module.getAllModuleDependencies());
hasDeduplicatedModules = true;
} }
} }
} }
@ -83,9 +86,12 @@ DedupePlugin.prototype.apply = function(compiler) {
chunk.addModule(template); chunk.addModule(template);
template.addChunk(chunk); template.addChunk(chunk);
compilation.modules.push(template); compilation.modules.push(template);
hasDeduplicatedModules = true;
} }
}); });
}([], [], [], chunk)); }([], [], [], chunk));
if(hasDeduplicatedModules)
chunk._DedupePlugin_hasDeduplicatedModules = true;
}); });
}); });
function mergeCommonModules(commonModules, newModules) { function mergeCommonModules(commonModules, newModules) {
@ -96,17 +102,25 @@ DedupePlugin.prototype.apply = function(compiler) {
}); });
compiler.moduleTemplate = new DedupModuleTemplateDecorator(compiler.moduleTemplate); compiler.moduleTemplate = new DedupModuleTemplateDecorator(compiler.moduleTemplate);
compiler.mainTemplate = Object.create(compiler.mainTemplate); compiler.mainTemplate = Object.create(compiler.mainTemplate);
var oldRenderAddModule = compiler.mainTemplate.renderAddModule;
compiler.mainTemplate.renderAddModule = function(hash, chunk, varModuleId, varModule) { compiler.mainTemplate.renderAddModule = function(hash, chunk, varModuleId, varModule) {
if(!chunk._DedupePlugin_hasDeduplicatedModules) {
return oldRenderAddModule.call(this, hash, chunk, varModuleId, varModule);
}
return [ return [
"var _m = " + varModule + ";", "var _m = " + varModule + ";",
"",
"// Check if module is deduplicated",
"switch(typeof _m) {", "switch(typeof _m) {",
"case \"number\":", "case \"number\":",
this.indent([ this.indent([
"// Module is a copy of another module",
"modules[" + varModuleId + "] = modules[_m];", "modules[" + varModuleId + "] = modules[_m];",
"break;" "break;"
]), ]),
"case \"object\":", "case \"object\":",
this.indent([ this.indent([
"// Module can be created from a template",
"modules[" + varModuleId + "] = (function(_m) {", "modules[" + varModuleId + "] = (function(_m) {",
this.indent([ this.indent([
"var args = _m.slice(1), fn = modules[_m[0]];", "var args = _m.slice(1), fn = modules[_m[0]];",
@ -120,25 +134,34 @@ DedupePlugin.prototype.apply = function(compiler) {
"break;" "break;"
]), ]),
"default:", "default:",
this.indent("modules[" + varModuleId + "] = _m;"), this.indent([
"// Normal module",
"modules[" + varModuleId + "] = _m;"
]),
"}" "}"
] ]
}; };
var oldRenderModules = compiler.mainTemplate.renderModules; var oldRenderModules = compiler.mainTemplate.renderModules;
compiler.mainTemplate.renderModules = function renderModules(hash, chunk, moduleTemplate, dependencyTemplates) { compiler.mainTemplate.renderModules = function renderModules(hash, chunk, moduleTemplate, dependencyTemplates) {
if(!chunk._DedupePlugin_hasDeduplicatedModules) {
return oldRenderModules.call(this, hash, chunk, moduleTemplate, dependencyTemplates);
}
var source = new ConcatSource(); var source = new ConcatSource();
source.add("(function(modules) {\n"); source.add("(function(modules) {\n");
source.add(this.indent([ source.add(this.indent([
"// Check all modules for deduplicated modules",
"for(var i in modules) {", "for(var i in modules) {",
this.indent([ this.indent([
"switch(typeof modules[i]) {", "switch(typeof modules[i]) {",
"case \"number\":", "case \"number\":",
this.indent([ this.indent([
"// Module is a copy of another module",
"modules[i] = modules[modules[i]];", "modules[i] = modules[modules[i]];",
"break;" "break;"
]), ]),
"case \"object\":", "case \"object\":",
this.indent([ this.indent([
"// Module can be created from a template",
"modules[i] = (function(_m) {", "modules[i] = (function(_m) {",
this.indent([ this.indent([
"var args = _m.slice(1), fn = modules[_m[0]];", "var args = _m.slice(1), fn = modules[_m[0]];",
@ -177,6 +200,10 @@ DedupModuleTemplateDecorator.prototype.render = function(module, dependencyTempl
request: module.request, request: module.request,
templateModules: rootDuplicates.template.templateModules templateModules: rootDuplicates.template.templateModules
}); });
rootDuplicates.template.reasons.sort(function(a, b) {
if(a.request == b.request) return 0;
return a.request < b.request ? -1 : 1;
});
var array = [rootDuplicates.template.id].concat(module.getTemplateArguments(rootDuplicates.template.templateModules).map(function(module) { var array = [rootDuplicates.template.id].concat(module.getTemplateArguments(rootDuplicates.template.templateModules).map(function(module) {
if(typeof module.id !== "number") if(typeof module.id !== "number")
return "(function webpackMissingModule() { throw new Error(" + JSON.stringify("Cannot find module") + "); }())" return "(function webpackMissingModule() { throw new Error(" + JSON.stringify("Cannot find module") + "); }())"

View File

@ -1,6 +1,6 @@
{ {
"name": "webpack", "name": "webpack",
"version": "0.10.0-beta21", "version": "0.10.0-beta22",
"author": "Tobias Koppers @sokra", "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.", "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": { "dependencies": {