Skip to content

Commit 20678c6

Browse files
authored
Merge pull request webpack#6150 from webpack/bugfix/concat-unused-modules
fix unnecessary module concatenation
2 parents f66fa27 + 878f288 commit 20678c6

File tree

50 files changed

+666
-565
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+666
-565
lines changed

lib/Compilation.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,10 @@ class Compilation extends Tapable {
838838
modules.sort((a, b) => {
839839
if(a.index < b.index) return -1;
840840
if(a.index > b.index) return 1;
841+
const identA = a.identifier();
842+
const identB = b.identifier();
843+
if(identA < identB) return -1;
844+
if(identA > identB) return 1;
841845
return 0;
842846
});
843847
}

lib/Stats.js

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ class Stats {
109109
const showChunkModules = optionOrLocalFallback(options.chunkModules, true);
110110
const showChunkOrigins = optionOrLocalFallback(options.chunkOrigins, !forToString);
111111
const showModules = optionOrLocalFallback(options.modules, true);
112+
const showNestedModules = optionOrLocalFallback(options.nestedModules, true);
112113
const showDepth = optionOrLocalFallback(options.depth, !forToString);
113114
const showCachedModules = optionOrLocalFallback(options.cached, true);
114115
const showCachedAssets = optionOrLocalFallback(options.cachedAssets, true);
@@ -385,6 +386,17 @@ class Stats {
385386
if(showDepth) {
386387
obj.depth = module.depth;
387388
}
389+
if(showNestedModules) {
390+
if(module.modules) {
391+
const modules = module.modules;
392+
obj.modules = modules
393+
.sort(sortByField("depth"))
394+
.filter(createModuleFilter())
395+
.map(fnModule);
396+
obj.filteredModules = modules.length - obj.modules.length;
397+
obj.modules.sort(sortByField(sortModules));
398+
}
399+
}
388400
if(showSource && module._source) {
389401
obj.source = module._source.source();
390402
}
@@ -792,26 +804,34 @@ class Stats {
792804
coloredTime(sum);
793805
newline();
794806
}
807+
if(module.modules) {
808+
processModulesList(module, prefix + "| ");
809+
}
795810
};
796811

797812
const processModulesList = (obj, prefix) => {
798813
if(obj.modules) {
799814
obj.modules.forEach(module => {
800815
colors.normal(prefix);
801-
if(module.id < 1000) colors.normal(" ");
802-
if(module.id < 100) colors.normal(" ");
803-
if(module.id < 10) colors.normal(" ");
804-
colors.normal("[");
805-
colors.normal(module.id);
806-
colors.normal("]");
807816
const name = module.name || module.identifier;
817+
let contentPrefix = prefix + " ";
818+
if(typeof module.id === "string" || typeof module.id === "number") {
819+
contentPrefix += " ";
820+
if(module.id < 1000) colors.normal(" ");
821+
if(module.id < 100) colors.normal(" ");
822+
if(module.id < 10) colors.normal(" ");
823+
colors.normal("[");
824+
colors.normal(module.id);
825+
colors.normal("]");
826+
if(name !== module.id)
827+
colors.normal(" ");
828+
}
808829
if(name !== module.id) {
809-
colors.normal(" ");
810830
colors.bold(name);
811831
}
812832
processModuleAttributes(module);
813833
newline();
814-
processModuleContent(module, prefix + " ");
834+
processModuleContent(module, contentPrefix);
815835
});
816836
if(obj.filteredModules > 0) {
817837
colors.normal(prefix);

lib/optimize/ConcatenatedModule.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,6 @@ class ConcatenatedModule extends Module {
186186
// Info from Optimization
187187
this.used = rootModule.used;
188188
this.usedExports = rootModule.usedExports;
189-
this.optimizationBailout = rootModule.optimizationBailout;
190189

191190
// Info from Build
192191
this.buildInfo = {

lib/optimize/ModuleConcatenationPlugin.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,20 @@ class ModuleConcatenationPlugin {
8787

8888
relevantModules.push(module);
8989

90+
const chunks = module.getChunks();
91+
9092
// Module must not be the entry points
91-
if(module.getChunks().some(chunk => chunk.entryModule === module)) {
93+
if(chunks.some(chunk => chunk.entryModule === module)) {
9294
setBailoutReason(module, "Module is an entry point");
9395
continue;
9496
}
9597

98+
// Module must be in any chunk (we don't want to do useless work)
99+
if(chunks.length === 0) {
100+
setBailoutReason(module, "Module is not in any chunk");
101+
continue;
102+
}
103+
96104
// Module must only be used by Harmony Imports
97105
const nonHarmonyReasons = module.reasons.filter(reason => !reason.dependency || !(reason.dependency instanceof HarmonyImportDependency));
98106
if(nonHarmonyReasons.length > 0) {

lib/optimize/OccurrenceOrderPlugin.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,12 @@ class OccurrenceOrderPlugin {
5151
});
5252
}
5353

54+
const originalOrder = new Map();
55+
let i = 0;
5456
modules.forEach(m => {
5557
const result = m.reasons.reduce(countOccurs, 0) + m.getNumberOfChunks() + entryCountMap.get(m);
5658
occursInAllChunksMap.set(m, result);
59+
originalOrder.set(m, i++);
5760
});
5861

5962
modules.sort((a, b) => {
@@ -67,20 +70,23 @@ class OccurrenceOrderPlugin {
6770
const bOccurs = occursInAllChunksMap.get(b);
6871
if(aOccurs > bOccurs) return -1;
6972
if(aOccurs < bOccurs) return 1;
70-
if(a.index > b.index) return 1;
71-
if(a.index < b.index) return -1;
72-
return 0;
73+
const orgA = originalOrder.get(a);
74+
const orgB = originalOrder.get(b);
75+
return orgB - orgA;
7376
});
7477
});
7578
compilation.hooks.optimizeChunkOrder.tap("OccurrenceOrderPlugin", (chunks) => {
7679
const occursInInitialChunksMap = new Map();
80+
const originalOrder = new Map();
7781

82+
let i = 0;
7883
chunks.forEach(c => {
7984
const result = c.getParents().reduce((sum, p) => {
8085
if(p.isInitial()) return sum + 1;
8186
return sum;
8287
}, 0);
83-
return occursInInitialChunksMap.set(c, result);
88+
occursInInitialChunksMap.set(c, result);
89+
originalOrder.set(c, i++);
8490
});
8591

8692
const occurs = c => {
@@ -96,7 +102,9 @@ class OccurrenceOrderPlugin {
96102
const bOccurs = occurs(b);
97103
if(aOccurs > bOccurs) return -1;
98104
if(aOccurs < bOccurs) return 1;
99-
return a.compareTo(b);
105+
const orgA = originalOrder.get(a);
106+
const orgB = originalOrder.get(b);
107+
return orgB - orgA;
100108
});
101109
});
102110
});

schemas/WebpackOptions.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1507,6 +1507,10 @@
15071507
"type": "boolean",
15081508
"description": "add built modules information"
15091509
},
1510+
"nestedModules": {
1511+
"type": "boolean",
1512+
"description": "add information about modules nested in other modules (like with module concatenation)"
1513+
},
15101514
"children": {
15111515
"type": "boolean",
15121516
"description": "add children information"

test/Compiler.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ describe("Compiler", () => {
8484
Object.keys(files).should.be.eql(["/main.js"]);
8585
const bundle = files["/main.js"];
8686
bundle.should.containEql("function __webpack_require__(");
87-
bundle.should.containEql("__webpack_require__(/*! ./a */ 1);");
87+
bundle.should.containEql("__webpack_require__(/*! ./a */ 0);");
8888
bundle.should.containEql("./c.js");
8989
bundle.should.containEql("./a.js");
9090
bundle.should.containEql("This is a");

test/binCases/entry/named-entry/test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ module.exports = function testAssertions(code, stdout, stderr) {
66
stdout.should.be.ok();
77
stdout[4].should.containEql("null.js");
88
stdout[5].should.containEql("foo.js"); // named entry from --entry foo=./a.js
9-
stdout[6].should.match(/a\.js.*\{1\}/);
10-
stdout[7].should.match(/index\.js.*\{0\}/);
9+
stdout[6].should.match(/index\.js.*\{0\}/);
10+
stdout[7].should.match(/a\.js.*\{1\}/);
1111
stderr.should.be.empty();
1212
};
1313

test/configCases/code-generation/use-strict/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ it("should include only one use strict per module", function() {
1717

1818
matches.should.be.eql([
1919
"__webpack_require__.r(__webpack_exports__);",
20-
"it(\"should include only one use strict per module\", function() {",
20+
"/* unused harmony default export */ var _unused_webpack_default_export = (\"a\");",
2121
"__webpack_require__.r(__webpack_exports__);",
2222
"__webpack_require__.r(__webpack_exports__);",
2323
"__webpack_require__.r(__webpack_exports__);",
24-
"/* unused harmony default export */ var _unused_webpack_default_export = (\"a\");",
24+
"it(\"should include only one use strict per module\", function() {",
2525
]);
2626
});

test/configCases/records/issue-2991/test.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ it("should write relative paths to records", function() {
99
content.should.eql(`{
1010
"modules": {
1111
"byIdentifier": {
12-
"test.js": 0,
13-
"ignored pkgs/somepackage/foo": 1,
14-
"external \\"fs\\"": 2,
15-
"external \\"path\\"": 3
12+
"external \\"path\\"": 0,
13+
"external \\"fs\\"": 1,
14+
"ignored pkgs/somepackage/foo": 2,
15+
"test.js": 3
1616
},
1717
"usedIds": {
1818
"0": 0,
Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,51 @@
1-
Hash: a1332ffdc8f016e06e2da1332ffdc8f016e06e2d
1+
Hash: 0a5db84405553d6f7edc0a5db84405553d6f7edc
22
Child fitting:
3-
Hash: a1332ffdc8f016e06e2d
3+
Hash: 0a5db84405553d6f7edc
44
Time: Xms
55
Asset Size Chunks Chunk Names
66
8687608dde0469fd3fba.js 2.23 KiB 0 [emitted]
7-
76eb20f234cf58f9823b.js 1.93 KiB 4 [emitted]
8-
a1f333026966f9f4cd86.js 5.78 KiB 5 [emitted]
9-
3dad677280e44d774e7d.js 1 KiB 6 [emitted]
10-
Entrypoint main = a1f333026966f9f4cd86.js 3dad677280e44d774e7d.js 76eb20f234cf58f9823b.js 8687608dde0469fd3fba.js
7+
47e0fac01fc36a2064e8.js 5.78 KiB 4 [emitted]
8+
f1e5018e4333f2466ecc.js 1 KiB 5 [emitted]
9+
ddccfa0cc7de77007a74.js 1.93 KiB 6 [emitted]
10+
Entrypoint main = 47e0fac01fc36a2064e8.js f1e5018e4333f2466ecc.js ddccfa0cc7de77007a74.js 8687608dde0469fd3fba.js
1111
chunk {0} 8687608dde0469fd3fba.js 1.87 KiB [initial] [rendered]
1212
> aggressive-splitted main [4] ./index.js
1313
[4] ./index.js 112 bytes {0} [built]
1414
[6] ./f.js 899 bytes {0} [built]
1515
[7] ./g.js 899 bytes {0} [built]
16-
chunk {4} 76eb20f234cf58f9823b.js 1.76 KiB [initial] [rendered] [recorded]
16+
chunk {4} 47e0fac01fc36a2064e8.js 1.76 KiB [entry] [rendered] [recorded]
1717
> aggressive-splitted main [4] ./index.js
18-
[0] ./b.js 899 bytes {4} [built]
19-
[1] ./c.js 899 bytes {4} [built]
20-
chunk {5} a1f333026966f9f4cd86.js 1.76 KiB [entry] [rendered] [recorded]
18+
[2] ./d.js 899 bytes {4} [built]
19+
[5] ./a.js 899 bytes {4} [built]
20+
chunk {5} f1e5018e4333f2466ecc.js 899 bytes [initial] [rendered]
2121
> aggressive-splitted main [4] ./index.js
22-
[2] ./d.js 899 bytes {5} [built]
23-
[5] ./a.js 899 bytes {5} [built]
24-
chunk {6} 3dad677280e44d774e7d.js 899 bytes [initial] [rendered]
22+
[3] ./e.js 899 bytes {5} [built]
23+
chunk {6} ddccfa0cc7de77007a74.js 1.76 KiB [initial] [rendered] [recorded]
2524
> aggressive-splitted main [4] ./index.js
26-
[3] ./e.js 899 bytes {6} [built]
25+
[0] ./b.js 899 bytes {6} [built]
26+
[1] ./c.js 899 bytes {6} [built]
2727
Child content-change:
28-
Hash: a1332ffdc8f016e06e2d
28+
Hash: 0a5db84405553d6f7edc
2929
Time: Xms
3030
Asset Size Chunks Chunk Names
3131
8687608dde0469fd3fba.js 2.23 KiB 0 [emitted]
32-
76eb20f234cf58f9823b.js 1.93 KiB 4 [emitted]
33-
a1f333026966f9f4cd86.js 5.78 KiB 5 [emitted]
34-
3dad677280e44d774e7d.js 1 KiB 6 [emitted]
35-
Entrypoint main = a1f333026966f9f4cd86.js 3dad677280e44d774e7d.js 76eb20f234cf58f9823b.js 8687608dde0469fd3fba.js
32+
47e0fac01fc36a2064e8.js 5.78 KiB 4 [emitted]
33+
f1e5018e4333f2466ecc.js 1 KiB 5 [emitted]
34+
ddccfa0cc7de77007a74.js 1.93 KiB 6 [emitted]
35+
Entrypoint main = 47e0fac01fc36a2064e8.js f1e5018e4333f2466ecc.js ddccfa0cc7de77007a74.js 8687608dde0469fd3fba.js
3636
chunk {0} 8687608dde0469fd3fba.js 1.87 KiB [initial] [rendered]
3737
> aggressive-splitted main [4] ./index.js
3838
[4] ./index.js 112 bytes {0} [built]
3939
[6] ./f.js 899 bytes {0} [built]
4040
[7] ./g.js 899 bytes {0} [built]
41-
chunk {4} 76eb20f234cf58f9823b.js 1.76 KiB [initial] [rendered] [recorded]
41+
chunk {4} 47e0fac01fc36a2064e8.js 1.76 KiB [entry] [rendered] [recorded]
4242
> aggressive-splitted main [4] ./index.js
43-
[0] ./b.js 899 bytes {4} [built]
44-
[1] ./c.js 899 bytes {4} [built]
45-
chunk {5} a1f333026966f9f4cd86.js 1.76 KiB [entry] [rendered] [recorded]
43+
[2] ./d.js 899 bytes {4} [built]
44+
[5] ./a.js 899 bytes {4} [built]
45+
chunk {5} f1e5018e4333f2466ecc.js 899 bytes [initial] [rendered]
4646
> aggressive-splitted main [4] ./index.js
47-
[2] ./d.js 899 bytes {5} [built]
48-
[5] ./a.js 899 bytes {5} [built]
49-
chunk {6} 3dad677280e44d774e7d.js 899 bytes [initial] [rendered]
47+
[3] ./e.js 899 bytes {5} [built]
48+
chunk {6} ddccfa0cc7de77007a74.js 1.76 KiB [initial] [rendered] [recorded]
5049
> aggressive-splitted main [4] ./index.js
51-
[3] ./e.js 899 bytes {6} [built]
50+
[0] ./b.js 899 bytes {6} [built]
51+
[1] ./c.js 899 bytes {6} [built]
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
chunk {0} 0.js 21 bytes {3} [rendered]
2-
> async commons [1] ./index.js 2:1-5:3
3-
> async commons [1] ./index.js 9:1-13:3
4-
> async commons [1] ./index.js 17:1-21:3
2+
> async commons [3] ./index.js 2:1-5:3
3+
> async commons [3] ./index.js 9:1-13:3
4+
> async commons [3] ./index.js 17:1-21:3
55
[0] ./a.js 21 bytes {0} [built]
66
chunk {1} 1.js 21 bytes {3} [rendered]
7-
> [1] ./index.js 17:1-21:3
8-
[3] ./c.js 21 bytes {1} [built]
7+
> [3] ./index.js 9:1-13:3
8+
[1] ./b.js 21 bytes {1} [built]
99
chunk {2} 2.js 21 bytes {3} [rendered]
10-
> [1] ./index.js 9:1-13:3
11-
[2] ./b.js 21 bytes {2} [built]
10+
> [3] ./index.js 17:1-21:3
11+
[2] ./c.js 21 bytes {2} [built]
1212
chunk {3} entry.js (entry) 550 bytes [entry] [rendered]
13-
> entry [1] ./index.js
14-
[1] ./index.js 550 bytes {3} [built]
13+
> entry [3] ./index.js
14+
[3] ./index.js 550 bytes {3} [built]
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
chunk {0} 0.js 21 bytes {3} [rendered]
2-
> async commons [1] ./index.js 2:1-5:3
3-
> async commons [1] ./index.js 9:1-13:3
4-
> async commons [1] ./index.js 17:1-21:3
2+
> async commons [3] ./index.js 2:1-5:3
3+
> async commons [3] ./index.js 9:1-13:3
4+
> async commons [3] ./index.js 17:1-21:3
55
[0] ./a.js 21 bytes {0} [built]
66
chunk {1} 1.js 21 bytes {3} [rendered]
7-
> [1] ./index.js 17:1-21:3
8-
[3] ./c.js 21 bytes {1} [built]
7+
> [3] ./index.js 9:1-13:3
8+
[1] ./b.js 21 bytes {1} [built]
99
chunk {2} 2.js 21 bytes {3} [rendered]
10-
> [1] ./index.js 9:1-13:3
11-
[2] ./b.js 21 bytes {2} [built]
10+
> [3] ./index.js 17:1-21:3
11+
[2] ./c.js 21 bytes {2} [built]
1212
chunk {3} main.js (main) 550 bytes [entry] [rendered]
13-
> main [1] ./index.js
14-
[1] ./index.js 550 bytes {3} [built]
13+
> main [3] ./index.js
14+
[3] ./index.js 550 bytes {3} [built]

0 commit comments

Comments
 (0)