ModulesInHierarchicalDirectoriesPlugin.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const forEachBail = require("./forEachBail");
  7. const getPaths = require("./getPaths");
  8. /** @typedef {import("./Resolver")} Resolver */
  9. /** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
  10. /** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
  11. module.exports = class ModulesInHierarchicalDirectoriesPlugin {
  12. /**
  13. * @param {string | ResolveStepHook} source source
  14. * @param {string | Array<string>} directories directories
  15. * @param {string | ResolveStepHook} target target
  16. */
  17. constructor(source, directories, target) {
  18. this.source = source;
  19. this.directories = /** @type {Array<string>} */ [...directories];
  20. this.target = target;
  21. }
  22. /**
  23. * @param {Resolver} resolver the resolver
  24. * @returns {void}
  25. */
  26. apply(resolver) {
  27. const target = resolver.ensureHook(this.target);
  28. resolver
  29. .getHook(this.source)
  30. .tapAsync(
  31. "ModulesInHierarchicalDirectoriesPlugin",
  32. (request, resolveContext, callback) => {
  33. const fs = resolver.fileSystem;
  34. const addrs = getPaths(/** @type {string} */ (request.path))
  35. .paths.map((path) =>
  36. this.directories.map((directory) =>
  37. resolver.join(path, directory),
  38. ),
  39. )
  40. .reduce((array, path) => {
  41. array.push(...path);
  42. return array;
  43. }, []);
  44. forEachBail(
  45. addrs,
  46. /**
  47. * @param {string} addr addr
  48. * @param {(err?: null|Error, result?: null|ResolveRequest) => void} callback callback
  49. * @returns {void}
  50. */
  51. (addr, callback) => {
  52. fs.stat(addr, (err, stat) => {
  53. if (!err && stat && stat.isDirectory()) {
  54. /** @type {ResolveRequest} */
  55. const obj = {
  56. ...request,
  57. path: addr,
  58. request: `./${request.request}`,
  59. module: false,
  60. };
  61. const message = `looking for modules in ${addr}`;
  62. return resolver.doResolve(
  63. target,
  64. obj,
  65. message,
  66. resolveContext,
  67. callback,
  68. );
  69. }
  70. if (resolveContext.log) {
  71. resolveContext.log(
  72. `${addr} doesn't exist or is not a directory`,
  73. );
  74. }
  75. if (resolveContext.missingDependencies) {
  76. resolveContext.missingDependencies.add(addr);
  77. }
  78. return callback();
  79. });
  80. },
  81. callback,
  82. );
  83. },
  84. );
  85. }
  86. };