relative-module-resolver.js 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. /**
  2. * Utility for resolving a module relative to another module
  3. * @author Teddy Katz
  4. */
  5. "use strict";
  6. const Module = require("module");
  7. const path = require("path");
  8. // Polyfill Node's `Module.createRequire` if not present. We only support the case where the argument is a filepath, not a URL.
  9. const createRequire = (
  10. // Added in v12.2.0
  11. Module.createRequire ||
  12. // Added in v10.12.0, but deprecated in v12.2.0.
  13. Module.createRequireFromPath ||
  14. // Polyfill - This is not executed on the tests on node@>=10.
  15. /* istanbul ignore next */
  16. (filename => {
  17. const mod = new Module(filename, null);
  18. mod.filename = filename;
  19. mod.paths = Module._nodeModulePaths(path.dirname(filename)); // eslint-disable-line no-underscore-dangle
  20. mod._compile("module.exports = require;", filename); // eslint-disable-line no-underscore-dangle
  21. return mod.exports;
  22. })
  23. );
  24. module.exports = {
  25. /**
  26. * Resolves a Node module relative to another module
  27. * @param {string} moduleName The name of a Node module, or a path to a Node module.
  28. *
  29. * @param {string} relativeToPath An absolute path indicating the module that `moduleName` should be resolved relative to. This must be
  30. * a file rather than a directory, but the file need not actually exist.
  31. * @returns {string} The absolute path that would result from calling `require.resolve(moduleName)` in a file located at `relativeToPath`
  32. */
  33. resolve(moduleName, relativeToPath) {
  34. try {
  35. return createRequire(relativeToPath).resolve(moduleName);
  36. } catch (error) {
  37. if (
  38. typeof error === "object" &&
  39. error !== null &&
  40. error.code === "MODULE_NOT_FOUND" &&
  41. !error.requireStack &&
  42. error.message.includes(moduleName)
  43. ) {
  44. error.message += `\nRequire stack:\n- ${relativeToPath}`;
  45. }
  46. throw error;
  47. }
  48. }
  49. };