IgnorePlugin.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const RawModule = require("./RawModule");
  7. const EntryDependency = require("./dependencies/EntryDependency");
  8. /**
  9. * @import {
  10. * IgnorePluginOptions
  11. * } from "../declarations/plugins/IgnorePlugin"
  12. */
  13. /** @import Compiler from "./Compiler" */
  14. /** @import { ResolveData } from "./NormalModuleFactory" */
  15. /** @import { BeforeContextResolveData } from "./ContextModuleFactory" */
  16. /** @typedef {(resource: string, context: string) => boolean} CheckResourceFn */
  17. const PLUGIN_NAME = "IgnorePlugin";
  18. class IgnorePlugin {
  19. /**
  20. * Creates an instance of IgnorePlugin.
  21. * @param {IgnorePluginOptions} options IgnorePlugin options
  22. */
  23. constructor(options) {
  24. /** @type {IgnorePluginOptions} */
  25. this.options = options;
  26. this.checkIgnore = this.checkIgnore.bind(this);
  27. }
  28. /**
  29. * Note that if "contextRegExp" is given, both the "resourceRegExp" and "contextRegExp" have to match.
  30. * @param {ResolveData | BeforeContextResolveData} resolveData resolve data
  31. * @returns {false | undefined} returns false when the request should be ignored, otherwise undefined
  32. */
  33. checkIgnore(resolveData) {
  34. if (
  35. "checkResource" in this.options &&
  36. this.options.checkResource &&
  37. this.options.checkResource(resolveData.request, resolveData.context)
  38. ) {
  39. return false;
  40. }
  41. if (
  42. "resourceRegExp" in this.options &&
  43. this.options.resourceRegExp &&
  44. this.options.resourceRegExp.test(resolveData.request)
  45. ) {
  46. if ("contextRegExp" in this.options && this.options.contextRegExp) {
  47. // if "contextRegExp" is given,
  48. // both the "resourceRegExp" and "contextRegExp" have to match.
  49. if (this.options.contextRegExp.test(resolveData.context)) {
  50. return false;
  51. }
  52. } else {
  53. return false;
  54. }
  55. }
  56. }
  57. /**
  58. * Applies the plugin by registering its hooks on the compiler.
  59. * @param {Compiler} compiler the compiler instance
  60. * @returns {void}
  61. */
  62. apply(compiler) {
  63. compiler.hooks.validate.tap(PLUGIN_NAME, () => {
  64. compiler.validate(
  65. /** @type {EXPECTED_ANY} */
  66. (require("../schemas/plugins/IgnorePlugin.json")),
  67. this.options,
  68. {
  69. name: "Ignore Plugin",
  70. baseDataPath: "options"
  71. },
  72. (options) => require("../schemas/plugins/IgnorePlugin.check")(options)
  73. );
  74. });
  75. compiler.hooks.normalModuleFactory.tap(PLUGIN_NAME, (nmf) => {
  76. nmf.hooks.beforeResolve.tap(PLUGIN_NAME, (resolveData) => {
  77. const result = this.checkIgnore(resolveData);
  78. if (
  79. result === false &&
  80. resolveData.dependencies.length > 0 &&
  81. resolveData.dependencies[0] instanceof EntryDependency
  82. ) {
  83. const module = new RawModule(
  84. "",
  85. "ignored-entry-module",
  86. "(ignored-entry-module)"
  87. );
  88. module.factoryMeta = { sideEffectFree: true };
  89. resolveData.ignoredModule = module;
  90. }
  91. return result;
  92. });
  93. });
  94. compiler.hooks.contextModuleFactory.tap(PLUGIN_NAME, (cmf) => {
  95. cmf.hooks.beforeResolve.tap(PLUGIN_NAME, this.checkIgnore);
  96. });
  97. }
  98. }
  99. module.exports = IgnorePlugin;