Skip to content

Commit 1fae5ec

Browse files
committed
WIP5
1 parent 9eb5d6b commit 1fae5ec

File tree

22 files changed

+180
-67
lines changed

22 files changed

+180
-67
lines changed

lib/Chunk.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,9 @@ class Chunk {
186186
for(const module of Array.from(this._modules)) {
187187
module.removeChunk(this);
188188
}
189+
for(const chunkGroup of this._groups) {
190+
chunkGroup.removeChunk(this);
191+
}
189192
}
190193

191194
moveModule(module, otherChunk) {
@@ -208,9 +211,17 @@ class Chunk {
208211

209212
for(const chunkGroup of otherChunk._groups) {
210213
chunkGroup.replaceChunk(otherChunk, this);
214+
this.addGroup(chunkGroup);
211215
}
212216
otherChunk._groups.clear();
213217

218+
if(this.name && otherChunk.name) {
219+
if(this.name.length !== otherChunk.name)
220+
this.name = this.name.length < otherChunk.name.length ? this.name : otherChunk.name;
221+
else
222+
this.name = this.name < otherChunk.name ? this.name : otherChunk.name;
223+
}
224+
214225
return true;
215226
}
216227

@@ -219,6 +230,7 @@ class Chunk {
219230
chunkGroup.insertChunk(newChunk, this);
220231
newChunk.addGroup(chunkGroup);
221232
}
233+
console.log("Chunk.split", this.name, newChunk.name, Array.from(this._groups, g => g.chunks.map(c => c.name)));
222234
}
223235

