ContextReplacementPlugin.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const path = require("path");
  7. const ContextElementDependency = require("./dependencies/ContextElementDependency");
  8. class ContextReplacementPlugin {
  9. constructor(
  10. resourceRegExp,
  11. newContentResource,
  12. newContentRecursive,
  13. newContentRegExp
  14. ) {
  15. this.resourceRegExp = resourceRegExp;
  16. if (typeof newContentResource === "function") {
  17. this.newContentCallback = newContentResource;
  18. } else if (
  19. typeof newContentResource === "string" &&
  20. typeof newContentRecursive === "object"
  21. ) {
  22. this.newContentResource = newContentResource;
  23. this.newContentCreateContextMap = (fs, callback) => {
  24. callback(null, newContentRecursive);
  25. };
  26. } else if (
  27. typeof newContentResource === "string" &&
  28. typeof newContentRecursive === "function"
  29. ) {
  30. this.newContentResource = newContentResource;
  31. this.newContentCreateContextMap = newContentRecursive;
  32. } else {
  33. if (typeof newContentResource !== "string") {
  34. newContentRegExp = newContentRecursive;
  35. newContentRecursive = newContentResource;
  36. newContentResource = undefined;
  37. }
  38. if (typeof newContentRecursive !== "boolean") {
  39. newContentRegExp = newContentRecursive;
  40. newContentRecursive = undefined;
  41. }
  42. this.newContentResource = newContentResource;
  43. this.newContentRecursive = newContentRecursive;
  44. this.newContentRegExp = newContentRegExp;
  45. }
  46. }
  47. apply(compiler) {
  48. const resourceRegExp = this.resourceRegExp;
  49. const newContentCallback = this.newContentCallback;
  50. const newContentResource = this.newContentResource;
  51. const newContentRecursive = this.newContentRecursive;
  52. const newContentRegExp = this.newContentRegExp;
  53. const newContentCreateContextMap = this.newContentCreateContextMap;
  54. compiler.hooks.contextModuleFactory.tap("ContextReplacementPlugin", cmf => {
  55. cmf.hooks.beforeResolve.tap("ContextReplacementPlugin", result => {
  56. if (!result) return;
  57. if (resourceRegExp.test(result.request)) {
  58. if (newContentResource !== undefined) {
  59. result.request = newContentResource;
  60. }
  61. if (newContentRecursive !== undefined) {
  62. result.recursive = newContentRecursive;
  63. }
  64. if (newContentRegExp !== undefined) {
  65. result.regExp = newContentRegExp;
  66. }
  67. if (typeof newContentCallback === "function") {
  68. newContentCallback(result);
  69. } else {
  70. for (const d of result.dependencies) {
  71. if (d.critical) d.critical = false;
  72. }
  73. }
  74. }
  75. return result;
  76. });
  77. cmf.hooks.afterResolve.tap("ContextReplacementPlugin", result => {
  78. if (!result) return;
  79. if (resourceRegExp.test(result.resource)) {
  80. if (newContentResource !== undefined) {
  81. result.resource = path.resolve(result.resource, newContentResource);
  82. }
  83. if (newContentRecursive !== undefined) {
  84. result.recursive = newContentRecursive;
  85. }
  86. if (newContentRegExp !== undefined) {
  87. result.regExp = newContentRegExp;
  88. }
  89. if (typeof newContentCreateContextMap === "function") {
  90. result.resolveDependencies = createResolveDependenciesFromContextMap(
  91. newContentCreateContextMap
  92. );
  93. }
  94. if (typeof newContentCallback === "function") {
  95. const origResource = result.resource;
  96. newContentCallback(result);
  97. if (result.resource !== origResource) {
  98. result.resource = path.resolve(origResource, result.resource);
  99. }
  100. } else {
  101. for (const d of result.dependencies) {
  102. if (d.critical) d.critical = false;
  103. }
  104. }
  105. }
  106. return result;
  107. });
  108. });
  109. }
  110. }
  111. const createResolveDependenciesFromContextMap = createContextMap => {
  112. const resolveDependenciesFromContextMap = (fs, options, callback) => {
  113. createContextMap(fs, (err, map) => {
  114. if (err) return callback(err);
  115. const dependencies = Object.keys(map).map(key => {
  116. return new ContextElementDependency(
  117. map[key] + options.resourceQuery,
  118. key
  119. );
  120. });
  121. callback(null, dependencies);
  122. });
  123. };
  124. return resolveDependenciesFromContextMap;
  125. };
  126. module.exports = ContextReplacementPlugin;