IgnorePlugin.js 3.0 KB

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