source: trip-planner-front/node_modules/webpack/lib/ExternalModuleFactoryPlugin.js

Last change on this file was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 7.0 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 util = require("util");
9const ExternalModule = require("./ExternalModule");
10const { resolveByProperty, cachedSetProperty } = require("./util/cleverMerge");
11
12/** @typedef {import("../declarations/WebpackOptions").Externals} Externals */
13/** @typedef {import("./NormalModuleFactory")} NormalModuleFactory */
14
15const UNSPECIFIED_EXTERNAL_TYPE_REGEXP = /^[a-z0-9-]+ /;
16const EMPTY_RESOLVE_OPTIONS = {};
17
18// TODO webpack 6 remove this
19const callDeprecatedExternals = util.deprecate(
20 (externalsFunction, context, request, cb) => {
21 externalsFunction.call(null, context, request, cb);
22 },
23 "The externals-function should be defined like ({context, request}, cb) => { ... }",
24 "DEP_WEBPACK_EXTERNALS_FUNCTION_PARAMETERS"
25);
26
27const cache = new WeakMap();
28
29const resolveLayer = (obj, layer) => {
30 let map = cache.get(obj);
31 if (map === undefined) {
32 map = new Map();
33 cache.set(obj, map);
34 } else {
35 const cacheEntry = map.get(layer);
36 if (cacheEntry !== undefined) return cacheEntry;
37 }
38 const result = resolveByProperty(obj, "byLayer", layer);
39 map.set(layer, result);
40 return result;
41};
42
43class ExternalModuleFactoryPlugin {
44 /**
45 * @param {string | undefined} type default external type
46 * @param {Externals} externals externals config
47 */
48 constructor(type, externals) {
49 this.type = type;
50 this.externals = externals;
51 }
52
53 /**
54 * @param {NormalModuleFactory} normalModuleFactory the normal module factory
55 * @returns {void}
56 */
57 apply(normalModuleFactory) {
58 const globalType = this.type;
59 normalModuleFactory.hooks.factorize.tapAsync(
60 "ExternalModuleFactoryPlugin",
61 (data, callback) => {
62 const context = data.context;
63 const contextInfo = data.contextInfo;
64 const dependency = data.dependencies[0];
65 const dependencyType = data.dependencyType;
66
67 /**
68 * @param {string|string[]|boolean|Record<string, string|string[]>} value the external config
69 * @param {string|undefined} type type of external
70 * @param {function(Error=, ExternalModule=): void} callback callback
71 * @returns {void}
72 */
73 const handleExternal = (value, type, callback) => {
74 if (value === false) {
75 // Not externals, fallback to original factory
76 return callback();
77 }
78 /** @type {string | string[] | Record<string, string|string[]>} */
79 let externalConfig;
80 if (value === true) {
81 externalConfig = dependency.request;
82 } else {
83 externalConfig = value;
84 }
85 // When no explicit type is specified, extract it from the externalConfig
86 if (type === undefined) {
87 if (
88 typeof externalConfig === "string" &&
89 UNSPECIFIED_EXTERNAL_TYPE_REGEXP.test(externalConfig)
90 ) {
91 const idx = externalConfig.indexOf(" ");
92 type = externalConfig.substr(0, idx);
93 externalConfig = externalConfig.substr(idx + 1);
94 } else if (
95 Array.isArray(externalConfig) &&
96 externalConfig.length > 0 &&
97 UNSPECIFIED_EXTERNAL_TYPE_REGEXP.test(externalConfig[0])
98 ) {
99 const firstItem = externalConfig[0];
100 const idx = firstItem.indexOf(" ");
101 type = firstItem.substr(0, idx);
102 externalConfig = [
103 firstItem.substr(idx + 1),
104 ...externalConfig.slice(1)
105 ];
106 }
107 }
108 callback(
109 null,
110 new ExternalModule(
111 externalConfig,
112 type || globalType,
113 dependency.request
114 )
115 );
116 };
117
118 /**
119 * @param {Externals} externals externals config
120 * @param {function(Error=, ExternalModule=): void} callback callback
121 * @returns {void}
122 */
123 const handleExternals = (externals, callback) => {
124 if (typeof externals === "string") {
125 if (externals === dependency.request) {
126 return handleExternal(dependency.request, undefined, callback);
127 }
128 } else if (Array.isArray(externals)) {
129 let i = 0;
130 const next = () => {
131 let asyncFlag;
132 const handleExternalsAndCallback = (err, module) => {
133 if (err) return callback(err);
134 if (!module) {
135 if (asyncFlag) {
136 asyncFlag = false;
137 return;
138 }
139 return next();
140 }
141 callback(null, module);
142 };
143
144 do {
145 asyncFlag = true;
146 if (i >= externals.length) return callback();
147 handleExternals(externals[i++], handleExternalsAndCallback);
148 } while (!asyncFlag);
149 asyncFlag = false;
150 };
151
152 next();
153 return;
154 } else if (externals instanceof RegExp) {
155 if (externals.test(dependency.request)) {
156 return handleExternal(dependency.request, undefined, callback);
157 }
158 } else if (typeof externals === "function") {
159 const cb = (err, value, type) => {
160 if (err) return callback(err);
161 if (value !== undefined) {
162 handleExternal(value, type, callback);
163 } else {
164 callback();
165 }
166 };
167 if (externals.length === 3) {
168 // TODO webpack 6 remove this
169 callDeprecatedExternals(
170 externals,
171 context,
172 dependency.request,
173 cb
174 );
175 } else {
176 const promise = externals(
177 {
178 context,
179 request: dependency.request,
180 dependencyType,
181 contextInfo,
182 getResolve: options => (context, request, callback) => {
183 const resolveContext = {
184 fileDependencies: data.fileDependencies,
185 missingDependencies: data.missingDependencies,
186 contextDependencies: data.contextDependencies
187 };
188 let resolver = normalModuleFactory.getResolver(
189 "normal",
190 dependencyType
191 ? cachedSetProperty(
192 data.resolveOptions || EMPTY_RESOLVE_OPTIONS,
193 "dependencyType",
194 dependencyType
195 )
196 : data.resolveOptions
197 );
198 if (options) resolver = resolver.withOptions(options);
199 if (callback) {
200 resolver.resolve(
201 {},
202 context,
203 request,
204 resolveContext,
205 callback
206 );
207 } else {
208 return new Promise((resolve, reject) => {
209 resolver.resolve(
210 {},
211 context,
212 request,
213 resolveContext,
214 (err, result) => {
215 if (err) reject(err);
216 else resolve(result);
217 }
218 );
219 });
220 }
221 }
222 },
223 cb
224 );
225 if (promise && promise.then) promise.then(r => cb(null, r), cb);
226 }
227 return;
228 } else if (typeof externals === "object") {
229 const resolvedExternals = resolveLayer(
230 externals,
231 contextInfo.issuerLayer
232 );
233 if (
234 Object.prototype.hasOwnProperty.call(
235 resolvedExternals,
236 dependency.request
237 )
238 ) {
239 return handleExternal(
240 resolvedExternals[dependency.request],
241 undefined,
242 callback
243 );
244 }
245 }
246 callback();
247 };
248
249 handleExternals(this.externals, callback);
250 }
251 );
252 }
253}
254module.exports = ExternalModuleFactoryPlugin;
Note: See TracBrowser for help on using the repository browser.