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