ParsePlugin.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. /** @typedef {import("./Resolver")} Resolver */
  7. /** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
  8. /** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
  9. module.exports = class ParsePlugin {
  10. /**
  11. * @param {string | ResolveStepHook} source source
  12. * @param {Partial<ResolveRequest>} requestOptions request options
  13. * @param {string | ResolveStepHook} target target
  14. */
  15. constructor(source, requestOptions, target) {
  16. this.source = source;
  17. this.requestOptions = requestOptions;
  18. this.target = target;
  19. }
  20. /**
  21. * @param {Resolver} resolver the resolver
  22. * @returns {void}
  23. */
  24. apply(resolver) {
  25. const target = resolver.ensureHook(this.target);
  26. resolver
  27. .getHook(this.source)
  28. .tapAsync("ParsePlugin", (request, resolveContext, callback) => {
  29. const parsed = resolver.parse(/** @type {string} */ (request.request));
  30. /** @type {ResolveRequest} */
  31. const obj = { ...request, ...parsed, ...this.requestOptions };
  32. if (request.query && !parsed.query) {
  33. obj.query = request.query;
  34. }
  35. if (request.fragment && !parsed.fragment) {
  36. obj.fragment = request.fragment;
  37. }
  38. if (parsed && resolveContext.log) {
  39. if (parsed.module) resolveContext.log("Parsed request is a module");
  40. if (parsed.directory)
  41. resolveContext.log("Parsed request is a directory");
  42. }
  43. // There is an edge-case where a request with # can be a path or a fragment -> try both
  44. if (obj.request && !obj.query && obj.fragment) {
  45. const directory = obj.fragment.endsWith("/");
  46. /** @type {ResolveRequest} */
  47. const alternative = {
  48. ...obj,
  49. directory,
  50. request:
  51. obj.request +
  52. (obj.directory ? "/" : "") +
  53. (directory ? obj.fragment.slice(0, -1) : obj.fragment),
  54. fragment: ""
  55. };
  56. resolver.doResolve(
  57. target,
  58. alternative,
  59. null,
  60. resolveContext,
  61. (err, result) => {
  62. if (err) return callback(err);
  63. if (result) return callback(null, result);
  64. resolver.doResolve(target, obj, null, resolveContext, callback);
  65. }
  66. );
  67. return;
  68. }
  69. resolver.doResolve(target, obj, null, resolveContext, callback);
  70. });
  71. }
  72. };