ResolverFactory.js 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const { Tapable, HookMap, SyncHook, SyncWaterfallHook } = require("tapable");
  7. const Factory = require("enhanced-resolve").ResolverFactory;
  8. module.exports = class ResolverFactory extends Tapable {
  9. constructor() {
  10. super();
  11. this.hooks = {
  12. resolveOptions: new HookMap(
  13. () => new SyncWaterfallHook(["resolveOptions"])
  14. ),
  15. resolver: new HookMap(() => new SyncHook(["resolver", "resolveOptions"]))
  16. };
  17. this._pluginCompat.tap("ResolverFactory", options => {
  18. let match;
  19. match = /^resolve-options (.+)$/.exec(options.name);
  20. if (match) {
  21. this.hooks.resolveOptions.tap(
  22. match[1],
  23. options.fn.name || "unnamed compat plugin",
  24. options.fn
  25. );
  26. return true;
  27. }
  28. match = /^resolver (.+)$/.exec(options.name);
  29. if (match) {
  30. this.hooks.resolver.tap(
  31. match[1],
  32. options.fn.name || "unnamed compat plugin",
  33. options.fn
  34. );
  35. return true;
  36. }
  37. });
  38. this.cache1 = new WeakMap();
  39. this.cache2 = new Map();
  40. }
  41. get(type, resolveOptions) {
  42. const cachedResolver = this.cache1.get(resolveOptions);
  43. if (cachedResolver) return cachedResolver();
  44. const ident = `${type}|${JSON.stringify(resolveOptions)}`;
  45. const resolver = this.cache2.get(ident);
  46. if (resolver) return resolver;
  47. const newResolver = this._create(type, resolveOptions);
  48. this.cache2.set(ident, newResolver);
  49. return newResolver;
  50. }
  51. _create(type, resolveOptions) {
  52. resolveOptions = this.hooks.resolveOptions.for(type).call(resolveOptions);
  53. const resolver = Factory.createResolver(resolveOptions);
  54. if (!resolver) {
  55. throw new Error("No resolver created");
  56. }
  57. this.hooks.resolver.for(type).call(resolver, resolveOptions);
  58. return resolver;
  59. }
  60. };