保誠-保戶業務員媒合平台
HelenHuang
2022-06-09 9bdb95c9e34cef640534e5e5a1e2225a80442000
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/*
 MIT License http://www.opensource.org/licenses/mit-license.php
 Author Tobias Koppers @sokra
 */
"use strict";
 
const { Tapable, HookMap, SyncHook, SyncWaterfallHook } = require("tapable");
const Factory = require("enhanced-resolve").ResolverFactory;
const { cachedCleverMerge } = require("./util/cleverMerge");
 
/** @typedef {import("enhanced-resolve").Resolver} Resolver */
 
const EMTPY_RESOLVE_OPTIONS = {};
 
module.exports = class ResolverFactory extends Tapable {
    constructor() {
        super();
        this.hooks = {
            resolveOptions: new HookMap(
                () => new SyncWaterfallHook(["resolveOptions"])
            ),
            resolver: new HookMap(() => new SyncHook(["resolver", "resolveOptions"]))
        };
        this._pluginCompat.tap("ResolverFactory", options => {
            let match;
            match = /^resolve-options (.+)$/.exec(options.name);
            if (match) {
                this.hooks.resolveOptions
                    .for(match[1])
                    .tap(options.fn.name || "unnamed compat plugin", options.fn);
                return true;
            }
            match = /^resolver (.+)$/.exec(options.name);
            if (match) {
                this.hooks.resolver
                    .for(match[1])
                    .tap(options.fn.name || "unnamed compat plugin", options.fn);
                return true;
            }
        });
        this.cache2 = new Map();
    }
 
    get(type, resolveOptions) {
        resolveOptions = resolveOptions || EMTPY_RESOLVE_OPTIONS;
        const ident = `${type}|${JSON.stringify(resolveOptions)}`;
        const resolver = this.cache2.get(ident);
        if (resolver) return resolver;
        const newResolver = this._create(type, resolveOptions);
        this.cache2.set(ident, newResolver);
        return newResolver;
    }
 
    _create(type, resolveOptions) {
        const originalResolveOptions = Object.assign({}, resolveOptions);
        resolveOptions = this.hooks.resolveOptions.for(type).call(resolveOptions);
        const resolver = Factory.createResolver(resolveOptions);
        if (!resolver) {
            throw new Error("No resolver created");
        }
        /** @type {Map<Object, Resolver>} */
        const childCache = new Map();
        resolver.withOptions = options => {
            const cacheEntry = childCache.get(options);
            if (cacheEntry !== undefined) return cacheEntry;
            const mergedOptions = cachedCleverMerge(originalResolveOptions, options);
            const resolver = this.get(type, mergedOptions);
            childCache.set(options, resolver);
            return resolver;
        };
        this.hooks.resolver.for(type).call(resolver, resolveOptions);
        return resolver;
    }
};