Browse Source

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

0.10
Tobias Koppers 9 years ago
parent
commit
47ae6dc211
  1. 24
      examples/code-splitted-dedupe/README.md
  2. 39
      examples/dedupe/README.md
  3. 29
      lib/optimize/DedupePlugin.js
  4. 2
      package.json

24
examples/code-splitted-dedupe/README.md

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

39
examples/dedupe/README.md

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

29
lib/optimize/DedupePlugin.js

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

2
package.json

@ -1,6 +1,6 @@
{
"name": "webpack",
"version": "0.10.0-beta21",
"version": "0.10.0-beta22",
"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": {

Loading…
Cancel
Save