AliasFieldPlugin.js 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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 data1 = fieldData[innerRequest];
  48. const data2 = fieldData[innerRequest.replace(/^\.\//, "")];
  49. const data = typeof data1 !== "undefined" ? data1 : data2;
  50. if (data === innerRequest) return callback();
  51. if (data === undefined) return callback();
  52. if (data === false) {
  53. /** @type {ResolveRequest} */
  54. const ignoreObj = {
  55. ...request,
  56. path: false
  57. };
  58. return callback(null, ignoreObj);
  59. }
  60. const obj = {
  61. ...request,
  62. path: request.descriptionFileRoot,
  63. request: data,
  64. fullySpecified: false
  65. };
  66. resolver.doResolve(
  67. target,
  68. obj,
  69. "aliased from description file " +
  70. request.descriptionFilePath +
  71. " with mapping '" +
  72. innerRequest +
  73. "' to '" +
  74. data +
  75. "'",
  76. resolveContext,
  77. (err, result) => {
  78. if (err) return callback(err);
  79. // Don't allow other aliasing or raw request
  80. if (result === undefined) return callback(null, null);
  81. callback(null, result);
  82. }
  83. );
  84. });
  85. }
  86. };