123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- /*
- 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) => {
- for (const item of b) {
- a.add(item);
- }
- };
- 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;
- let providedExportsAreTemporary;
- 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;
- return true;
- }
- // merge in new exports
- if (Array.isArray(exports)) {
- addToSet(moduleProvidedExports, exports);
- }
- // store dependencies
- const exportDeps = exportDesc.dependencies;
- if (exportDeps) {
- providedExportsAreTemporary = true;
- 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);
- }
- }
- };
- const notifyDependenciesIfDifferent = (set, array) => {
- const deps = dependencies.get(module);
- if (deps !== undefined) {
- if (set.size === array.length) {
- let i = 0;
- let different = false;
- for (const item of set) {
- if (item !== array[i++]) {
- different = true;
- break;
- }
- }
- if (!different) return;
- }
- for (const dep of deps) {
- queue.enqueue(dep);
- }
- }
- };
- // Start with all modules without provided exports
- for (const module of modules) {
- if (module.buildInfo.temporaryProvidedExports) {
- // Clear exports when they are temporary
- // and recreate them
- module.buildMeta.providedExports = null;
- queue.enqueue(module);
- } else 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 = new Set();
- providedExportsAreTemporary = false;
- processDependenciesBlock(module);
- module.buildInfo.temporaryProvidedExports = providedExportsAreTemporary;
- if (!moduleWithExports) {
- notifyDependencies();
- module.buildMeta.providedExports = true;
- } else if (module.buildMeta.providedExports === true) {
- notifyDependencies();
- } else if (!module.buildMeta.providedExports) {
- notifyDependencies();
- module.buildMeta.providedExports = Array.from(
- moduleProvidedExports
- );
- } else {
- notifyDependenciesIfDifferent(
- moduleProvidedExports,
- module.buildMeta.providedExports
- );
- 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;
|