FlagDependencyUsagePlugin.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. class FlagDependencyUsagePlugin {
  7. apply(compiler) {
  8. compiler.plugin("compilation", compilation => {
  9. compilation.plugin("optimize-modules-advanced", modules => {
  10. modules.forEach(module => module.used = false);
  11. const queue = [];
  12. compilation.chunks.forEach(chunk => {
  13. if(chunk.entryModule) {
  14. processModule(chunk.entryModule, true);
  15. }
  16. });
  17. while(queue.length) {
  18. const queueItem = queue.pop();
  19. processDependenciesBlock(queueItem[0], queueItem[1]);
  20. }
  21. function processModule(module, usedExports) {
  22. module.used = true;
  23. if(module.usedExports === true)
  24. return;
  25. else if(usedExports === true)
  26. module.usedExports = true;
  27. else if(Array.isArray(usedExports)) {
  28. var old = module.usedExports ? module.usedExports.length : -1;
  29. module.usedExports = addToSet(module.usedExports || [], usedExports);
  30. if(module.usedExports.length === old)
  31. return;
  32. } else if(Array.isArray(module.usedExports))
  33. return;
  34. else
  35. module.usedExports = false;
  36. queue.push([module, module.usedExports]);
  37. }
  38. function processDependenciesBlock(depBlock, usedExports) {
  39. depBlock.dependencies.forEach(dep => processDependency(dep));
  40. depBlock.variables.forEach(variable => variable.dependencies.forEach(dep => processDependency(dep)));
  41. depBlock.blocks.forEach(block => queue.push([block, usedExports]));
  42. }
  43. function processDependency(dep) {
  44. const reference = dep.getReference && dep.getReference();
  45. if(!reference) return;
  46. const module = reference.module;
  47. const importedNames = reference.importedNames;
  48. const oldUsed = module.used;
  49. const oldUsedExports = module.usedExports;
  50. if(!oldUsed || (importedNames && (!oldUsedExports || !isSubset(oldUsedExports, importedNames)))) {
  51. processModule(module, importedNames);
  52. }
  53. }
  54. });
  55. function addToSet(a, b) {
  56. b.forEach(item => {
  57. if(a.indexOf(item) < 0)
  58. a.push(item);
  59. });
  60. return a;
  61. }
  62. function isSubset(biggerSet, subset) {
  63. if(biggerSet === true) return true;
  64. if(subset === true) return false;
  65. return subset.every(item => biggerSet.indexOf(item) >= 0);
  66. }
  67. });
  68. }
  69. }
  70. module.exports = FlagDependencyUsagePlugin;