From bbff7403fbf46f9ad92240ac213df8d30ef31b64 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Thu, 20 Sep 2018 02:56:13 +0200 Subject: update packages --- .../lib/optimize/RemoveParentModulesPlugin.js | 192 ++++++++++++++------- 1 file changed, 127 insertions(+), 65 deletions(-) (limited to 'node_modules/webpack/lib/optimize/RemoveParentModulesPlugin.js') diff --git a/node_modules/webpack/lib/optimize/RemoveParentModulesPlugin.js b/node_modules/webpack/lib/optimize/RemoveParentModulesPlugin.js index 43550819c..7fff59207 100644 --- a/node_modules/webpack/lib/optimize/RemoveParentModulesPlugin.js +++ b/node_modules/webpack/lib/optimize/RemoveParentModulesPlugin.js @@ -1,65 +1,127 @@ -/* - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra -*/ -"use strict"; - -function hasModule(chunk, module, checkedChunks) { - if(chunk.containsModule(module)) return [chunk]; - if(chunk.parents.length === 0) return false; - return allHaveModule(chunk.parents.filter((c) => { - return !checkedChunks.has(c); - }), module, checkedChunks); -} - -function allHaveModule(someChunks, module, checkedChunks) { - if(!checkedChunks) checkedChunks = new Set(); - var chunks = new Set(); - for(var i = 0; i < someChunks.length; i++) { - checkedChunks.add(someChunks[i]); - var subChunks = hasModule(someChunks[i], module, checkedChunks); - if(!subChunks) return false; - - for(var index = 0; index < subChunks.length; index++) { - var item = subChunks[index]; - - chunks.add(item); - } - } - return chunks; -} - -class RemoveParentModulesPlugin { - apply(compiler) { - compiler.plugin("compilation", (compilation) => { - compilation.plugin(["optimize-chunks-basic", "optimize-extracted-chunks-basic"], (chunks) => { - for(var index = 0; index < chunks.length; index++) { - var chunk = chunks[index]; - if(chunk.parents.length === 0) continue; - - // TODO consider Map when performance has improved https://gist.github.com/sokra/b36098368da7b8f6792fd7c85fca6311 - var cache = Object.create(null); - var modules = chunk.getModules(); - for(var i = 0; i < modules.length; i++) { - var module = modules[i]; - - var dId = module.getChunkIdsIdent(); - var parentChunksWithModule; - if(dId === null) { - parentChunksWithModule = allHaveModule(chunk.parents, module); - } else if(dId in cache) { - parentChunksWithModule = cache[dId]; - } else { - parentChunksWithModule = cache[dId] = allHaveModule(chunk.parents, module); - } - if(parentChunksWithModule) { - module.rewriteChunkInReasons(chunk, Array.from(parentChunksWithModule)); - chunk.removeModule(module); - } - } - } - }); - }); - } -} -module.exports = RemoveParentModulesPlugin; +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +"use strict"; + +const Queue = require("../util/Queue"); +const { intersect } = require("../util/SetHelpers"); + +const getParentChunksWithModule = (currentChunk, module) => { + const chunks = []; + const stack = new Set(currentChunk.parentsIterable); + + for (const chunk of stack) { + if (chunk.containsModule(module)) { + chunks.push(chunk); + } else { + for (const parent of chunk.parentsIterable) { + stack.add(parent); + } + } + } + + return chunks; +}; + +class RemoveParentModulesPlugin { + apply(compiler) { + compiler.hooks.compilation.tap("RemoveParentModulesPlugin", compilation => { + const handler = (chunks, chunkGroups) => { + const queue = new Queue(); + const availableModulesMap = new WeakMap(); + + for (const chunkGroup of compilation.entrypoints.values()) { + // initialize available modules for chunks without parents + availableModulesMap.set(chunkGroup, new Set()); + for (const child of chunkGroup.childrenIterable) { + queue.enqueue(child); + } + } + + while (queue.length > 0) { + const chunkGroup = queue.dequeue(); + let availableModules = availableModulesMap.get(chunkGroup); + let changed = false; + for (const parent of chunkGroup.parentsIterable) { + const availableModulesInParent = availableModulesMap.get(parent); + if (availableModulesInParent !== undefined) { + // If we know the available modules in parent: process these + if (availableModules === undefined) { + // if we have not own info yet: create new entry + availableModules = new Set(availableModulesInParent); + for (const chunk of parent.chunks) { + for (const m of chunk.modulesIterable) { + availableModules.add(m); + } + } + availableModulesMap.set(chunkGroup, availableModules); + changed = true; + } else { + for (const m of availableModules) { + if ( + !parent.containsModule(m) && + !availableModulesInParent.has(m) + ) { + availableModules.delete(m); + changed = true; + } + } + } + } + } + if (changed) { + // if something changed: enqueue our children + for (const child of chunkGroup.childrenIterable) { + queue.enqueue(child); + } + } + } + + // now we have available modules for every chunk + for (const chunk of chunks) { + const availableModulesSets = Array.from( + chunk.groupsIterable, + chunkGroup => availableModulesMap.get(chunkGroup) + ); + if (availableModulesSets.some(s => s === undefined)) continue; // No info about this chunk group + const availableModules = + availableModulesSets.length === 1 + ? availableModulesSets[0] + : intersect(availableModulesSets); + const numberOfModules = chunk.getNumberOfModules(); + const toRemove = new Set(); + if (numberOfModules < availableModules.size) { + for (const m of chunk.modulesIterable) { + if (availableModules.has(m)) { + toRemove.add(m); + } + } + } else { + for (const m of availableModules) { + if (chunk.containsModule(m)) { + toRemove.add(m); + } + } + } + for (const module of toRemove) { + module.rewriteChunkInReasons( + chunk, + getParentChunksWithModule(chunk, module) + ); + chunk.removeModule(module); + } + } + }; + compilation.hooks.optimizeChunksBasic.tap( + "RemoveParentModulesPlugin", + handler + ); + compilation.hooks.optimizeExtractedChunksBasic.tap( + "RemoveParentModulesPlugin", + handler + ); + }); + } +} +module.exports = RemoveParentModulesPlugin; -- cgit v1.2.3