AliasFieldPlugin.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const DescriptionFileUtils = require("./DescriptionFileUtils");
  7. const getInnerRequest = require("./getInnerRequest");
  8. /** @typedef {import("./Resolver")} Resolver */
  9. /** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
  10. /** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
  11. module.exports = class AliasFieldPlugin {
  12. /**
  13. * @param {string | ResolveStepHook} source source
  14. * @param {string | Array<string>} field field
  15. * @param {string | ResolveStepHook} target target
  16. */
  17. constructor(source, field, target) {
  18. this.source = source;
  19. this.field = field;
  20. this.target = target;
  21. }
  22. /**
  23. * @param {Resolver} resolver the resolver
  24. * @returns {void}
  25. */
  26. apply(resolver) {
  27. const target = resolver.ensureHook(this.target);
  28. resolver
  29. .getHook(this.source)
  30. .tapAsync("AliasFieldPlugin", (request, resolveContext, callback) => {
  31. if (!request.descriptionFileData) return callback();
  32. const innerRequest = getInnerRequest(resolver, request);
  33. if (!innerRequest) return callback();
  34. const fieldData = DescriptionFileUtils.getField(
  35. request.descriptionFileData,
  36. this.field
  37. );
  38. if (fieldData === null || typeof fieldData !== "object") {
  39. if (resolveContext.log)
  40. resolveContext.log(
  41. "Field '" +
  42. this.field +
  43. "' doesn't contain a valid alias configuration"
  44. );
  45. return callback();
  46. }
  47. const data = Object.prototype.hasOwnProperty.call(
  48. fieldData,
  49. innerRequest
  50. )
  51. ? fieldData[innerRequest]
  52. : innerRequest.startsWith("./")
  53. ? fieldData[innerRequest.slice(2)]
  54. : undefined;
  55. if (data === innerRequest) return callback();
  56. if (data === undefined) return callback();
  57. if (data === false) {
  58. /** @type {ResolveRequest} */
  59. const ignoreObj = {
  60. ...request,
  61. path: false
  62. };
  63. if (typeof resolveContext.yield === "function") {
  64. resolveContext.yield(ignoreObj);
  65. return callback(null, null);
  66. }
  67. return callback(null, ignoreObj);
  68. }
  69. const obj = {
  70. ...request,
  71. path: request.descriptionFileRoot,
  72. request: data,
  73. fullySpecified: false
  74. };
  75. resolver.doResolve(
  76. target,
  77. obj,
  78. "aliased from description file " +
  79. request.descriptionFilePath +
  80. " with mapping '" +
  81. innerRequest +
  82. "' to '" +
  83. data +
  84. "'",
  85. resolveContext,
  86. (err, result) => {
  87. if (err) return callback(err);
  88. // Don't allow other aliasing or raw request
  89. if (result === undefined) return callback(null, null);
  90. callback(null, result);
  91. }
  92. );
  93. });
  94. }
  95. };