Projekt

Obecné

Profil

Stáhnout (24 KB) Statistiky
| Větev: | Revize:
1
/*
2
	MIT License http://www.opensource.org/licenses/mit-license.php
3
	Author Tobias Koppers @sokra
4
*/
5
"use strict";
6
const util = require("util");
7
const { OriginalSource, RawSource } = require("webpack-sources");
8
const Module = require("./Module");
9
const AsyncDependenciesBlock = require("./AsyncDependenciesBlock");
10
const Template = require("./Template");
11
const contextify = require("./util/identifier").contextify;
12

    
13
/** @typedef {"sync" | "eager" | "weak" | "async-weak" | "lazy" | "lazy-once"} ContextMode Context mode */
14
/** @typedef {import("./dependencies/ContextElementDependency")} ContextElementDependency */
15

    
16
/**
17
 * @callback ResolveDependenciesCallback
18
 * @param {Error=} err
19
 * @param {ContextElementDependency[]} dependencies
20
 */
21

    
22
/**
23
 * @callback ResolveDependencies
24
 * @param {TODO} fs
25
 * @param {TODO} options
26
 * @param {ResolveDependenciesCallback} callback
27
 */
28

    
29
class ContextModule extends Module {
30
	// type ContextMode = "sync" | "eager" | "weak" | "async-weak" | "lazy" | "lazy-once"
31
	// type ContextOptions = { resource: string, recursive: boolean, regExp: RegExp, addon?: string, mode?: ContextMode, chunkName?: string, include?: RegExp, exclude?: RegExp, groupOptions?: Object }
32
	// resolveDependencies: (fs: FS, options: ContextOptions, (err: Error?, dependencies: Dependency[]) => void) => void
33
	// options: ContextOptions
34
	/**
35
	 * @param {ResolveDependencies} resolveDependencies function to get dependencies in this context
36
	 * @param {TODO} options options object
37
	 */
38
	constructor(resolveDependencies, options) {
39
		let resource;
40
		let resourceQuery;
41
		const queryIdx = options.resource.indexOf("?");
42
		if (queryIdx >= 0) {
43
			resource = options.resource.substr(0, queryIdx);
44
			resourceQuery = options.resource.substr(queryIdx);
45
		} else {
46
			resource = options.resource;
47
			resourceQuery = "";
48
		}
49

    
50
		super("javascript/dynamic", resource);
51

    
52
		// Info from Factory
53
		this.resolveDependencies = resolveDependencies;
54
		this.options = Object.assign({}, options, {
55
			resource: resource,
56
			resourceQuery: resourceQuery
57
		});
58
		if (options.resolveOptions !== undefined) {
59
			this.resolveOptions = options.resolveOptions;
60
		}
61

    
62
		// Info from Build
63
		this._contextDependencies = new Set([this.context]);
64

    
65
		if (typeof options.mode !== "string") {
66
			throw new Error("options.mode is a required option");
67
		}
68

    
69
		this._identifier = this._createIdentifier();
70
	}
71

    
72
	updateCacheModule(module) {
73
		this.resolveDependencies = module.resolveDependencies;
74
		this.options = module.options;
75
		this.resolveOptions = module.resolveOptions;
76
	}
77

    
78
	prettyRegExp(regexString) {
79
		// remove the "/" at the front and the beginning
80
		// "/foo/" -> "foo"
81
		return regexString.substring(1, regexString.length - 1);
82
	}
83

    
84
	_createIdentifier() {
85
		let identifier = this.context;
86
		if (this.options.resourceQuery) {
87
			identifier += ` ${this.options.resourceQuery}`;
88
		}
89
		if (this.options.mode) {
90
			identifier += ` ${this.options.mode}`;
91
		}
92
		if (!this.options.recursive) {
93
			identifier += " nonrecursive";
94
		}
95
		if (this.options.addon) {
96
			identifier += ` ${this.options.addon}`;
97
		}
98
		if (this.options.regExp) {
99
			identifier += ` ${this.options.regExp}`;
100
		}
101
		if (this.options.include) {
102
			identifier += ` include: ${this.options.include}`;
103
		}
104
		if (this.options.exclude) {
105
			identifier += ` exclude: ${this.options.exclude}`;
106
		}
107
		if (this.options.groupOptions) {
108
			identifier += ` groupOptions: ${JSON.stringify(
109
				this.options.groupOptions
110
			)}`;
111
		}
112
		if (this.options.namespaceObject === "strict") {
113
			identifier += " strict namespace object";
114
		} else if (this.options.namespaceObject) {
115
			identifier += " namespace object";
116
		}
117

    
118
		return identifier;
119
	}
120

    
121
	identifier() {
122
		return this._identifier;
123
	}
124

    
125
	readableIdentifier(requestShortener) {
126
		let identifier = requestShortener.shorten(this.context);
127
		if (this.options.resourceQuery) {
128
			identifier += ` ${this.options.resourceQuery}`;
129
		}
130
		if (this.options.mode) {
131
			identifier += ` ${this.options.mode}`;
132
		}
133
		if (!this.options.recursive) {
134
			identifier += " nonrecursive";
135
		}
136
		if (this.options.addon) {
137
			identifier += ` ${requestShortener.shorten(this.options.addon)}`;
138
		}
139
		if (this.options.regExp) {
140
			identifier += ` ${this.prettyRegExp(this.options.regExp + "")}`;
141
		}
142
		if (this.options.include) {
143
			identifier += ` include: ${this.prettyRegExp(this.options.include + "")}`;
144
		}
145
		if (this.options.exclude) {
146
			identifier += ` exclude: ${this.prettyRegExp(this.options.exclude + "")}`;
147
		}
148
		if (this.options.groupOptions) {
149
			const groupOptions = this.options.groupOptions;
150
			for (const key of Object.keys(groupOptions)) {
151
				identifier += ` ${key}: ${groupOptions[key]}`;
152
			}
153
		}
154
		if (this.options.namespaceObject === "strict") {
155
			identifier += " strict namespace object";
156
		} else if (this.options.namespaceObject) {
157
			identifier += " namespace object";
158
		}
159

    
160
		return identifier;
161
	}
162

    
163
	libIdent(options) {
164
		let identifier = contextify(options.context, this.context);
165
		if (this.options.mode) {
166
			identifier += ` ${this.options.mode}`;
167
		}
168
		if (this.options.recursive) {
169
			identifier += " recursive";
170
		}
171
		if (this.options.addon) {
172
			identifier += ` ${contextify(options.context, this.options.addon)}`;
173
		}
174
		if (this.options.regExp) {
175
			identifier += ` ${this.prettyRegExp(this.options.regExp + "")}`;
176
		}
177
		if (this.options.include) {
178
			identifier += ` include: ${this.prettyRegExp(this.options.include + "")}`;
179
		}
180
		if (this.options.exclude) {
181
			identifier += ` exclude: ${this.prettyRegExp(this.options.exclude + "")}`;
182
		}
183

    
184
		return identifier;
185
	}
186

    
187
	needRebuild(fileTimestamps, contextTimestamps) {
188
		const ts = contextTimestamps.get(this.context);
189
		if (!ts) {
190
			return true;
191
		}
192

    
193
		return ts >= this.buildInfo.builtTime;
194
	}
195

    
196
	build(options, compilation, resolver, fs, callback) {
197
		this.built = true;
198
		this.buildMeta = {};
199
		this.buildInfo = {
200
			builtTime: Date.now(),
201
			contextDependencies: this._contextDependencies
202
		};
203
		this.resolveDependencies(fs, this.options, (err, dependencies) => {
204
			if (err) return callback(err);
205

    
206
			// abort if something failed
207
			// this will create an empty context
208
			if (!dependencies) {
209
				callback();
210
				return;
211
			}
212

    
213
			// enhance dependencies with meta info
214
			for (const dep of dependencies) {
215
				dep.loc = {
216
					name: dep.userRequest
217
				};
218
				dep.request = this.options.addon + dep.request;
219
			}
220

    
221
			if (this.options.mode === "sync" || this.options.mode === "eager") {
222
				// if we have an sync or eager context
223
				// just add all dependencies and continue
224
				this.dependencies = dependencies;
225
			} else if (this.options.mode === "lazy-once") {
226
				// for the lazy-once mode create a new async dependency block
227
				// and add that block to this context
228
				if (dependencies.length > 0) {
229
					const block = new AsyncDependenciesBlock(
230
						Object.assign({}, this.options.groupOptions, {
231
							name: this.options.chunkName
232
						}),
233
						this
234
					);
235
					for (const dep of dependencies) {
236
						block.addDependency(dep);
237
					}
238
					this.addBlock(block);
239
				}
240
			} else if (
241
				this.options.mode === "weak" ||
242
				this.options.mode === "async-weak"
243
			) {
244
				// we mark all dependencies as weak
245
				for (const dep of dependencies) {
246
					dep.weak = true;
247
				}
248
				this.dependencies = dependencies;
249
			} else if (this.options.mode === "lazy") {
250
				// if we are lazy create a new async dependency block per dependency
251
				// and add all blocks to this context
252
				let index = 0;
253
				for (const dep of dependencies) {
254
					let chunkName = this.options.chunkName;
255
					if (chunkName) {
256
						if (!/\[(index|request)\]/.test(chunkName)) {
257
							chunkName += "[index]";
258
						}
259
						chunkName = chunkName.replace(/\[index\]/g, index++);
260
						chunkName = chunkName.replace(
261
							/\[request\]/g,
262
							Template.toPath(dep.userRequest)
263
						);
264
					}
265
					const block = new AsyncDependenciesBlock(
266
						Object.assign({}, this.options.groupOptions, {
267
							name: chunkName
268
						}),
269
						dep.module,
270
						dep.loc,
271
						dep.userRequest
272
					);
273
					block.addDependency(dep);
274
					this.addBlock(block);
275
				}
276
			} else {
277
				callback(
278
					new Error(`Unsupported mode "${this.options.mode}" in context`)
279
				);
280
				return;
281
			}
282
			callback();
283
		});
284
	}
285

    
286
	getUserRequestMap(dependencies) {
287
		// if we filter first we get a new array
288
		// therefor we dont need to create a clone of dependencies explicitly
289
		// therefore the order of this is !important!
290
		return dependencies
291
			.filter(dependency => dependency.module)
292
			.sort((a, b) => {
293
				if (a.userRequest === b.userRequest) {
294
					return 0;
295
				}
296
				return a.userRequest < b.userRequest ? -1 : 1;
297
			})
298
			.reduce((map, dep) => {
299
				map[dep.userRequest] = dep.module.id;
300
				return map;
301
			}, Object.create(null));
302
	}
303

    
304
	getFakeMap(dependencies) {
305
		if (!this.options.namespaceObject) {
306
			return 9;
307
		}
308
		// if we filter first we get a new array
309
		// therefor we dont need to create a clone of dependencies explicitly
310
		// therefore the order of this is !important!
311
		let hasNonHarmony = false;
312
		let hasNamespace = false;
313
		let hasNamed = false;
314
		const fakeMap = dependencies
315
			.filter(dependency => dependency.module)
316
			.sort((a, b) => {
317
				return b.module.id - a.module.id;
318
			})
319
			.reduce((map, dep) => {
320
				const exportsType =
321
					dep.module.buildMeta && dep.module.buildMeta.exportsType;
322
				const id = dep.module.id;
323
				if (!exportsType) {
324
					map[id] = this.options.namespaceObject === "strict" ? 1 : 7;
325
					hasNonHarmony = true;
326
				} else if (exportsType === "namespace") {
327
					map[id] = 9;
328
					hasNamespace = true;
329
				} else if (exportsType === "named") {
330
					map[id] = 3;
331
					hasNamed = true;
332
				}
333
				return map;
334
			}, Object.create(null));
335
		if (!hasNamespace && hasNonHarmony && !hasNamed) {
336
			return this.options.namespaceObject === "strict" ? 1 : 7;
337
		}
338
		if (hasNamespace && !hasNonHarmony && !hasNamed) {
339
			return 9;
340
		}
341
		if (!hasNamespace && !hasNonHarmony && hasNamed) {
342
			return 3;
343
		}
344
		if (!hasNamespace && !hasNonHarmony && !hasNamed) {
345
			return 9;
346
		}
347
		return fakeMap;
348
	}
349

    
350
	getFakeMapInitStatement(fakeMap) {
351
		return typeof fakeMap === "object"
352
			? `var fakeMap = ${JSON.stringify(fakeMap, null, "\t")};`
353
			: "";
354
	}
355

    
356
	getReturn(type) {
357
		if (type === 9) {
358
			return "__webpack_require__(id)";
359
		}
360
		return `__webpack_require__.t(id, ${type})`;
361
	}
362

    
363
	getReturnModuleObjectSource(fakeMap, fakeMapDataExpression = "fakeMap[id]") {
364
		if (typeof fakeMap === "number") {
365
			return `return ${this.getReturn(fakeMap)};`;
366
		}
367
		return `return __webpack_require__.t(id, ${fakeMapDataExpression})`;
368
	}
369

    
370
	getSyncSource(dependencies, id) {
371
		const map = this.getUserRequestMap(dependencies);
372
		const fakeMap = this.getFakeMap(dependencies);
373
		const returnModuleObject = this.getReturnModuleObjectSource(fakeMap);
374

    
375
		return `var map = ${JSON.stringify(map, null, "\t")};
376
${this.getFakeMapInitStatement(fakeMap)}
377

    
378
function webpackContext(req) {
379
	var id = webpackContextResolve(req);
380
	${returnModuleObject}
381
}
382
function webpackContextResolve(req) {
383
	if(!__webpack_require__.o(map, req)) {
384
		var e = new Error("Cannot find module '" + req + "'");
385
		e.code = 'MODULE_NOT_FOUND';
386
		throw e;
387
	}
388
	return map[req];
389
}
390
webpackContext.keys = function webpackContextKeys() {
391
	return Object.keys(map);
392
};
393
webpackContext.resolve = webpackContextResolve;
394
module.exports = webpackContext;
395
webpackContext.id = ${JSON.stringify(id)};`;
396
	}
397

    
398
	getWeakSyncSource(dependencies, id) {
399
		const map = this.getUserRequestMap(dependencies);
400
		const fakeMap = this.getFakeMap(dependencies);
401
		const returnModuleObject = this.getReturnModuleObjectSource(fakeMap);
402

    
403
		return `var map = ${JSON.stringify(map, null, "\t")};
404
${this.getFakeMapInitStatement(fakeMap)}
405

    
406
function webpackContext(req) {
407
	var id = webpackContextResolve(req);
408
	if(!__webpack_require__.m[id]) {
409
		var e = new Error("Module '" + req + "' ('" + id + "') is not available (weak dependency)");
410
		e.code = 'MODULE_NOT_FOUND';
411
		throw e;
412
	}
413
	${returnModuleObject}
414
}
415
function webpackContextResolve(req) {
416
	if(!__webpack_require__.o(map, req)) {
417
		var e = new Error("Cannot find module '" + req + "'");
418
		e.code = 'MODULE_NOT_FOUND';
419
		throw e;
420
	}
421
	return map[req];
422
}
423
webpackContext.keys = function webpackContextKeys() {
424
	return Object.keys(map);
425
};
426
webpackContext.resolve = webpackContextResolve;
427
webpackContext.id = ${JSON.stringify(id)};
428
module.exports = webpackContext;`;
429
	}
430

    
431
	getAsyncWeakSource(dependencies, id) {
432
		const map = this.getUserRequestMap(dependencies);
433
		const fakeMap = this.getFakeMap(dependencies);
434
		const returnModuleObject = this.getReturnModuleObjectSource(fakeMap);
435

    
436
		return `var map = ${JSON.stringify(map, null, "\t")};
437
${this.getFakeMapInitStatement(fakeMap)}
438

    
439
function webpackAsyncContext(req) {
440
	return webpackAsyncContextResolve(req).then(function(id) {
441
		if(!__webpack_require__.m[id]) {
442
			var e = new Error("Module '" + req + "' ('" + id + "') is not available (weak dependency)");
443
			e.code = 'MODULE_NOT_FOUND';
444
			throw e;
445
		}
446
		${returnModuleObject}
447
	});
448
}
449
function webpackAsyncContextResolve(req) {
450
	// Here Promise.resolve().then() is used instead of new Promise() to prevent
451
	// uncaught exception popping up in devtools
452
	return Promise.resolve().then(function() {
453
		if(!__webpack_require__.o(map, req)) {
454
			var e = new Error("Cannot find module '" + req + "'");
455
			e.code = 'MODULE_NOT_FOUND';
456
			throw e;
457
		}
458
		return map[req];
459
	});
460
}
461
webpackAsyncContext.keys = function webpackAsyncContextKeys() {
462
	return Object.keys(map);
463
};
464
webpackAsyncContext.resolve = webpackAsyncContextResolve;
465
webpackAsyncContext.id = ${JSON.stringify(id)};
466
module.exports = webpackAsyncContext;`;
467
	}
468

    
469
	getEagerSource(dependencies, id) {
470
		const map = this.getUserRequestMap(dependencies);
471
		const fakeMap = this.getFakeMap(dependencies);
472
		const thenFunction =
473
			fakeMap !== 9
474
				? `function(id) {
475
		${this.getReturnModuleObjectSource(fakeMap)}
476
	}`
477
				: "__webpack_require__";
478
		return `var map = ${JSON.stringify(map, null, "\t")};
479
${this.getFakeMapInitStatement(fakeMap)}
480

    
481
function webpackAsyncContext(req) {
482
	return webpackAsyncContextResolve(req).then(${thenFunction});
483
}
484
function webpackAsyncContextResolve(req) {
485
	// Here Promise.resolve().then() is used instead of new Promise() to prevent
486
	// uncaught exception popping up in devtools
487
	return Promise.resolve().then(function() {
488
		if(!__webpack_require__.o(map, req)) {
489
			var e = new Error("Cannot find module '" + req + "'");
490
			e.code = 'MODULE_NOT_FOUND';
491
			throw e;
492
		}
493
		return map[req];
494
	});
495
}
496
webpackAsyncContext.keys = function webpackAsyncContextKeys() {
497
	return Object.keys(map);
498
};
499
webpackAsyncContext.resolve = webpackAsyncContextResolve;
500
webpackAsyncContext.id = ${JSON.stringify(id)};
501
module.exports = webpackAsyncContext;`;
502
	}
503

    
504
	getLazyOnceSource(block, dependencies, id, runtimeTemplate) {
505
		const promise = runtimeTemplate.blockPromise({
506
			block,
507
			message: "lazy-once context"
508
		});
509
		const map = this.getUserRequestMap(dependencies);
510
		const fakeMap = this.getFakeMap(dependencies);
511
		const thenFunction =
512
			fakeMap !== 9
513
				? `function(id) {
514
		${this.getReturnModuleObjectSource(fakeMap)};
515
	}`
516
				: "__webpack_require__";
517

    
518
		return `var map = ${JSON.stringify(map, null, "\t")};
519
${this.getFakeMapInitStatement(fakeMap)}
520

    
521
function webpackAsyncContext(req) {
522
	return webpackAsyncContextResolve(req).then(${thenFunction});
523
}
524
function webpackAsyncContextResolve(req) {
525
	return ${promise}.then(function() {
526
		if(!__webpack_require__.o(map, req)) {
527
			var e = new Error("Cannot find module '" + req + "'");
528
			e.code = 'MODULE_NOT_FOUND';
529
			throw e;
530
		}
531
		return map[req];
532
	});
533
}
534
webpackAsyncContext.keys = function webpackAsyncContextKeys() {
535
	return Object.keys(map);
536
};
537
webpackAsyncContext.resolve = webpackAsyncContextResolve;
538
webpackAsyncContext.id = ${JSON.stringify(id)};
539
module.exports = webpackAsyncContext;`;
540
	}
541

    
542
	getLazySource(blocks, id) {
543
		let hasMultipleOrNoChunks = false;
544
		let hasNoChunk = true;
545
		const fakeMap = this.getFakeMap(blocks.map(b => b.dependencies[0]));
546
		const hasFakeMap = typeof fakeMap === "object";
547
		const map = blocks
548
			.filter(block => block.dependencies[0].module)
549
			.map(block => {
550
				const chunks = block.chunkGroup ? block.chunkGroup.chunks : [];
551
				if (chunks.length > 0) {
552
					hasNoChunk = false;
553
				}
554
				if (chunks.length !== 1) {
555
					hasMultipleOrNoChunks = true;
556
				}
557
				return {
558
					dependency: block.dependencies[0],
559
					block: block,
560
					userRequest: block.dependencies[0].userRequest,
561
					chunks
562
				};
563
			})
564
			.sort((a, b) => {
565
				if (a.userRequest === b.userRequest) return 0;
566
				return a.userRequest < b.userRequest ? -1 : 1;
567
			})
568
			.reduce((map, item) => {
569
				const chunks = item.chunks;
570

    
571
				if (hasNoChunk && !hasFakeMap) {
572
					map[item.userRequest] = item.dependency.module.id;
573
				} else {
574
					const arrayStart = [item.dependency.module.id];
575
					if (typeof fakeMap === "object") {
576
						arrayStart.push(fakeMap[item.dependency.module.id]);
577
					}
578
					map[item.userRequest] = arrayStart.concat(
579
						chunks.map(chunk => chunk.id)
580
					);
581
				}
582

    
583
				return map;
584
			}, Object.create(null));
585

    
586
		const shortMode = hasNoChunk && !hasFakeMap;
587
		const chunksStartPosition = hasFakeMap ? 2 : 1;
588
		const requestPrefix = hasNoChunk
589
			? "Promise.resolve()"
590
			: hasMultipleOrNoChunks
591
			? `Promise.all(ids.slice(${chunksStartPosition}).map(__webpack_require__.e))`
592
			: `__webpack_require__.e(ids[${chunksStartPosition}])`;
593
		const returnModuleObject = this.getReturnModuleObjectSource(
594
			fakeMap,
595
			shortMode ? "invalid" : "ids[1]"
596
		);
597

    
598
		const webpackAsyncContext =
599
			requestPrefix === "Promise.resolve()"
600
				? `${shortMode ? "" : ""}
601
function webpackAsyncContext(req) {
602
	return Promise.resolve().then(function() {
603
		if(!__webpack_require__.o(map, req)) {
604
			var e = new Error("Cannot find module '" + req + "'");
605
			e.code = 'MODULE_NOT_FOUND';
606
			throw e;
607
		}
608

    
609
		${shortMode ? "var id = map[req];" : "var ids = map[req], id = ids[0];"}
610
		${returnModuleObject}
611
	});
612
}`
613
				: `function webpackAsyncContext(req) {
614
	if(!__webpack_require__.o(map, req)) {
615
		return Promise.resolve().then(function() {
616
			var e = new Error("Cannot find module '" + req + "'");
617
			e.code = 'MODULE_NOT_FOUND';
618
			throw e;
619
		});
620
	}
621

    
622
	var ids = map[req], id = ids[0];
623
	return ${requestPrefix}.then(function() {
624
		${returnModuleObject}
625
	});
626
}`;
627

    
628
		return `var map = ${JSON.stringify(map, null, "\t")};
629
${webpackAsyncContext}
630
webpackAsyncContext.keys = function webpackAsyncContextKeys() {
631
	return Object.keys(map);
632
};
633
webpackAsyncContext.id = ${JSON.stringify(id)};
634
module.exports = webpackAsyncContext;`;
635
	}
636

    
637
	getSourceForEmptyContext(id) {
638
		return `function webpackEmptyContext(req) {
639
	var e = new Error("Cannot find module '" + req + "'");
640
	e.code = 'MODULE_NOT_FOUND';
641
	throw e;
642
}
643
webpackEmptyContext.keys = function() { return []; };
644
webpackEmptyContext.resolve = webpackEmptyContext;
645
module.exports = webpackEmptyContext;
646
webpackEmptyContext.id = ${JSON.stringify(id)};`;
647
	}
648

    
649
	getSourceForEmptyAsyncContext(id) {
650
		return `function webpackEmptyAsyncContext(req) {
651
	// Here Promise.resolve().then() is used instead of new Promise() to prevent
652
	// uncaught exception popping up in devtools
653
	return Promise.resolve().then(function() {
654
		var e = new Error("Cannot find module '" + req + "'");
655
		e.code = 'MODULE_NOT_FOUND';
656
		throw e;
657
	});
658
}
659
webpackEmptyAsyncContext.keys = function() { return []; };
660
webpackEmptyAsyncContext.resolve = webpackEmptyAsyncContext;
661
module.exports = webpackEmptyAsyncContext;
662
webpackEmptyAsyncContext.id = ${JSON.stringify(id)};`;
663
	}
664

    
665
	getSourceString(asyncMode, runtimeTemplate) {
666
		if (asyncMode === "lazy") {
667
			if (this.blocks && this.blocks.length > 0) {
668
				return this.getLazySource(this.blocks, this.id);
669
			}
670
			return this.getSourceForEmptyAsyncContext(this.id);
671
		}
672
		if (asyncMode === "eager") {
673
			if (this.dependencies && this.dependencies.length > 0) {
674
				return this.getEagerSource(this.dependencies, this.id);
675
			}
676
			return this.getSourceForEmptyAsyncContext(this.id);
677
		}
678
		if (asyncMode === "lazy-once") {
679
			const block = this.blocks[0];
680
			if (block) {
681
				return this.getLazyOnceSource(
682
					block,
683
					block.dependencies,
684
					this.id,
685
					runtimeTemplate
686
				);
687
			}
688
			return this.getSourceForEmptyAsyncContext(this.id);
689
		}
690
		if (asyncMode === "async-weak") {
691
			if (this.dependencies && this.dependencies.length > 0) {
692
				return this.getAsyncWeakSource(this.dependencies, this.id);
693
			}
694
			return this.getSourceForEmptyAsyncContext(this.id);
695
		}
696
		if (asyncMode === "weak") {
697
			if (this.dependencies && this.dependencies.length > 0) {
698
				return this.getWeakSyncSource(this.dependencies, this.id);
699
			}
700
		}
701
		if (this.dependencies && this.dependencies.length > 0) {
702
			return this.getSyncSource(this.dependencies, this.id);
703
		}
704
		return this.getSourceForEmptyContext(this.id);
705
	}
706

    
707
	getSource(sourceString) {
708
		if (this.useSourceMap) {
709
			return new OriginalSource(sourceString, this.identifier());
710
		}
711
		return new RawSource(sourceString);
712
	}
713

    
714
	source(dependencyTemplates, runtimeTemplate) {
715
		return this.getSource(
716
			this.getSourceString(this.options.mode, runtimeTemplate)
717
		);
718
	}
719

    
720
	size() {
721
		// base penalty
722
		const initialSize = 160;
723

    
724
		// if we dont have dependencies we stop here.
725
		return this.dependencies.reduce((size, dependency) => {
726
			const element = /** @type {ContextElementDependency} */ (dependency);
727
			return size + 5 + element.userRequest.length;
728
		}, initialSize);
729
	}
730
}
731

    
732
// TODO remove in webpack 5
733
Object.defineProperty(ContextModule.prototype, "recursive", {
734
	configurable: false,
735
	get: util.deprecate(
736
		/**
737
		 * @deprecated
738
		 * @this {ContextModule}
739
		 * @returns {boolean} is recursive
740
		 */
741
		function() {
742
			return this.options.recursive;
743
		},
744
		"ContextModule.recursive has been moved to ContextModule.options.recursive"
745
	),
746
	set: util.deprecate(
747
		/**
748
		 * @deprecated
749
		 * @this {ContextModule}
750
		 * @param {boolean} value is recursive
751
		 * @returns {void}
752
		 */
753
		function(value) {
754
			this.options.recursive = value;
755
		},
756
		"ContextModule.recursive has been moved to ContextModule.options.recursive"
757
	)
758
});
759

    
760
// TODO remove in webpack 5
761
Object.defineProperty(ContextModule.prototype, "regExp", {
762
	configurable: false,
763
	get: util.deprecate(
764
		/**
765
		 * @deprecated
766
		 * @this {ContextModule}
767
		 * @returns {RegExp} regular expression
768
		 */
769
		function() {
770
			return this.options.regExp;
771
		},
772
		"ContextModule.regExp has been moved to ContextModule.options.regExp"
773
	),
774
	set: util.deprecate(
775
		/**
776
		 * @deprecated
777
		 * @this {ContextModule}
778
		 * @param {RegExp} value Regular expression
779
		 * @returns {void}
780
		 */
781
		function(value) {
782
			this.options.regExp = value;
783
		},
784
		"ContextModule.regExp has been moved to ContextModule.options.regExp"
785
	)
786
});
787

    
788
// TODO remove in webpack 5
789
Object.defineProperty(ContextModule.prototype, "addon", {
790
	configurable: false,
791
	get: util.deprecate(
792
		/**
793
		 * @deprecated
794
		 * @this {ContextModule}
795
		 * @returns {string} addon
796
		 */
797
		function() {
798
			return this.options.addon;
799
		},
800
		"ContextModule.addon has been moved to ContextModule.options.addon"
801
	),
802
	set: util.deprecate(
803
		/**
804
		 * @deprecated
805
		 * @this {ContextModule}
806
		 * @param {string} value addon
807
		 * @returns {void}
808
		 */
809
		function(value) {
810
			this.options.addon = value;
811
		},
812
		"ContextModule.addon has been moved to ContextModule.options.addon"
813
	)
814
});
815

    
816
// TODO remove in webpack 5
817
Object.defineProperty(ContextModule.prototype, "async", {
818
	configurable: false,
819
	get: util.deprecate(
820
		/**
821
		 * @deprecated
822
		 * @this {ContextModule}
823
		 * @returns {boolean} is async
824
		 */
825
		function() {
826
			return this.options.mode;
827
		},
828
		"ContextModule.async has been moved to ContextModule.options.mode"
829
	),
830
	set: util.deprecate(
831
		/**
832
		 * @deprecated
833
		 * @this {ContextModule}
834
		 * @param {ContextMode} value Context mode
835
		 * @returns {void}
836
		 */
837
		function(value) {
838
			this.options.mode = value;
839
		},
840
		"ContextModule.async has been moved to ContextModule.options.mode"
841
	)
842
});
843

    
844
// TODO remove in webpack 5
845
Object.defineProperty(ContextModule.prototype, "chunkName", {
846
	configurable: false,
847
	get: util.deprecate(
848
		/**
849
		 * @deprecated
850
		 * @this {ContextModule}
851
		 * @returns {string} chunk name
852
		 */
853
		function() {
854
			return this.options.chunkName;
855
		},
856
		"ContextModule.chunkName has been moved to ContextModule.options.chunkName"
857
	),
858
	set: util.deprecate(
859
		/**
860
		 * @deprecated
861
		 * @this {ContextModule}
862
		 * @param {string} value chunk name
863
		 * @returns {void}
864
		 */
865
		function(value) {
866
			this.options.chunkName = value;
867
		},
868
		"ContextModule.chunkName has been moved to ContextModule.options.chunkName"
869
	)
870
});
871

    
872
module.exports = ContextModule;
(22-22/144)