resolveMatchedConfigs.js 3.2 KB

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