source: frontend/node_modules/webpack/lib/ResolverFactory.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 11 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 5.3 KB
Line 
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const Factory = require("enhanced-resolve").ResolverFactory;
9const { HookMap, SyncHook, SyncWaterfallHook } = require("tapable");
10const {
11 cachedCleverMerge,
12 removeOperations,
13 resolveByProperty
14} = require("./util/cleverMerge");
15
16/** @typedef {import("enhanced-resolve").ResolveOptions} ResolveOptions */
17/** @typedef {import("enhanced-resolve").Resolver} Resolver */
18/** @typedef {import("../declarations/WebpackOptions").ResolveOptions} WebpackResolveOptions */
19/** @typedef {import("../declarations/WebpackOptions").ResolvePluginInstance} ResolvePluginInstance */
20
21/** @typedef {WebpackResolveOptions & { dependencyType?: string, resolveToContext?: boolean }} ResolveOptionsWithDependencyType */
22/**
23 * Defines the with options type used by this module.
24 * @typedef {object} WithOptions
25 * @property {(options: Partial<ResolveOptionsWithDependencyType>) => ResolverWithOptions} withOptions create a resolver with additional/different options
26 */
27
28/** @typedef {Resolver & WithOptions} ResolverWithOptions */
29
30// need to be hoisted on module level for caching identity
31/** @type {ResolveOptionsWithDependencyType} */
32const EMPTY_RESOLVE_OPTIONS = {};
33
34/**
35 * Convert to resolve options.
36 * @param {ResolveOptionsWithDependencyType} resolveOptionsWithDepType enhanced options
37 * @returns {ResolveOptions} merged options
38 */
39const convertToResolveOptions = (resolveOptionsWithDepType) => {
40 const { dependencyType, plugins, ...remaining } = resolveOptionsWithDepType;
41
42 // check type compat
43 /** @type {Partial<ResolveOptionsWithDependencyType>} */
44 const partialOptions = {
45 ...remaining,
46 plugins:
47 plugins &&
48 /** @type {ResolvePluginInstance[]} */ (
49 plugins.filter((item) => item !== "...")
50 )
51 };
52
53 if (!partialOptions.fileSystem) {
54 throw new Error(
55 "fileSystem is missing in resolveOptions, but it's required for enhanced-resolve"
56 );
57 }
58 // These weird types validate that we checked all non-optional properties
59 const options =
60 /** @type {Partial<ResolveOptionsWithDependencyType> & Pick<ResolveOptionsWithDependencyType, "fileSystem">} */ (
61 partialOptions
62 );
63
64 return /** @type {ResolveOptions} */ (
65 removeOperations(
66 resolveByProperty(options, "byDependency", dependencyType),
67 // Keep the `unsafeCache` because it can be a `Proxy`
68 ["unsafeCache"]
69 )
70 );
71};
72
73/**
74 * Represents the resolver factory runtime component.
75 * @typedef {object} ResolverCache
76 * @property {WeakMap<ResolveOptionsWithDependencyType, ResolverWithOptions>} direct
77 * @property {Map<string, ResolverWithOptions>} stringified
78 */
79
80module.exports = class ResolverFactory {
81 constructor() {
82 this.hooks = Object.freeze({
83 /** @type {HookMap<SyncWaterfallHook<[ResolveOptionsWithDependencyType]>>} */
84 resolveOptions: new HookMap(
85 () => new SyncWaterfallHook(["resolveOptions"])
86 ),
87 /** @type {HookMap<SyncHook<[Resolver, ResolveOptions, ResolveOptionsWithDependencyType]>>} */
88 resolver: new HookMap(
89 () => new SyncHook(["resolver", "resolveOptions", "userResolveOptions"])
90 )
91 });
92 /** @type {Map<string, ResolverCache>} */
93 this.cache = new Map();
94 }
95
96 /**
97 * Returns the resolver.
98 * @param {string} type type of resolver
99 * @param {ResolveOptionsWithDependencyType=} resolveOptions options
100 * @returns {ResolverWithOptions} the resolver
101 */
102 get(type, resolveOptions = EMPTY_RESOLVE_OPTIONS) {
103 let typedCaches = this.cache.get(type);
104 if (!typedCaches) {
105 typedCaches = {
106 direct: new WeakMap(),
107 stringified: new Map()
108 };
109 this.cache.set(type, typedCaches);
110 }
111 const cachedResolver = typedCaches.direct.get(resolveOptions);
112 if (cachedResolver) {
113 return cachedResolver;
114 }
115 const ident = JSON.stringify(resolveOptions);
116 const resolver = typedCaches.stringified.get(ident);
117 if (resolver) {
118 typedCaches.direct.set(resolveOptions, resolver);
119 return resolver;
120 }
121 const newResolver = this._create(type, resolveOptions);
122 typedCaches.direct.set(resolveOptions, newResolver);
123 typedCaches.stringified.set(ident, newResolver);
124 return newResolver;
125 }
126
127 /**
128 * Returns the resolver.
129 * @param {string} type type of resolver
130 * @param {ResolveOptionsWithDependencyType} resolveOptionsWithDepType options
131 * @returns {ResolverWithOptions} the resolver
132 */
133 _create(type, resolveOptionsWithDepType) {
134 /** @type {ResolveOptionsWithDependencyType} */
135 const originalResolveOptions = { ...resolveOptionsWithDepType };
136
137 const resolveOptions = convertToResolveOptions(
138 this.hooks.resolveOptions.for(type).call(resolveOptionsWithDepType)
139 );
140 const resolver = /** @type {ResolverWithOptions} */ (
141 Factory.createResolver(resolveOptions)
142 );
143 if (!resolver) {
144 throw new Error("No resolver created");
145 }
146 /** @type {WeakMap<Partial<ResolveOptionsWithDependencyType>, ResolverWithOptions>} */
147 const childCache = new WeakMap();
148 resolver.withOptions = (options) => {
149 const cacheEntry = childCache.get(options);
150 if (cacheEntry !== undefined) return cacheEntry;
151 const mergedOptions = cachedCleverMerge(originalResolveOptions, options);
152 const resolver = this.get(type, mergedOptions);
153 childCache.set(options, resolver);
154 return resolver;
155 };
156 this.hooks.resolver
157 .for(type)
158 .call(resolver, resolveOptions, originalResolveOptions);
159 return resolver;
160 }
161};
Note: See TracBrowser for help on using the repository browser.