diff options
Diffstat (limited to 'node_modules/webpack/lib/FlagDependencyExportsPlugin.js')
| -rw-r--r-- | node_modules/webpack/lib/FlagDependencyExportsPlugin.js | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/node_modules/webpack/lib/FlagDependencyExportsPlugin.js b/node_modules/webpack/lib/FlagDependencyExportsPlugin.js new file mode 100644 index 00000000..0aafb0b4 --- /dev/null +++ b/node_modules/webpack/lib/FlagDependencyExportsPlugin.js @@ -0,0 +1,146 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +"use strict"; + +const Queue = require("./util/Queue"); + +const addToSet = (a, b) => { + let changed = false; + for (const item of b) { + if (!a.has(item)) { + a.add(item); + changed = true; + } + } + return changed; +}; + +class FlagDependencyExportsPlugin { + apply(compiler) { + compiler.hooks.compilation.tap( + "FlagDependencyExportsPlugin", + compilation => { + compilation.hooks.finishModules.tap( + "FlagDependencyExportsPlugin", + modules => { + const dependencies = new Map(); + + const queue = new Queue(); + + let module; + let moduleWithExports; + let moduleProvidedExports; + + const processDependenciesBlock = depBlock => { + for (const dep of depBlock.dependencies) { + if (processDependency(dep)) return true; + } + for (const variable of depBlock.variables) { + for (const dep of variable.dependencies) { + if (processDependency(dep)) return true; + } + } + for (const block of depBlock.blocks) { + if (processDependenciesBlock(block)) return true; + } + return false; + }; + + const processDependency = dep => { + const exportDesc = dep.getExports && dep.getExports(); + if (!exportDesc) return; + moduleWithExports = true; + const exports = exportDesc.exports; + // break early if it's only in the worst state + if (module.buildMeta.providedExports === true) { + return true; + } + // break if it should move to the worst state + if (exports === true) { + module.buildMeta.providedExports = true; + notifyDependencies(); + return true; + } + // merge in new exports + if (Array.isArray(exports)) { + if (addToSet(moduleProvidedExports, exports)) { + notifyDependencies(); + } + } + // store dependencies + const exportDeps = exportDesc.dependencies; + if (exportDeps) { + for (const exportDependency of exportDeps) { + // add dependency for this module + const set = dependencies.get(exportDependency); + if (set === undefined) { + dependencies.set(exportDependency, new Set([module])); + } else { + set.add(module); + } + } + } + return false; + }; + + const notifyDependencies = () => { + const deps = dependencies.get(module); + if (deps !== undefined) { + for (const dep of deps) { + queue.enqueue(dep); + } + } + }; + + // Start with all modules without provided exports + for (const module of modules) { + if (!module.buildMeta.providedExports) { + queue.enqueue(module); + } + } + + while (queue.length > 0) { + module = queue.dequeue(); + + if (module.buildMeta.providedExports !== true) { + moduleWithExports = + module.buildMeta && module.buildMeta.exportsType; + moduleProvidedExports = Array.isArray( + module.buildMeta.providedExports + ) + ? new Set(module.buildMeta.providedExports) + : new Set(); + processDependenciesBlock(module); + if (!moduleWithExports) { + module.buildMeta.providedExports = true; + notifyDependencies(); + } else if (module.buildMeta.providedExports !== true) { + module.buildMeta.providedExports = Array.from( + moduleProvidedExports + ); + } + } + } + } + ); + const providedExportsCache = new WeakMap(); + compilation.hooks.rebuildModule.tap( + "FlagDependencyExportsPlugin", + module => { + providedExportsCache.set(module, module.buildMeta.providedExports); + } + ); + compilation.hooks.finishRebuildingModule.tap( + "FlagDependencyExportsPlugin", + module => { + module.buildMeta.providedExports = providedExportsCache.get(module); + } + ); + } + ); + } +} + +module.exports = FlagDependencyExportsPlugin; |