224236
isEmpty() {

lib/ChunkGroup.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
const SortableSet = require("./util/SortableSet");
88
const compareLocations = require("./compareLocations");
99

10+
let debugId = 5000;
11+
1012
const getArray = set => Array.from(set);
1113

1214
const sortById = (a, b) => {
@@ -17,6 +19,7 @@ const sortById = (a, b) => {
1719

1820
class ChunkGroup {
1921
constructor(name) {
22+
this.groupDebugId = debugId++;
2023
this.name = name;
2124
this._children = new SortableSet(undefined, sortById);
2225
this._parents = new SortableSet(undefined, sortById);
@@ -88,6 +91,15 @@ class ChunkGroup {
8891
}
8992
}
9093

94+
removeChunk(chunk) {
95+
const idx = this.chunks.indexOf(chunk);
96+
if(idx >= 0) {
97+
this.chunks.splice(idx, 1);
98+
return true;
99+
}
100+
return false;
101+
}
102+
91103
isInitial() {
92104
return false;
93105
}

lib/Compilation.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ class Compilation extends Tapable {
219219
this.chunks = [];
220220
this.chunkGroups = [];
221221
this.namedChunkGroups = new Map();
222+
this.namedChunks = new Map();
222223
this.modules = [];
223224
this._modules = new Map();
224225
this.cache = null;
@@ -910,21 +911,29 @@ class Compilation extends Tapable {
910911
const chunkGroup = new ChunkGroup(name);
911912
if(module)
912913
chunkGroup.addOrigin(module, loc, request);
913-
const chunk = new Chunk(name);
914+
const chunk = this.addChunk(name);
914915

915916
GraphHelpers.connectChunkGroupAndChunk(chunkGroup, chunk);
916917

917-
this.chunks.push(chunk);
918918
this.chunkGroups.push(chunkGroup);
919919
if(name) {
920920
this.namedChunkGroups.set(name, chunkGroup);
921921
}
922922
return chunkGroup;
923923
}
924924

925-
addChunk() {
926-
const chunk = new Chunk();
925+
addChunk(name) {
926+
if(name) {
927+
const chunk = this.namedChunks.get(name);
928+
if(chunk !== undefined) {
929+
return chunk;
930+
}
931+
}
932+
const chunk = new Chunk(name);
927933
this.chunks.push(chunk);
934+
if(name) {
935+
this.namedChunks.set(name, chunk);
936+
}
928937
return chunk;
929938
}
930939

lib/HotModuleReplacementPlugin.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,14 @@ module.exports = class HotModuleReplacementPlugin {
161161
return Template.asString(buf);
162162
});
163163

164+
const needChunkLoadingCode = chunk => {
165+
for(const chunkGroup of chunk.groupsIterable) {
166+
if(chunkGroup.chunks.length > 0) return true;
167+
if(chunkGroup.getNumberOfChildren() > 0) return true;
168+
}
169+
return false;
170+
};
171+
164172
mainTemplate.hooks.bootstrap.tap("HotModuleReplacementPlugin", (source, chunk, hash) => {
165173
source = mainTemplate.hooks.hotBootstrap.call(source, chunk, hash);
166174
return Template.asString([
@@ -170,7 +178,7 @@ module.exports = class HotModuleReplacementPlugin {
170178
.replace(/\$require\$/g, mainTemplate.requireFn)
171179
.replace(/\$hash\$/g, JSON.stringify(hash))
172180
.replace(/\$requestTimeout\$/g, requestTimeout)
173-
.replace(/\/\*foreachInstalledChunks\*\//g, chunk.getNumberOfChunks() > 0 ? "for(var chunkId in installedChunks)" : `var chunkId = ${JSON.stringify(chunk.id)};`)
181+
.replace(/\/\*foreachInstalledChunks\*\//g, needChunkLoadingCode(chunk) ? "for(var chunkId in installedChunks)" : `var chunkId = ${JSON.stringify(chunk.id)};`)
174182
]);
175183
});
176184

lib/MainTemplate.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ module.exports = class MainTemplate extends Tapable {
4141
localVars: new SyncWaterfallHook(["source", "chunk", "hash"]),
4242
require: new SyncWaterfallHook(["source", "chunk", "hash"]),
4343
requireExtensions: new SyncWaterfallHook(["source", "chunk", "hash"]),
44+
beforeStartup: new SyncWaterfallHook(["source", "chunk", "hash"]),
4445
startup: new SyncWaterfallHook(["source", "chunk", "hash"]),
4546
render: new SyncWaterfallHook(["source", "chunk", "hash", "moduleTemplate", "dependencyTemplates"]),
4647
renderWithEntry: new SyncWaterfallHook(["source", "chunk", "hash"]),
@@ -252,6 +253,7 @@ module.exports = class MainTemplate extends Tapable {
252253
buf.push("");
253254
buf.push(Template.asString(this.hooks.requireExtensions.call("", chunk, hash)));
254255
buf.push("");
256+
buf.push(Template.asString(this.hooks.beforeStartup.call("", chunk, hash)));
255257
buf.push(Template.asString(this.hooks.startup.call("", chunk, hash)));
256258
let source = this.hooks.render.call(new OriginalSource(Template.prefix(buf, " \t") + "\n", "webpack/bootstrap"), chunk, hash, moduleTemplate, dependencyTemplates);
257259
if(chunk.hasEntryModule()) {

lib/RuntimeTemplate.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,6 @@ module.exports = class RuntimeTemplate {
254254
block,
255255
message
256256
}) {
257-
console.log("blockPromise", block.chunkGroup)
258257
if(!block || !block.chunkGroup || block.chunkGroup.chunks.length === 0) {
259258
const comment = this.comment({
260259
message

lib/Stats.js

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,25 @@ class Stats {
407407
};
408408
if(showChunks) {
409409
obj.chunks = compilation.chunks.map(chunk => {
410+
const parents = new Set();
411+
const children = new Set();
412+
const siblings = new Set();
413+
for(const chunkGroup of chunk.groupsIterable) {
414+
for(const parentGroup of chunkGroup.parentsIterable) {
415+
for(const chunk of parentGroup.chunks) {
416+
parents.add(chunk.id);
417+
}
418+
}
419+
for(const childGroup of chunkGroup.childrenIterable) {
420+
for(const chunk of childGroup.chunks) {
421+
children.add(chunk.id);
422+
}
423+
}
424+
for(const sibling of chunkGroup.chunks) {
425+
if(sibling !== chunk)
426+
siblings.add(sibling.id);
427+
}
428+
}
410429
const obj = {
411430
id: chunk.id,
412431
rendered: chunk.rendered,
@@ -418,19 +437,9 @@ class Stats {
418437
names: chunk.name ? [chunk.name] : [],
419438
files: chunk.files.slice(),
420439
hash: chunk.renderedHash,
421-
siblings: Array.from(chunk.groupsIterable, group => {
422-
return group.chunks.map(c => c.id);
423-
}),
424-
parents: Array.from(chunk.groupsIterable, group => {
425-
return Array.from(group.parentsIterable, parent => {
426-
return parent.chunks.map(c => c.id);
427-
});
428-
}),
429-
children: Array.from(chunk.groupsIterable, group => {
430-
return Array.from(group.childrenIterable, child => {
431-
return child.chunks.map(c => c.id);
432-
});
433-
})
440+
siblings: Array.from(siblings),
441+
parents: Array.from(parents),
442+
children: Array.from(children)
434443
};
435444
if(showChunkModules) {
436445
obj.modules = chunk
@@ -881,12 +890,20 @@ class Stats {
881890
}
882891
colors.normal(" ");
883892
colors.normal(SizeFormatHelpers.formatSize(chunk.size));
884-
chunk.parents.forEach(group => {
885-
group.forEach(parent => {
886-
colors.normal(" {");
887-
colors.yellow(parent.join("+"));
888-
colors.normal("}");
889-
});
893+
chunk.parents.forEach(id => {
894+
colors.normal(" <{");
895+
colors.yellow(id);
896+
colors.normal("}>");
897+
});
898+
chunk.siblings.forEach(id => {
899+
colors.normal(" ={");
900+
colors.yellow(id);
901+
colors.normal("}=");
902+
});
903+
chunk.children.forEach(id => {
904+
colors.normal(" >{");
905+
colors.yellow(id);
906+
colors.normal("}<");
890907
});
891908
if(chunk.entry) {
892909
colors.yellow(" [entry]");
@@ -903,11 +920,6 @@ class Stats {
903920
colors.yellow(` ${chunk.reason}`);
904921
}
905922
newline();
906-
for(const group of chunk.siblings) {
907-
colors.normal(" > ");
908-
colors.normal(`[${group.join(" + ")}]`);
909-
newline();
910-
}
911923
if(chunk.origins) {
912924
chunk.origins.forEach(origin => {
913925
colors.normal(" > ");

lib/WebpackOptionsApply.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ class WebpackOptionsApply extends OptionsApply {
293293
const names = chunks.map(c => c.name);
294294
if(!names.every(Boolean)) return;
295295
names.sort();
296-
return names.join("-");
296+
return names.join("~");
297297
};
298298
} else if(typeof value === "string") {
299299
return (module, chunks) => {

lib/optimize/AutomaticCommonsChunksPlugin.js

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,16 @@ module.exports = class AutomaticCommonsChunksPlugin {
7777
modules: new SortableSet(undefined, sortByIdentifier),
7878
enforce,
7979
name,
80-
chunks: new Set(),
80+
chunks: new Map(),
81+
reusedableChunks: new Set(),
8182
chunksKeys: new Set()
8283
});
8384
}
8485
info.modules.add(module);
8586
if(!info.chunksKeys.has(chunksKey)) {
8687
info.chunksKeys.add(chunksKey);
8788
for(const chunk of chunks) {
88-
info.chunks.add(chunk);
89+
info.chunks.set(chunk, chunk.getNumberOfModules());
8990
}
9091
}
9192
}
@@ -133,22 +134,36 @@ module.exports = class AutomaticCommonsChunksPlugin {
133134
let changed = false;
134135
// Walk though all entries
135136
for(const item of entries) {
136-
const chunkName = item.name;
137+
let chunkName = item.name;
137138
const enforced = item.enforce;
138139
// Variable for the new chunk (lazy created)
139140
let newChunk;
141+
// When not enforced, check if we can reuse a chunk instead of creating a new one
142+
let isReused = false;
143+
if(!enforced) {
144+
for(const pair of item.chunks) {
145+
if(pair[1] === item.modules.size) {
146+
const chunk = pair[0];
147+
if(!newChunk || !newChunk.name)
148+
newChunk = chunk;
149+
else if(chunk.name && chunk.name.length < newChunk.name.length)
150+
newChunk = chunk;
151+
else if(chunk.name && chunk.name.length === newChunk.name.length && chunk.name < newChunk.name)
152+
newChunk = chunk;
153+
chunkName = undefined;
154+
isReused = true;
155+
}
156+
}
157+
}
140158
// Walk through all chunks
141-
for(const chunk of item.chunks) {
159+
for(const chunk of item.chunks.keys()) {
142160
// skip if we address ourself
143-
if(chunk.name === chunkName) continue;
161+
if(chunk.name === chunkName || chunk === newChunk) continue;
144162
// respect max requests when not a named chunk
145163
if(!enforced && getRequests(chunk) >= this.options.maxRequests) continue;
146164
if(newChunk === undefined) {
147165
// Create the new chunk
148-
newChunk = compilation.addChunk();
149-
if(chunkName) {
150-
newChunk.name = chunkName;
151-
}
166+
newChunk = compilation.addChunk(chunkName);
152167
}
153168
// Add graph connections for splitted chunk
154169
chunk.split(newChunk);
@@ -159,7 +174,14 @@ module.exports = class AutomaticCommonsChunksPlugin {
159174
}
160175
}
161176
// If we successfully creates a new chunk
162-
if(newChunk) {
177+
if(isReused) {
178+
// Add a note to the chunk
179+
newChunk.chunkReason = "reused as commons chunk";
180+
if(chunkName) {
181+
newChunk.chunkReason += " " + chunkName;
182+
}
183+
changed = true;
184+
} else if(newChunk) {
163185
// Add a note to the chunk
164186
newChunk.chunkReason = enforced ? "vendors chunk" : "commons chunk";
165187
// If the choosen name is already an entry point we remove the entry point
@@ -168,6 +190,7 @@ module.exports = class AutomaticCommonsChunksPlugin {
168190
if(entrypoint) {
169191
compilation.entrypoints.delete(chunkName);
170192
entrypoint.remove();
193+
newChunk.entryModule = undefined;
171194
}
172195
newChunk.chunkReason += " " + chunkName;
173196
}

lib/web/JsonpChunkTemplatePlugin.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class JsonpChunkTemplatePlugin {
1616
source.add(modules);
1717
const entries = [chunk.entryModule]
1818
.filter(Boolean)
19-
.map(m => [m.id].concat(chunk.getEntrypoints()[0].chunks.map(c => c.id)));
19+
.map(m => [m.id].concat(Array.from(chunk.groupsIterable)[0].chunks.filter(c => c !== chunk).map(c => c.id)));
2020
if(entries.length > 0) {
2121
source.add(`,${JSON.stringify(entries)}`);
2222
}

0 commit comments

Comments
 (0)