马宇豪
2024-07-16 f591c27b57e2418c9495bc02ae8cfff84d35bc18
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*
    MIT License http://www.opensource.org/licenses/mit-license.php
    Author Tobias Koppers @sokra
*/
 
"use strict";
 
const ModuleNotFoundError = require("../ModuleNotFoundError");
const LazySet = require("../util/LazySet");
 
/** @typedef {import("../Compilation")} Compilation */
/** @typedef {import("../ResolverFactory").ResolveOptionsWithDependencyType} ResolveOptionsWithDependencyType */
 
/**
 * @template T
 * @typedef {Object} MatchedConfigs
 * @property {Map<string, T>} resolved
 * @property {Map<string, T>} unresolved
 * @property {Map<string, T>} prefixed
 */
 
/** @type {ResolveOptionsWithDependencyType} */
const RESOLVE_OPTIONS = { dependencyType: "esm" };
 
/**
 * @template T
 * @param {Compilation} compilation the compilation
 * @param {[string, T][]} configs to be processed configs
 * @returns {Promise<MatchedConfigs<T>>} resolved matchers
 */
exports.resolveMatchedConfigs = (compilation, configs) => {
    /** @type {Map<string, T>} */
    const resolved = new Map();
    /** @type {Map<string, T>} */
    const unresolved = new Map();
    /** @type {Map<string, T>} */
    const prefixed = new Map();
    const resolveContext = {
        /** @type {LazySet<string>} */
        fileDependencies: new LazySet(),
        /** @type {LazySet<string>} */
        contextDependencies: new LazySet(),
        /** @type {LazySet<string>} */
        missingDependencies: new LazySet()
    };
    const resolver = compilation.resolverFactory.get("normal", RESOLVE_OPTIONS);
    const context = compilation.compiler.context;
 
    return Promise.all(
        configs.map(([request, config]) => {
            if (/^\.\.?(\/|$)/.test(request)) {
                // relative request
                return new Promise(resolve => {
                    resolver.resolve(
                        {},
                        context,
                        request,
                        resolveContext,
                        (err, result) => {
                            if (err || result === false) {
                                err = err || new Error(`Can't resolve ${request}`);
                                compilation.errors.push(
                                    new ModuleNotFoundError(null, err, {
                                        name: `shared module ${request}`
                                    })
                                );
                                return resolve();
                            }
                            resolved.set(result, config);
                            resolve();
                        }
                    );
                });
            } else if (/^(\/|[A-Za-z]:\\|\\\\)/.test(request)) {
                // absolute path
                resolved.set(request, config);
            } else if (request.endsWith("/")) {
                // module request prefix
                prefixed.set(request, config);
            } else {
                // module request
                unresolved.set(request, config);
            }
        })
    ).then(() => {
        compilation.contextDependencies.addAll(resolveContext.contextDependencies);
        compilation.fileDependencies.addAll(resolveContext.fileDependencies);
        compilation.missingDependencies.addAll(resolveContext.missingDependencies);
        return { resolved, unresolved, prefixed };
    });
};