resolveMatchedConfigs.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const ModuleNotFoundError = require("../ModuleNotFoundError");
  7. const LazySet = require("../util/LazySet");
  8. /** @typedef {import("enhanced-resolve").ResolveContext} ResolveContext */
  9. /** @typedef {import("../Compilation")} Compilation */
  10. /** @typedef {import("../Compilation").FileSystemDependencies} FileSystemDependencies */
  11. /** @typedef {import("../ResolverFactory").ResolveOptionsWithDependencyType} ResolveOptionsWithDependencyType */
  12. /**
  13. * Defines the matched configs item type used by this module.
  14. * @template T
  15. * @typedef {Map<string, T>} MatchedConfigsItem
  16. */
  17. /**
  18. * Defines the matched configs type used by this module.
  19. * @template T
  20. * @typedef {object} MatchedConfigs
  21. * @property {MatchedConfigsItem<T>} resolved
  22. * @property {MatchedConfigsItem<T>} unresolved
  23. * @property {MatchedConfigsItem<T>} prefixed
  24. */
  25. /** @type {ResolveOptionsWithDependencyType} */
  26. const RESOLVE_OPTIONS = { dependencyType: "esm" };
  27. /**
  28. * Returns resolved matchers.
  29. * @template T
  30. * @param {Compilation} compilation the compilation
  31. * @param {[string, T][]} configs to be processed configs
  32. * @returns {Promise<MatchedConfigs<T>>} resolved matchers
  33. */
  34. module.exports.resolveMatchedConfigs = (compilation, configs) => {
  35. /** @type {MatchedConfigsItem<T>} */
  36. const resolved = new Map();
  37. /** @type {MatchedConfigsItem<T>} */
  38. const unresolved = new Map();
  39. /** @type {MatchedConfigsItem<T>} */
  40. const prefixed = new Map();
  41. /** @type {ResolveContext} */
  42. const resolveContext = {
  43. fileDependencies: new LazySet(),
  44. contextDependencies: new LazySet(),
  45. missingDependencies: new LazySet()
  46. };
  47. const resolver = compilation.resolverFactory.get("normal", RESOLVE_OPTIONS);
  48. const context = compilation.compiler.context;
  49. return Promise.all(
  50. // eslint-disable-next-line array-callback-return
  51. configs.map(([request, config]) => {
  52. if (/^\.\.?(?:\/|$)/.test(request)) {
  53. // relative request
  54. return new Promise((resolve) => {
  55. resolver.resolve(
  56. {},
  57. context,
  58. request,
  59. resolveContext,
  60. (err, result) => {
  61. if (err || result === false) {
  62. err = err || new Error(`Can't resolve ${request}`);
  63. compilation.errors.push(
  64. new ModuleNotFoundError(null, err, {
  65. name: `shared module ${request}`
  66. })
  67. );
  68. return resolve(null);
  69. }
  70. resolved.set(/** @type {string} */ (result), config);
  71. resolve(null);
  72. }
  73. );
  74. });
  75. } else if (/^(?:\/|[a-z]:\\|\\\\)/i.test(request)) {
  76. // absolute path
  77. resolved.set(request, config);
  78. } else if (request.endsWith("/")) {
  79. // module request prefix
  80. prefixed.set(request, config);
  81. } else {
  82. // module request
  83. unresolved.set(request, config);
  84. }
  85. })
  86. ).then(() => {
  87. compilation.contextDependencies.addAll(
  88. /** @type {FileSystemDependencies} */
  89. (resolveContext.contextDependencies)
  90. );
  91. compilation.fileDependencies.addAll(
  92. /** @type {FileSystemDependencies} */
  93. (resolveContext.fileDependencies)
  94. );
  95. compilation.missingDependencies.addAll(
  96. /** @type {FileSystemDependencies} */
  97. (resolveContext.missingDependencies)
  98. );
  99. return { resolved, unresolved, prefixed };
  100. });
  101. };