resolveMatchedConfigs.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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. * @template T
  14. * @typedef {Map<string, T>} MatchedConfigsItem
  15. */
  16. /**
  17. * @template T
  18. * @typedef {object} MatchedConfigs
  19. * @property {MatchedConfigsItem<T>} resolved
  20. * @property {MatchedConfigsItem<T>} unresolved
  21. * @property {MatchedConfigsItem<T>} prefixed
  22. */
  23. /** @type {ResolveOptionsWithDependencyType} */
  24. const RESOLVE_OPTIONS = { dependencyType: "esm" };
  25. /**
  26. * @template T
  27. * @param {Compilation} compilation the compilation
  28. * @param {[string, T][]} configs to be processed configs
  29. * @returns {Promise<MatchedConfigs<T>>} resolved matchers
  30. */
  31. module.exports.resolveMatchedConfigs = (compilation, configs) => {
  32. /** @type {MatchedConfigsItem<T>} */
  33. const resolved = new Map();
  34. /** @type {MatchedConfigsItem<T>} */
  35. const unresolved = new Map();
  36. /** @type {MatchedConfigsItem<T>} */
  37. const prefixed = new Map();
  38. /** @type {ResolveContext} */
  39. const resolveContext = {
  40. fileDependencies: new LazySet(),
  41. contextDependencies: new LazySet(),
  42. missingDependencies: new LazySet()
  43. };
  44. const resolver = compilation.resolverFactory.get("normal", RESOLVE_OPTIONS);
  45. const context = compilation.compiler.context;
  46. return Promise.all(
  47. // eslint-disable-next-line array-callback-return
  48. configs.map(([request, config]) => {
  49. if (/^\.\.?(\/|$)/.test(request)) {
  50. // relative request
  51. return new Promise((resolve) => {
  52. resolver.resolve(
  53. {},
  54. context,
  55. request,
  56. resolveContext,
  57. (err, result) => {
  58. if (err || result === false) {
  59. err = err || new Error(`Can't resolve ${request}`);
  60. compilation.errors.push(
  61. new ModuleNotFoundError(null, err, {
  62. name: `shared module ${request}`
  63. })
  64. );
  65. return resolve(null);
  66. }
  67. resolved.set(/** @type {string} */ (result), config);
  68. resolve(null);
  69. }
  70. );
  71. });
  72. } else if (/^(\/|[A-Za-z]:\\|\\\\)/.test(request)) {
  73. // absolute path
  74. resolved.set(request, config);
  75. } else if (request.endsWith("/")) {
  76. // module request prefix
  77. prefixed.set(request, config);
  78. } else {
  79. // module request
  80. unresolved.set(request, config);
  81. }
  82. })
  83. ).then(() => {
  84. compilation.contextDependencies.addAll(
  85. /** @type {FileSystemDependencies} */
  86. (resolveContext.contextDependencies)
  87. );
  88. compilation.fileDependencies.addAll(
  89. /** @type {FileSystemDependencies} */
  90. (resolveContext.fileDependencies)
  91. );
  92. compilation.missingDependencies.addAll(
  93. /** @type {FileSystemDependencies} */
  94. (resolveContext.missingDependencies)
  95. );
  96. return { resolved, unresolved, prefixed };
  97. });
  98. };