ParsePlugin.js 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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. }
  44. // There is an edge-case where a request with # can be a path or a fragment -> try both
  45. if (obj.request && !obj.query && obj.fragment) {
  46. const directory = obj.fragment.endsWith("/");
  47. /** @type {ResolveRequest} */
  48. const alternative = {
  49. ...obj,
  50. directory,
  51. request:
  52. obj.request +
  53. (obj.directory ? "/" : "") +
  54. (directory ? obj.fragment.slice(0, -1) : obj.fragment),
  55. fragment: "",
  56. };
  57. resolver.doResolve(
  58. target,
  59. alternative,
  60. null,
  61. resolveContext,
  62. (err, result) => {
  63. if (err) return callback(err);
  64. if (result) return callback(null, result);
  65. resolver.doResolve(target, obj, null, resolveContext, callback);
  66. },
  67. );
  68. return;
  69. }
  70. resolver.doResolve(target, obj, null, resolveContext, callback);
  71. });
  72. }
  73. };