NormalModuleReplacementPlugin.js 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const { join, dirname } = require("./util/fs");
  7. /** @typedef {import("./Compiler")} Compiler */
  8. /** @typedef {import("./NormalModuleFactory").ResolveData} ResolveData */
  9. /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
  10. /** @typedef {(resolveData: ResolveData) => void} ModuleReplacer */
  11. const PLUGIN_NAME = "NormalModuleReplacementPlugin";
  12. class NormalModuleReplacementPlugin {
  13. /**
  14. * Create an instance of the plugin
  15. * @param {RegExp} resourceRegExp the resource matcher
  16. * @param {string | ModuleReplacer} newResource the resource replacement
  17. */
  18. constructor(resourceRegExp, newResource) {
  19. this.resourceRegExp = resourceRegExp;
  20. this.newResource = newResource;
  21. }
  22. /**
  23. * Apply the plugin
  24. * @param {Compiler} compiler the compiler instance
  25. * @returns {void}
  26. */
  27. apply(compiler) {
  28. const resourceRegExp = this.resourceRegExp;
  29. const newResource = this.newResource;
  30. compiler.hooks.normalModuleFactory.tap(PLUGIN_NAME, nmf => {
  31. nmf.hooks.beforeResolve.tap(PLUGIN_NAME, result => {
  32. if (resourceRegExp.test(result.request)) {
  33. if (typeof newResource === "function") {
  34. newResource(result);
  35. } else {
  36. result.request = newResource;
  37. }
  38. }
  39. });
  40. nmf.hooks.afterResolve.tap(PLUGIN_NAME, result => {
  41. const createData = result.createData;
  42. if (resourceRegExp.test(/** @type {string} */ (createData.resource))) {
  43. if (typeof newResource === "function") {
  44. newResource(result);
  45. } else {
  46. const fs =
  47. /** @type {InputFileSystem} */
  48. (compiler.inputFileSystem);
  49. if (
  50. newResource.startsWith("/") ||
  51. (newResource.length > 1 && newResource[1] === ":")
  52. ) {
  53. createData.resource = newResource;
  54. } else {
  55. createData.resource = join(
  56. fs,
  57. dirname(fs, /** @type {string} */ (createData.resource)),
  58. newResource
  59. );
  60. }
  61. }
  62. }
  63. });
  64. });
  65. }
  66. }
  67. module.exports = NormalModuleReplacementPlugin;