MainFieldPlugin.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const path = require("path");
  7. const DescriptionFileUtils = require("./DescriptionFileUtils");
  8. /** @typedef {import("./Resolver")} Resolver */
  9. /** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
  10. /** @typedef {{name: string|Array<string>, forceRelative: boolean}} MainFieldOptions */
  11. const alreadyTriedMainField = Symbol("alreadyTriedMainField");
  12. module.exports = class MainFieldPlugin {
  13. /**
  14. * @param {string | ResolveStepHook} source source
  15. * @param {MainFieldOptions} options options
  16. * @param {string | ResolveStepHook} target target
  17. */
  18. constructor(source, options, target) {
  19. this.source = source;
  20. this.options = options;
  21. this.target = target;
  22. }
  23. /**
  24. * @param {Resolver} resolver the resolver
  25. * @returns {void}
  26. */
  27. apply(resolver) {
  28. const target = resolver.ensureHook(this.target);
  29. resolver
  30. .getHook(this.source)
  31. .tapAsync("MainFieldPlugin", (request, resolveContext, callback) => {
  32. if (
  33. request.path !== request.descriptionFileRoot ||
  34. request[alreadyTriedMainField] === request.descriptionFilePath ||
  35. !request.descriptionFilePath
  36. )
  37. return callback();
  38. const filename = path.basename(request.descriptionFilePath);
  39. let mainModule = DescriptionFileUtils.getField(
  40. request.descriptionFileData,
  41. this.options.name
  42. );
  43. if (
  44. !mainModule ||
  45. typeof mainModule !== "string" ||
  46. mainModule === "." ||
  47. mainModule === "./"
  48. ) {
  49. return callback();
  50. }
  51. if (this.options.forceRelative && !/^\.\.?\//.test(mainModule))
  52. mainModule = "./" + mainModule;
  53. const obj = {
  54. ...request,
  55. request: mainModule,
  56. module: false,
  57. directory: mainModule.endsWith("/"),
  58. [alreadyTriedMainField]: request.descriptionFilePath
  59. };
  60. return resolver.doResolve(
  61. target,
  62. obj,
  63. "use " +
  64. mainModule +
  65. " from " +
  66. this.options.name +
  67. " in " +
  68. filename,
  69. resolveContext,
  70. callback
  71. );
  72. });
  73. }
  74. };