source: frontend/node_modules/webpack/lib/ContextModule.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: 43.4 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 { OriginalSource, RawSource } = require("webpack-sources");
9const AsyncDependenciesBlock = require("./AsyncDependenciesBlock");
10const Module = require("./Module");
11const {
12 JAVASCRIPT_TYPE,
13 JAVASCRIPT_TYPES
14} = require("./ModuleSourceTypeConstants");
15const { JAVASCRIPT_MODULE_TYPE_DYNAMIC } = require("./ModuleTypeConstants");
16const RuntimeGlobals = require("./RuntimeGlobals");
17const Template = require("./Template");
18const {
19 getOutgoingAsyncModules
20} = require("./async-modules/AsyncModuleHelpers");
21const { ImportPhase, ImportPhaseUtils } = require("./dependencies/ImportPhase");
22const { makeWebpackError } = require("./errors/HookWebpackError");
23const WebpackError = require("./errors/WebpackError");
24const {
25 compareLocations,
26 compareModulesById,
27 compareSelect,
28 concatComparators,
29 keepOriginalOrder
30} = require("./util/comparators");
31const {
32 contextify,
33 makePathsRelative,
34 parseResource
35} = require("./util/identifier");
36const makeSerializable = require("./util/makeSerializable");
37
38/** @typedef {import("webpack-sources").Source} Source */
39/** @typedef {import("../declarations/WebpackOptions").ResolveOptions} ResolveOptions */
40/** @typedef {import("./config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
41/** @typedef {import("./Chunk")} Chunk */
42/** @typedef {import("./Chunk").ChunkId} ChunkId */
43/** @typedef {import("./Chunk").ChunkName} ChunkName */
44/** @typedef {import("./ChunkGraph")} ChunkGraph */
45/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */
46/** @typedef {import("./ChunkGroup").RawChunkGroupOptions} RawChunkGroupOptions */
47/** @typedef {import("./Compilation")} Compilation */
48/** @typedef {import("./Dependency")} Dependency */
49/** @typedef {import("./Dependency").RawReferencedExports} RawReferencedExports */
50/** @typedef {import("./Generator").SourceTypes} SourceTypes */
51/** @typedef {import("./Module").BuildCallback} BuildCallback */
52/** @typedef {import("./Module").BuildInfo} BuildInfo */
53/** @typedef {import("./Module").FileSystemDependencies} FileSystemDependencies */
54/** @typedef {import("./Module").BuildMeta} BuildMeta */
55/** @typedef {import("./Module").CodeGenerationContext} CodeGenerationContext */
56/** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */
57/** @typedef {import("./Module").LibIdentOptions} LibIdentOptions */
58/** @typedef {import("./Module").LibIdent} LibIdent */
59/** @typedef {import("./Module").NeedBuildCallback} NeedBuildCallback */
60/** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */
61/** @typedef {import("./Module").RuntimeRequirements} RuntimeRequirements */
62/** @typedef {import("./Module").Sources} Sources */
63/** @typedef {import("./RequestShortener")} RequestShortener */
64/** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */
65/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
66/** @typedef {import("./dependencies/ContextElementDependency")} ContextElementDependency */
67/** @typedef {import("./javascript/JavascriptParser").ImportAttributes} ImportAttributes */
68/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
69/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
70/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
71/** @typedef {import("./dependencies/ImportPhase").ImportPhaseType} ImportPhaseType */
72
73/** @typedef {"sync" | "eager" | "weak" | "async-weak" | "lazy" | "lazy-once"} ContextMode Context mode */
74
75/**
76 * @typedef {object} ContextOptions
77 * @property {ContextMode} mode
78 * @property {boolean} recursive
79 * @property {RegExp | false | null} regExp
80 * @property {"strict" | boolean=} namespaceObject
81 * @property {string=} addon
82 * @property {ChunkName=} chunkName
83 * @property {RegExp | null=} include
84 * @property {RegExp | null=} exclude
85 * @property {RawChunkGroupOptions=} groupOptions
86 * @property {string=} typePrefix
87 * @property {string=} category
88 * @property {RawReferencedExports | null=} referencedExports exports referenced from modules (won't be mangled)
89 * @property {string | null=} layer
90 * @property {ImportAttributes=} attributes
91 * @property {ImportPhaseType=} phase
92 */
93
94/**
95 * @typedef {object} ContextModuleOptionsExtras
96 * @property {false | string | string[]} resource
97 * @property {string=} resourceQuery
98 * @property {string=} resourceFragment
99 * @property {ResolveOptions=} resolveOptions
100 */
101
102/** @typedef {ContextOptions & ContextModuleOptionsExtras} ContextModuleOptions */
103
104/**
105 * @callback ResolveDependenciesCallback
106 * @param {Error | null} err
107 * @param {ContextElementDependency[]=} dependencies
108 * @returns {void}
109 */
110
111/**
112 * @callback ResolveDependencies
113 * @param {InputFileSystem} fs
114 * @param {ContextModuleOptions} options
115 * @param {ResolveDependenciesCallback} callback
116 */
117
118/** @typedef {1 | 3 | 7 | 9} FakeMapType */
119
120/** @typedef {Record<ModuleId, FakeMapType>} FakeMap */
121/** @typedef {Record<string, ModuleId>} UserRequestMap */
122/** @typedef {Record<ModuleId, ModuleId[]>} UserRequestsMap */
123
124class ContextModule extends Module {
125 /**
126 * @param {ResolveDependencies} resolveDependencies function to get dependencies in this context
127 * @param {ContextModuleOptions} options options object
128 */
129 constructor(resolveDependencies, options) {
130 if (!options || typeof options.resource === "string") {
131 const parsed = parseResource(
132 options ? /** @type {string} */ (options.resource) : ""
133 );
134 const resource = parsed.path;
135 const resourceQuery = (options && options.resourceQuery) || parsed.query;
136 const resourceFragment =
137 (options && options.resourceFragment) || parsed.fragment;
138 const layer = options && options.layer;
139
140 super(JAVASCRIPT_MODULE_TYPE_DYNAMIC, resource, layer);
141 /** @type {ContextModuleOptions} */
142 this.options = {
143 ...options,
144 resource,
145 resourceQuery,
146 resourceFragment
147 };
148 } else {
149 super(JAVASCRIPT_MODULE_TYPE_DYNAMIC, undefined, options.layer);
150 /** @type {ContextModuleOptions} */
151 this.options = {
152 ...options,
153 resource: options.resource,
154 resourceQuery: options.resourceQuery || "",
155 resourceFragment: options.resourceFragment || ""
156 };
157 }
158
159 // Info from Factory
160 /** @type {ResolveDependencies | undefined} */
161 this.resolveDependencies = resolveDependencies;
162 if (options && options.resolveOptions !== undefined) {
163 this.resolveOptions = options.resolveOptions;
164 }
165
166 if (options && typeof options.mode !== "string") {
167 throw new Error("options.mode is a required option");
168 }
169
170 this._identifier = this._createIdentifier();
171 this._forceBuild = true;
172 }
173
174 /**
175 * Returns the source types this module can generate.
176 * @returns {SourceTypes} types available (do not mutate)
177 */
178 getSourceTypes() {
179 return JAVASCRIPT_TYPES;
180 }
181
182 /**
183 * Assuming this module is in the cache. Update the (cached) module with
184 * the fresh module from the factory. Usually updates internal references
185 * and properties.
186 * @param {Module} module fresh module
187 * @returns {void}
188 */
189 updateCacheModule(module) {
190 const m = /** @type {ContextModule} */ (module);
191 this.resolveDependencies = m.resolveDependencies;
192 this.options = m.options;
193 }
194
195 /**
196 * Assuming this module is in the cache. Remove internal references to allow freeing some memory.
197 */
198 cleanupForCache() {
199 super.cleanupForCache();
200 this.resolveDependencies = undefined;
201 }
202
203 /**
204 * @private
205 * @param {RegExp} regexString RegExp as a string
206 * @param {boolean=} stripSlash do we need to strip a slsh
207 * @returns {string} pretty RegExp
208 */
209 _prettyRegExp(regexString, stripSlash = true) {
210 const str = stripSlash
211 ? regexString.source + regexString.flags
212 : `${regexString}`;
213 return str.replace(/!/g, "%21").replace(/\|/g, "%7C");
214 }
215
216 _createIdentifier() {
217 let identifier =
218 this.context ||
219 (typeof this.options.resource === "string" ||
220 this.options.resource === false
221 ? `${this.options.resource}`
222 : this.options.resource.join("|"));
223 if (this.options.resourceQuery) {
224 identifier += `|${this.options.resourceQuery}`;
225 }
226 if (this.options.resourceFragment) {
227 identifier += `|${this.options.resourceFragment}`;
228 }
229 if (this.options.mode) {
230 identifier += `|${this.options.mode}`;
231 }
232 if (!this.options.recursive) {
233 identifier += "|nonrecursive";
234 }
235 if (this.options.addon) {
236 identifier += `|${this.options.addon}`;
237 }
238 if (this.options.regExp) {
239 identifier += `|${this._prettyRegExp(this.options.regExp, false)}`;
240 }
241 if (this.options.include) {
242 identifier += `|include: ${this._prettyRegExp(
243 this.options.include,
244 false
245 )}`;
246 }
247 if (this.options.exclude) {
248 identifier += `|exclude: ${this._prettyRegExp(
249 this.options.exclude,
250 false
251 )}`;
252 }
253 if (this.options.referencedExports) {
254 identifier += `|referencedExports: ${JSON.stringify(
255 this.options.referencedExports
256 )}`;
257 }
258 if (this.options.chunkName) {
259 identifier += `|chunkName: ${this.options.chunkName}`;
260 }
261 if (this.options.groupOptions) {
262 identifier += `|groupOptions: ${JSON.stringify(
263 this.options.groupOptions
264 )}`;
265 }
266 if (this.options.namespaceObject === "strict") {
267 identifier += "|strict namespace object";
268 } else if (this.options.namespaceObject) {
269 identifier += "|namespace object";
270 }
271 if (this.options.attributes) {
272 identifier += `|importAttributes: ${JSON.stringify(this.options.attributes)}`;
273 }
274 if (this.options.phase) {
275 identifier += `|importPhase: ${this.options.phase}`;
276 }
277 if (this.layer) {
278 identifier += `|layer: ${this.layer}`;
279 }
280 return identifier;
281 }
282
283 /**
284 * Returns the unique identifier used to reference this module.
285 * @returns {string} a unique identifier of the module
286 */
287 identifier() {
288 return this._identifier;
289 }
290
291 /**
292 * Returns a human-readable identifier for this module.
293 * @param {RequestShortener} requestShortener the request shortener
294 * @returns {string} a user readable identifier of the module
295 */
296 readableIdentifier(requestShortener) {
297 /** @type {string} */
298 let identifier;
299
300 if (this.context) {
301 identifier = `${requestShortener.shorten(this.context)}/`;
302 } else if (
303 typeof this.options.resource === "string" ||
304 this.options.resource === false
305 ) {
306 identifier = `${requestShortener.shorten(`${this.options.resource}`)}/`;
307 } else {
308 identifier = this.options.resource
309 .map((r) => `${requestShortener.shorten(r)}/`)
310 .join(" ");
311 }
312 if (this.options.resourceQuery) {
313 identifier += ` ${this.options.resourceQuery}`;
314 }
315 if (this.options.mode) {
316 identifier += ` ${this.options.mode}`;
317 }
318 if (!this.options.recursive) {
319 identifier += " nonrecursive";
320 }
321 if (this.options.addon) {
322 identifier += ` ${requestShortener.shorten(this.options.addon)}`;
323 }
324 if (this.options.regExp) {
325 identifier += ` ${this._prettyRegExp(this.options.regExp)}`;
326 }
327 if (this.options.include) {
328 identifier += ` include: ${this._prettyRegExp(this.options.include)}`;
329 }
330 if (this.options.exclude) {
331 identifier += ` exclude: ${this._prettyRegExp(this.options.exclude)}`;
332 }
333 if (this.options.referencedExports) {
334 identifier += ` referencedExports: ${this.options.referencedExports
335 .map((e) => e.join("."))
336 .join(", ")}`;
337 }
338 if (this.options.chunkName) {
339 identifier += ` chunkName: ${this.options.chunkName}`;
340 }
341 if (this.options.groupOptions) {
342 const groupOptions = this.options.groupOptions;
343 for (const key of Object.keys(groupOptions)) {
344 identifier += ` ${key}: ${
345 groupOptions[/** @type {keyof RawChunkGroupOptions} */ (key)]
346 }`;
347 }
348 }
349 if (this.options.namespaceObject === "strict") {
350 identifier += " strict namespace object";
351 } else if (this.options.namespaceObject) {
352 identifier += " namespace object";
353 }
354
355 return identifier;
356 }
357
358 /**
359 * Gets the library identifier.
360 * @param {LibIdentOptions} options options
361 * @returns {LibIdent | null} an identifier for library inclusion
362 */
363 libIdent(options) {
364 /** @type {string} */
365 let identifier;
366
367 if (this.context) {
368 identifier = contextify(
369 options.context,
370 this.context,
371 options.associatedObjectForCache
372 );
373 } else if (typeof this.options.resource === "string") {
374 identifier = contextify(
375 options.context,
376 this.options.resource,
377 options.associatedObjectForCache
378 );
379 } else if (this.options.resource === false) {
380 identifier = "false";
381 } else {
382 identifier = this.options.resource
383 .map((res) =>
384 contextify(options.context, res, options.associatedObjectForCache)
385 )
386 .join(" ");
387 }
388
389 if (this.layer) identifier = `(${this.layer})/${identifier}`;
390 if (this.options.mode) {
391 identifier += ` ${this.options.mode}`;
392 }
393 if (this.options.recursive) {
394 identifier += " recursive";
395 }
396 if (this.options.addon) {
397 identifier += ` ${contextify(
398 options.context,
399 this.options.addon,
400 options.associatedObjectForCache
401 )}`;
402 }
403 if (this.options.regExp) {
404 identifier += ` ${this._prettyRegExp(this.options.regExp)}`;
405 }
406 if (this.options.include) {
407 identifier += ` include: ${this._prettyRegExp(this.options.include)}`;
408 }
409 if (this.options.exclude) {
410 identifier += ` exclude: ${this._prettyRegExp(this.options.exclude)}`;
411 }
412 if (this.options.referencedExports) {
413 identifier += ` referencedExports: ${this.options.referencedExports
414 .map((e) => e.join("."))
415 .join(", ")}`;
416 }
417
418 return identifier;
419 }
420
421 /**
422 * Invalidates the cached state associated with this value.
423 * @returns {void}
424 */
425 invalidateBuild() {
426 this._forceBuild = true;
427 }
428
429 /**
430 * Checks whether the module needs to be rebuilt for the current build state.
431 * @param {NeedBuildContext} context context info
432 * @param {NeedBuildCallback} callback callback function, returns true, if the module needs a rebuild
433 * @returns {void}
434 */
435 needBuild({ fileSystemInfo }, callback) {
436 // build if enforced
437 if (this._forceBuild) return callback(null, true);
438
439 const buildInfo = /** @type {BuildInfo} */ (this.buildInfo);
440
441 // always build when we have no snapshot and context
442 if (!buildInfo.snapshot) {
443 return callback(null, Boolean(this.context || this.options.resource));
444 }
445
446 fileSystemInfo.checkSnapshotValid(buildInfo.snapshot, (err, valid) => {
447 callback(err, !valid);
448 });
449 }
450
451 /**
452 * Builds the module using the provided compilation context.
453 * @param {WebpackOptions} options webpack options
454 * @param {Compilation} compilation the compilation
455 * @param {ResolverWithOptions} resolver the resolver
456 * @param {InputFileSystem} fs the file system
457 * @param {BuildCallback} callback callback function
458 * @returns {void}
459 */
460 build(options, compilation, resolver, fs, callback) {
461 this._forceBuild = false;
462 /** @type {BuildMeta} */
463 this.buildMeta = {
464 exportsType: "default",
465 defaultObject: "redirect-warn"
466 };
467 this.buildInfo = {
468 snapshot: undefined
469 };
470 this.dependencies.length = 0;
471 this.blocks.length = 0;
472 const startTime = Date.now();
473 /** @type {ResolveDependencies} */
474 (this.resolveDependencies)(fs, this.options, (err, dependencies) => {
475 if (err) {
476 return callback(
477 makeWebpackError(err, "ContextModule.resolveDependencies")
478 );
479 }
480
481 // abort if something failed
482 // this will create an empty context
483 if (!dependencies) {
484 callback();
485 return;
486 }
487
488 // enhance dependencies with meta info
489 for (const dep of dependencies) {
490 dep.loc = {
491 name: dep.userRequest
492 };
493 dep.request = this.options.addon + dep.request;
494 }
495 dependencies.sort(
496 concatComparators(
497 compareSelect((a) => a.loc, compareLocations),
498 keepOriginalOrder(this.dependencies)
499 )
500 );
501
502 if (this.options.mode === "sync" || this.options.mode === "eager") {
503 // if we have an sync or eager context
504 // just add all dependencies and continue
505 this.dependencies = dependencies;
506 } else if (this.options.mode === "lazy-once") {
507 // for the lazy-once mode create a new async dependency block
508 // and add that block to this context
509 if (dependencies.length > 0) {
510 const block = new AsyncDependenciesBlock({
511 ...this.options.groupOptions,
512 name: this.options.chunkName
513 });
514 for (const dep of dependencies) {
515 block.addDependency(dep);
516 }
517 this.addBlock(block);
518 }
519 } else if (
520 this.options.mode === "weak" ||
521 this.options.mode === "async-weak"
522 ) {
523 // we mark all dependencies as weak
524 for (const dep of dependencies) {
525 dep.weak = true;
526 }
527 this.dependencies = dependencies;
528 } else if (this.options.mode === "lazy") {
529 // if we are lazy create a new async dependency block per dependency
530 // and add all blocks to this context
531 let index = 0;
532 for (const dep of dependencies) {
533 let chunkName = this.options.chunkName;
534 if (chunkName) {
535 if (!/\[(?:index|request)\]/.test(chunkName)) {
536 chunkName += "[index]";
537 }
538 chunkName = chunkName.replace(/\[index\]/g, `${index++}`);
539 chunkName = chunkName.replace(
540 /\[request\]/g,
541 Template.toPath(dep.userRequest)
542 );
543 }
544 const block = new AsyncDependenciesBlock(
545 {
546 ...this.options.groupOptions,
547 name: chunkName
548 },
549 dep.loc,
550 dep.userRequest
551 );
552 block.addDependency(dep);
553 this.addBlock(block);
554 }
555 } else {
556 callback(
557 new WebpackError(`Unsupported mode "${this.options.mode}" in context`)
558 );
559 return;
560 }
561 if (!this.context && !this.options.resource) return callback();
562
563 const snapshotOptions = compilation.options.snapshot.contextModule;
564
565 compilation.fileSystemInfo.createSnapshot(
566 startTime,
567 null,
568 this.context
569 ? [this.context]
570 : typeof this.options.resource === "string"
571 ? [this.options.resource]
572 : /** @type {string[]} */ (this.options.resource),
573 null,
574 snapshotOptions,
575 (err, snapshot) => {
576 if (err) return callback(err);
577 /** @type {BuildInfo} */
578 (this.buildInfo).snapshot = snapshot;
579 callback();
580 }
581 );
582 });
583 }
584
585 /**
586 * Adds the provided file dependencies to the module.
587 * @param {FileSystemDependencies} fileDependencies set where file dependencies are added to
588 * @param {FileSystemDependencies} contextDependencies set where context dependencies are added to
589 * @param {FileSystemDependencies} missingDependencies set where missing dependencies are added to
590 * @param {FileSystemDependencies} buildDependencies set where build dependencies are added to
591 */
592 addCacheDependencies(
593 fileDependencies,
594 contextDependencies,
595 missingDependencies,
596 buildDependencies
597 ) {
598 if (this.context) {
599 contextDependencies.add(this.context);
600 } else if (typeof this.options.resource === "string") {
601 contextDependencies.add(this.options.resource);
602 } else if (this.options.resource === false) {
603 // Do nothing
604 } else {
605 for (const res of this.options.resource) contextDependencies.add(res);
606 }
607 }
608
609 /**
610 * @param {Dependency[]} dependencies all dependencies
611 * @param {ChunkGraph} chunkGraph chunk graph
612 * @returns {UserRequestMap} map with user requests
613 */
614 getUserRequestMap(dependencies, chunkGraph) {
615 const moduleGraph = chunkGraph.moduleGraph;
616 // if we filter first we get a new array
617 // therefore we don't need to create a clone of dependencies explicitly
618 // therefore the order of this is !important!
619 const sortedDependencies =
620 /** @type {ContextElementDependency[]} */
621 (dependencies)
622 .filter((dependency) => moduleGraph.getModule(dependency))
623 .sort((a, b) => {
624 if (a.userRequest === b.userRequest) {
625 return 0;
626 }
627 return a.userRequest < b.userRequest ? -1 : 1;
628 });
629 /** @type {UserRequestMap} */
630 const map = Object.create(null);
631 for (const dep of sortedDependencies) {
632 const module = /** @type {Module} */ (moduleGraph.getModule(dep));
633 map[dep.userRequest] =
634 /** @type {ModuleId} */
635 (chunkGraph.getModuleId(module));
636 }
637 return map;
638 }
639
640 /**
641 * @param {Dependency[]} dependencies all dependencies
642 * @param {ChunkGraph} chunkGraph chunk graph
643 * @returns {FakeMap | FakeMapType} fake map
644 */
645 getFakeMap(dependencies, chunkGraph) {
646 if (!this.options.namespaceObject) {
647 return 9;
648 }
649 const moduleGraph = chunkGraph.moduleGraph;
650 // bitfield
651 let hasType = 0;
652 const comparator = compareModulesById(chunkGraph);
653 // if we filter first we get a new array
654 // therefore we don't need to create a clone of dependencies explicitly
655 // therefore the order of this is !important!
656 const sortedModules = dependencies
657 .map(
658 (dependency) =>
659 /** @type {Module} */ (moduleGraph.getModule(dependency))
660 )
661 .filter(Boolean)
662 .sort(comparator);
663 /** @type {FakeMap} */
664 const fakeMap = Object.create(null);
665 for (const module of sortedModules) {
666 const exportsType = module.getExportsType(
667 moduleGraph,
668 this.options.namespaceObject === "strict"
669 );
670 const id = /** @type {ModuleId} */ (chunkGraph.getModuleId(module));
671 switch (exportsType) {
672 case "namespace":
673 fakeMap[id] = 9;
674 hasType |= 1;
675 break;
676 case "dynamic":
677 fakeMap[id] = 7;
678 hasType |= 2;
679 break;
680 case "default-only":
681 fakeMap[id] = 1;
682 hasType |= 4;
683 break;
684 case "default-with-named":
685 fakeMap[id] = 3;
686 hasType |= 8;
687 break;
688 default:
689 throw new Error(`Unexpected exports type ${exportsType}`);
690 }
691 }
692 if (hasType === 1) {
693 return 9;
694 }
695 if (hasType === 2) {
696 return 7;
697 }
698 if (hasType === 4) {
699 return 1;
700 }
701 if (hasType === 8) {
702 return 3;
703 }
704 if (hasType === 0) {
705 return 9;
706 }
707 return fakeMap;
708 }
709
710 /**
711 * @param {FakeMap | FakeMapType} fakeMap fake map
712 * @returns {string} fake map init statement
713 */
714 getFakeMapInitStatement(fakeMap) {
715 return typeof fakeMap === "object"
716 ? `var fakeMap = ${JSON.stringify(fakeMap, null, "\t")};`
717 : "";
718 }
719
720 /**
721 * @param {Dependency[]} dependencies all dependencies
722 * @param {ChunkGraph} chunkGraph chunk graph
723 * @returns {UserRequestsMap} map with user requests
724 */
725 getModuleDeferredAsyncDepsMap(dependencies, chunkGraph) {
726 const moduleGraph = chunkGraph.moduleGraph;
727 const comparator = compareModulesById(chunkGraph);
728 // if we filter first we get a new array
729 // therefore we don't need to create a clone of dependencies explicitly
730 // therefore the order of this is !important!
731 const sortedModules = dependencies
732 .map(
733 (dependency) =>
734 /** @type {Module} */ (moduleGraph.getModule(dependency))
735 )
736 .filter(Boolean)
737 .sort(comparator);
738 /** @type {UserRequestsMap} */
739 const map = Object.create(null);
740 for (const module of sortedModules) {
741 if (!(/** @type {BuildMeta} */ (module.buildMeta).async)) {
742 const id = /** @type {ModuleId} */ (chunkGraph.getModuleId(module));
743 map[id] = Array.from(
744 getOutgoingAsyncModules(chunkGraph.moduleGraph, module),
745 (m) => chunkGraph.getModuleId(m)
746 ).filter((id) => id !== null);
747 }
748 }
749 return map;
750 }
751
752 /**
753 * @param {false | UserRequestsMap} asyncDepsMap fake map
754 * @returns {string} async deps map init statement
755 */
756 getModuleDeferredAsyncDepsMapInitStatement(asyncDepsMap) {
757 return typeof asyncDepsMap === "object"
758 ? `var asyncDepsMap = ${JSON.stringify(asyncDepsMap, null, "\t")};`
759 : "";
760 }
761
762 /**
763 * @param {FakeMapType} type type
764 * @param {boolean=} asyncModule is async module
765 * @returns {string} return result
766 */
767 getReturn(type, asyncModule) {
768 if (type === 9) {
769 return `${RuntimeGlobals.require}(id)`;
770 }
771 return `${RuntimeGlobals.createFakeNamespaceObject}(id, ${type}${
772 asyncModule ? " | 16" : ""
773 })`;
774 }
775
776 /**
777 * @param {FakeMap | FakeMapType} fakeMap fake map
778 * @param {boolean=} asyncModule is async module
779 * @param {string=} asyncDeps async deps for deferred module
780 * @param {string=} fakeMapDataExpression fake map data expression
781 * @returns {string} module object source
782 */
783 getReturnModuleObjectSource(
784 fakeMap,
785 asyncModule,
786 asyncDeps,
787 fakeMapDataExpression = "fakeMap[id]"
788 ) {
789 const source =
790 typeof fakeMap === "number"
791 ? this.getReturn(fakeMap, asyncModule)
792 : `${RuntimeGlobals.createFakeNamespaceObject}(id, ${fakeMapDataExpression}${asyncModule ? " | 16" : ""})`;
793 if (asyncDeps) {
794 if (!asyncModule) {
795 throw new Error("Must be async when module is deferred");
796 }
797 const type =
798 typeof fakeMap === "number" ? fakeMap : fakeMapDataExpression;
799 return `${asyncDeps} ? ${asyncDeps}.length ? ${RuntimeGlobals.deferredModuleAsyncTransitiveDependencies}(${asyncDeps}).then(${RuntimeGlobals.makeDeferredNamespaceObject}.bind(${RuntimeGlobals.require}, id, ${type} ^ 1, true)) : ${RuntimeGlobals.makeDeferredNamespaceObject}(id, ${type} ^ 1 | 16) : ${source}`;
800 }
801 return source;
802 }
803
804 /**
805 * @param {Dependency[]} dependencies dependencies
806 * @param {ModuleId} id module id
807 * @param {ChunkGraph} chunkGraph the chunk graph
808 * @returns {string} source code
809 */
810 getSyncSource(dependencies, id, chunkGraph) {
811 const map = this.getUserRequestMap(dependencies, chunkGraph);
812 const fakeMap = this.getFakeMap(dependencies, chunkGraph);
813 const returnModuleObject = this.getReturnModuleObjectSource(fakeMap);
814
815 return `var map = ${JSON.stringify(map, null, "\t")};
816${this.getFakeMapInitStatement(fakeMap)}
817
818function webpackContext(req) {
819 var id = webpackContextResolve(req);
820 return ${returnModuleObject};
821}
822function webpackContextResolve(req) {
823 if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
824 var e = new Error("Cannot find module '" + req + "'");
825 e.code = 'MODULE_NOT_FOUND';
826 throw e;
827 }
828 return map[req];
829}
830webpackContext.keys = function webpackContextKeys() {
831 return Object.keys(map);
832};
833webpackContext.resolve = webpackContextResolve;
834module.exports = webpackContext;
835webpackContext.id = ${JSON.stringify(id)};`;
836 }
837
838 /**
839 * @param {Dependency[]} dependencies dependencies
840 * @param {ModuleId} id module id
841 * @param {ChunkGraph} chunkGraph the chunk graph
842 * @returns {string} source code
843 */
844 getWeakSyncSource(dependencies, id, chunkGraph) {
845 const map = this.getUserRequestMap(dependencies, chunkGraph);
846 const fakeMap = this.getFakeMap(dependencies, chunkGraph);
847 const returnModuleObject = this.getReturnModuleObjectSource(fakeMap);
848
849 return `var map = ${JSON.stringify(map, null, "\t")};
850${this.getFakeMapInitStatement(fakeMap)}
851
852function webpackContext(req) {
853 var id = webpackContextResolve(req);
854 if(!${RuntimeGlobals.moduleFactories}[id]) {
855 var e = new Error("Module '" + req + "' ('" + id + "') is not available (weak dependency)");
856 e.code = 'MODULE_NOT_FOUND';
857 throw e;
858 }
859 return ${returnModuleObject};
860}
861function webpackContextResolve(req) {
862 if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
863 var e = new Error("Cannot find module '" + req + "'");
864 e.code = 'MODULE_NOT_FOUND';
865 throw e;
866 }
867 return map[req];
868}
869webpackContext.keys = function webpackContextKeys() {
870 return Object.keys(map);
871};
872webpackContext.resolve = webpackContextResolve;
873webpackContext.id = ${JSON.stringify(id)};
874module.exports = webpackContext;`;
875 }
876
877 /**
878 * @param {Dependency[]} dependencies dependencies
879 * @param {ModuleId} id module id
880 * @param {ImportPhaseType} phase import phase
881 * @param {object} context context
882 * @param {ChunkGraph} context.chunkGraph the chunk graph
883 * @param {RuntimeTemplate} context.runtimeTemplate the chunk graph
884 * @returns {string} source code
885 */
886 getAsyncWeakSource(dependencies, id, phase, { chunkGraph, runtimeTemplate }) {
887 const map = this.getUserRequestMap(dependencies, chunkGraph);
888 const fakeMap = this.getFakeMap(dependencies, chunkGraph);
889 const asyncDepsMap =
890 ImportPhaseUtils.isDefer(phase) &&
891 this.getModuleDeferredAsyncDepsMap(dependencies, chunkGraph);
892 const returnModuleObject = this.getReturnModuleObjectSource(
893 fakeMap,
894 true,
895 asyncDepsMap ? "asyncDepsMap[id]" : undefined
896 );
897
898 return `var map = ${JSON.stringify(map, null, "\t")};
899${this.getFakeMapInitStatement(fakeMap)}
900${this.getModuleDeferredAsyncDepsMapInitStatement(asyncDepsMap)}
901
902function webpackAsyncContext(req) {
903 return webpackAsyncContextResolve(req).then(${runtimeTemplate.basicFunction(
904 "id",
905 [
906 `if(!${RuntimeGlobals.moduleFactories}[id]) {`,
907 Template.indent([
908 'var e = new Error("Module \'" + req + "\' (\'" + id + "\') is not available (weak dependency)");',
909 "e.code = 'MODULE_NOT_FOUND';",
910 "throw e;"
911 ]),
912 "}",
913 `return ${returnModuleObject};`
914 ]
915 )});
916}
917function webpackAsyncContextResolve(req) {
918 // Here Promise.resolve().then() is used instead of new Promise() to prevent
919 // uncaught exception popping up in devtools
920 return Promise.resolve().then(${runtimeTemplate.basicFunction("", [
921 `if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {`,
922 Template.indent([
923 'var e = new Error("Cannot find module \'" + req + "\'");',
924 "e.code = 'MODULE_NOT_FOUND';",
925 "throw e;"
926 ]),
927 "}",
928 "return map[req];"
929 ])});
930}
931webpackAsyncContext.keys = ${runtimeTemplate.returningFunction(
932 "Object.keys(map)"
933 )};
934webpackAsyncContext.resolve = webpackAsyncContextResolve;
935webpackAsyncContext.id = ${JSON.stringify(id)};
936module.exports = webpackAsyncContext;`;
937 }
938
939 /**
940 * @param {Dependency[]} dependencies dependencies
941 * @param {ModuleId} id module id
942 * @param {ImportPhaseType} phase import phase
943 * @param {object} context context
944 * @param {ChunkGraph} context.chunkGraph the chunk graph
945 * @param {RuntimeTemplate} context.runtimeTemplate the chunk graph
946 * @returns {string} source code
947 */
948 getEagerSource(dependencies, id, phase, { chunkGraph, runtimeTemplate }) {
949 const map = this.getUserRequestMap(dependencies, chunkGraph);
950 const fakeMap = this.getFakeMap(dependencies, chunkGraph);
951 const asyncDepsMap =
952 ImportPhaseUtils.isDefer(phase) &&
953 this.getModuleDeferredAsyncDepsMap(dependencies, chunkGraph);
954 const thenFunction = runtimeTemplate.returningFunction(
955 this.getReturnModuleObjectSource(
956 fakeMap,
957 true,
958 asyncDepsMap ? "asyncDepsMap[id]" : undefined
959 ),
960 "id"
961 );
962
963 return `var map = ${JSON.stringify(map, null, "\t")};
964${this.getFakeMapInitStatement(fakeMap)}
965${this.getModuleDeferredAsyncDepsMapInitStatement(asyncDepsMap)}
966
967function webpackAsyncContext(req) {
968 return webpackAsyncContextResolve(req).then(${thenFunction});
969}
970function webpackAsyncContextResolve(req) {
971 // Here Promise.resolve().then() is used instead of new Promise() to prevent
972 // uncaught exception popping up in devtools
973 return Promise.resolve().then(${runtimeTemplate.basicFunction("", [
974 `if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {`,
975 Template.indent([
976 'var e = new Error("Cannot find module \'" + req + "\'");',
977 "e.code = 'MODULE_NOT_FOUND';",
978 "throw e;"
979 ]),
980 "}",
981 "return map[req];"
982 ])});
983}
984webpackAsyncContext.keys = ${runtimeTemplate.returningFunction(
985 "Object.keys(map)"
986 )};
987webpackAsyncContext.resolve = webpackAsyncContextResolve;
988webpackAsyncContext.id = ${JSON.stringify(id)};
989module.exports = webpackAsyncContext;`;
990 }
991
992 /**
993 * @param {AsyncDependenciesBlock} block block
994 * @param {Dependency[]} dependencies dependencies
995 * @param {ModuleId} id module id
996 * @param {ImportPhaseType} phase import phase
997 * @param {object} options options object
998 * @param {RuntimeTemplate} options.runtimeTemplate the runtime template
999 * @param {ChunkGraph} options.chunkGraph the chunk graph
1000 * @returns {string} source code
1001 */
1002 getLazyOnceSource(
1003 block,
1004 dependencies,
1005 id,
1006 phase,
1007 { runtimeTemplate, chunkGraph }
1008 ) {
1009 const promise = runtimeTemplate.blockPromise({
1010 chunkGraph,
1011 block,
1012 message: "lazy-once context",
1013 /** @type {RuntimeRequirements} */
1014 runtimeRequirements: new Set()
1015 });
1016 const map = this.getUserRequestMap(dependencies, chunkGraph);
1017 const fakeMap = this.getFakeMap(dependencies, chunkGraph);
1018 const asyncDepsMap =
1019 ImportPhaseUtils.isDefer(phase) &&
1020 this.getModuleDeferredAsyncDepsMap(dependencies, chunkGraph);
1021 const thenFunction = runtimeTemplate.returningFunction(
1022 this.getReturnModuleObjectSource(
1023 fakeMap,
1024 true,
1025 asyncDepsMap ? "asyncDepsMap[id]" : undefined
1026 ),
1027 "id"
1028 );
1029
1030 return `var map = ${JSON.stringify(map, null, "\t")};
1031${this.getFakeMapInitStatement(fakeMap)}
1032${this.getModuleDeferredAsyncDepsMapInitStatement(asyncDepsMap)}
1033
1034function webpackAsyncContext(req) {
1035 return webpackAsyncContextResolve(req).then(${thenFunction});
1036}
1037function webpackAsyncContextResolve(req) {
1038 return ${promise}.then(${runtimeTemplate.basicFunction("", [
1039 `if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {`,
1040 Template.indent([
1041 'var e = new Error("Cannot find module \'" + req + "\'");',
1042 "e.code = 'MODULE_NOT_FOUND';",
1043 "throw e;"
1044 ]),
1045 "}",
1046 "return map[req];"
1047 ])});
1048}
1049webpackAsyncContext.keys = ${runtimeTemplate.returningFunction(
1050 "Object.keys(map)"
1051 )};
1052webpackAsyncContext.resolve = webpackAsyncContextResolve;
1053webpackAsyncContext.id = ${JSON.stringify(id)};
1054module.exports = webpackAsyncContext;`;
1055 }
1056
1057 /**
1058 * @param {AsyncDependenciesBlock[]} blocks blocks
1059 * @param {ModuleId} id module id
1060 * @param {ImportPhaseType} phase import phase
1061 * @param {object} context context
1062 * @param {ChunkGraph} context.chunkGraph the chunk graph
1063 * @param {RuntimeTemplate} context.runtimeTemplate the chunk graph
1064 * @returns {string} source code
1065 */
1066 getLazySource(blocks, id, phase, { chunkGraph, runtimeTemplate }) {
1067 const moduleGraph = chunkGraph.moduleGraph;
1068 let hasMultipleOrNoChunks = false;
1069 let hasNoChunk = true;
1070 let hasNoModuleDeferred = true;
1071 const fakeMap = this.getFakeMap(
1072 blocks.map((b) => b.dependencies[0]),
1073 chunkGraph
1074 );
1075 const hasFakeMap = typeof fakeMap === "object";
1076 /** @typedef {{ userRequest: string, dependency: ContextElementDependency, chunks: undefined | Chunk[], module: Module, block: AsyncDependenciesBlock, asyncDeps: undefined | ModuleId[] }} Item */
1077 /**
1078 * @type {Item[]}
1079 */
1080 const items = blocks
1081 .map((block) => {
1082 const dependency =
1083 /** @type {ContextElementDependency} */
1084 (block.dependencies[0]);
1085 return {
1086 dependency,
1087 module: /** @type {Module} */ (moduleGraph.getModule(dependency)),
1088 block,
1089 userRequest: dependency.userRequest,
1090 chunks: undefined,
1091 asyncDeps: undefined
1092 };
1093 })
1094 .filter((item) => item.module);
1095 for (const item of items) {
1096 const chunkGroup = chunkGraph.getBlockChunkGroup(item.block);
1097 const chunks = (chunkGroup && chunkGroup.chunks) || [];
1098 item.chunks = chunks;
1099 if (chunks.length > 0) {
1100 hasNoChunk = false;
1101 }
1102 if (chunks.length !== 1) {
1103 hasMultipleOrNoChunks = true;
1104 }
1105 const isModuleDeferred =
1106 ImportPhaseUtils.isDefer(phase) &&
1107 !(/** @type {BuildMeta} */ (item.module.buildMeta).async);
1108 if (isModuleDeferred) {
1109 const asyncDeps = Array.from(
1110 getOutgoingAsyncModules(chunkGraph.moduleGraph, item.module),
1111 (m) => chunkGraph.getModuleId(m)
1112 ).filter((id) => id !== null);
1113 item.asyncDeps = asyncDeps;
1114 hasNoModuleDeferred = false;
1115 }
1116 }
1117 const shortMode = hasNoChunk && hasNoModuleDeferred && !hasFakeMap;
1118 const sortedItems = items.sort((a, b) => {
1119 if (a.userRequest === b.userRequest) return 0;
1120 return a.userRequest < b.userRequest ? -1 : 1;
1121 });
1122 /** @type {Record<string, ModuleId | (ModuleId | FakeMapType | ChunkId[] | (ModuleId[] | undefined))[]>} */
1123 const map = Object.create(null);
1124 for (const item of sortedItems) {
1125 const moduleId =
1126 /** @type {ModuleId} */
1127 (chunkGraph.getModuleId(item.module));
1128 if (shortMode) {
1129 map[item.userRequest] = moduleId;
1130 } else {
1131 /** @type {(ModuleId | FakeMapType | ChunkId[] | (ModuleId[] | undefined))[]} */
1132 const array = [moduleId];
1133 if (hasFakeMap) {
1134 array.push(fakeMap[moduleId]);
1135 }
1136 if (!hasNoChunk) {
1137 array.push(
1138 /** @type {Chunk[]} */ (item.chunks).map(
1139 (chunk) => /** @type {ChunkId} */ (chunk.id)
1140 )
1141 );
1142 }
1143 if (!hasNoModuleDeferred) {
1144 array.push(item.asyncDeps);
1145 }
1146 map[item.userRequest] = array;
1147 }
1148 }
1149
1150 const chunksPosition = hasFakeMap ? 2 : 1;
1151 const asyncDepsPosition = chunksPosition + 1;
1152 const requestPrefix = hasNoChunk
1153 ? "Promise.resolve()"
1154 : hasMultipleOrNoChunks
1155 ? `Promise.all(ids[${chunksPosition}].map(${RuntimeGlobals.ensureChunk}))`
1156 : `${RuntimeGlobals.ensureChunk}(ids[${chunksPosition}][0])`;
1157 const returnModuleObject = this.getReturnModuleObjectSource(
1158 fakeMap,
1159 true,
1160 hasNoModuleDeferred ? undefined : `ids[${asyncDepsPosition}]`,
1161 shortMode ? "invalid" : "ids[1]"
1162 );
1163
1164 const webpackAsyncContext =
1165 requestPrefix === "Promise.resolve()"
1166 ? `
1167function webpackAsyncContext(req) {
1168 return Promise.resolve().then(${runtimeTemplate.basicFunction("", [
1169 `if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {`,
1170 Template.indent([
1171 'var e = new Error("Cannot find module \'" + req + "\'");',
1172 "e.code = 'MODULE_NOT_FOUND';",
1173 "throw e;"
1174 ]),
1175 "}",
1176 shortMode ? "var id = map[req];" : "var ids = map[req], id = ids[0];",
1177 `return ${returnModuleObject};`
1178 ])});
1179}`
1180 : `function webpackAsyncContext(req) {
1181 try {
1182 if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
1183 return Promise.resolve().then(${runtimeTemplate.basicFunction("", [
1184 'var e = new Error("Cannot find module \'" + req + "\'");',
1185 "e.code = 'MODULE_NOT_FOUND';",
1186 "throw e;"
1187 ])});
1188 }
1189 } catch(err) {
1190 return Promise.reject(err);
1191 }
1192
1193 var ids = map[req], id = ids[0];
1194 return ${requestPrefix}.then(${runtimeTemplate.returningFunction(returnModuleObject)});
1195}`;
1196
1197 return `var map = ${JSON.stringify(map, null, "\t")};
1198${webpackAsyncContext}
1199webpackAsyncContext.keys = ${runtimeTemplate.returningFunction(
1200 "Object.keys(map)"
1201 )};
1202webpackAsyncContext.id = ${JSON.stringify(id)};
1203module.exports = webpackAsyncContext;`;
1204 }
1205
1206 /**
1207 * @param {ModuleId} id module id
1208 * @param {RuntimeTemplate} runtimeTemplate runtime template
1209 * @returns {string} source for empty async context
1210 */
1211 getSourceForEmptyContext(id, runtimeTemplate) {
1212 return `function webpackEmptyContext(req) {
1213 var e = new Error("Cannot find module '" + req + "'");
1214 e.code = 'MODULE_NOT_FOUND';
1215 throw e;
1216}
1217webpackEmptyContext.keys = ${runtimeTemplate.returningFunction("[]")};
1218webpackEmptyContext.resolve = webpackEmptyContext;
1219webpackEmptyContext.id = ${JSON.stringify(id)};
1220module.exports = webpackEmptyContext;`;
1221 }
1222
1223 /**
1224 * @param {ModuleId} id module id
1225 * @param {RuntimeTemplate} runtimeTemplate runtime template
1226 * @returns {string} source for empty async context
1227 */
1228 getSourceForEmptyAsyncContext(id, runtimeTemplate) {
1229 return `function webpackEmptyAsyncContext(req) {
1230 // Here Promise.resolve().then() is used instead of new Promise() to prevent
1231 // uncaught exception popping up in devtools
1232 return Promise.resolve().then(${runtimeTemplate.basicFunction("", [
1233 'var e = new Error("Cannot find module \'" + req + "\'");',
1234 "e.code = 'MODULE_NOT_FOUND';",
1235 "throw e;"
1236 ])});
1237}
1238webpackEmptyAsyncContext.keys = ${runtimeTemplate.returningFunction("[]")};
1239webpackEmptyAsyncContext.resolve = webpackEmptyAsyncContext;
1240webpackEmptyAsyncContext.id = ${JSON.stringify(id)};
1241module.exports = webpackEmptyAsyncContext;`;
1242 }
1243
1244 /**
1245 * @param {string} asyncMode module mode
1246 * @param {ImportPhaseType} phase import phase
1247 * @param {CodeGenerationContext} context context info
1248 * @returns {string} the source code
1249 */
1250 getSourceString(asyncMode, phase, { runtimeTemplate, chunkGraph }) {
1251 const id = /** @type {ModuleId} */ (chunkGraph.getModuleId(this));
1252 if (asyncMode === "lazy") {
1253 if (this.blocks && this.blocks.length > 0) {
1254 return this.getLazySource(this.blocks, id, phase, {
1255 runtimeTemplate,
1256 chunkGraph
1257 });
1258 }
1259 return this.getSourceForEmptyAsyncContext(id, runtimeTemplate);
1260 }
1261 if (asyncMode === "eager") {
1262 if (this.dependencies && this.dependencies.length > 0) {
1263 return this.getEagerSource(this.dependencies, id, phase, {
1264 chunkGraph,
1265 runtimeTemplate
1266 });
1267 }
1268 return this.getSourceForEmptyAsyncContext(id, runtimeTemplate);
1269 }
1270 if (asyncMode === "lazy-once") {
1271 const block = this.blocks[0];
1272 if (block) {
1273 return this.getLazyOnceSource(block, block.dependencies, id, phase, {
1274 runtimeTemplate,
1275 chunkGraph
1276 });
1277 }
1278 return this.getSourceForEmptyAsyncContext(id, runtimeTemplate);
1279 }
1280 if (asyncMode === "async-weak") {
1281 if (this.dependencies && this.dependencies.length > 0) {
1282 return this.getAsyncWeakSource(this.dependencies, id, phase, {
1283 chunkGraph,
1284 runtimeTemplate
1285 });
1286 }
1287 return this.getSourceForEmptyAsyncContext(id, runtimeTemplate);
1288 }
1289 if (
1290 asyncMode === "weak" &&
1291 this.dependencies &&
1292 this.dependencies.length > 0
1293 ) {
1294 return this.getWeakSyncSource(this.dependencies, id, chunkGraph);
1295 }
1296 if (this.dependencies && this.dependencies.length > 0) {
1297 return this.getSyncSource(this.dependencies, id, chunkGraph);
1298 }
1299 return this.getSourceForEmptyContext(id, runtimeTemplate);
1300 }
1301
1302 /**
1303 * @param {string} sourceString source content
1304 * @param {Compilation=} compilation the compilation
1305 * @returns {Source} generated source
1306 */
1307 getSource(sourceString, compilation) {
1308 if (this.useSourceMap || this.useSimpleSourceMap) {
1309 return new OriginalSource(
1310 sourceString,
1311 `webpack://${makePathsRelative(
1312 (compilation && compilation.compiler.context) || "",
1313 this.identifier(),
1314 compilation && compilation.compiler.root
1315 )}`
1316 );
1317 }
1318 return new RawSource(sourceString);
1319 }
1320
1321 /**
1322 * Generates code and runtime requirements for this module.
1323 * @param {CodeGenerationContext} context context for code generation
1324 * @returns {CodeGenerationResult} result
1325 */
1326 codeGeneration(context) {
1327 const { chunkGraph, compilation } = context;
1328
1329 /** @type {Sources} */
1330 const sources = new Map();
1331 sources.set(
1332 JAVASCRIPT_TYPE,
1333 this.getSource(
1334 this.getSourceString(
1335 this.options.mode,
1336 this.options.phase || ImportPhase.Evaluation,
1337 context
1338 ),
1339 compilation
1340 )
1341 );
1342 /** @type {RuntimeRequirements} */
1343 const set = new Set();
1344 const allDeps =
1345 this.dependencies.length > 0
1346 ? /** @type {ContextElementDependency[]} */ [...this.dependencies]
1347 : [];
1348 for (const block of this.blocks) {
1349 for (const dep of block.dependencies) {
1350 allDeps.push(/** @type {ContextElementDependency} */ (dep));
1351 }
1352 }
1353 set.add(RuntimeGlobals.module);
1354 set.add(RuntimeGlobals.hasOwnProperty);
1355 if (allDeps.length > 0) {
1356 const asyncMode = this.options.mode;
1357 set.add(RuntimeGlobals.require);
1358 if (asyncMode === "weak") {
1359 set.add(RuntimeGlobals.moduleFactories);
1360 } else if (asyncMode === "async-weak") {
1361 set.add(RuntimeGlobals.moduleFactories);
1362 set.add(RuntimeGlobals.ensureChunk);
1363 } else if (asyncMode === "lazy" || asyncMode === "lazy-once") {
1364 set.add(RuntimeGlobals.ensureChunk);
1365 }
1366 if (this.getFakeMap(allDeps, chunkGraph) !== 9) {
1367 set.add(RuntimeGlobals.createFakeNamespaceObject);
1368 }
1369 if (
1370 ImportPhaseUtils.isDefer(this.options.phase || ImportPhase.Evaluation)
1371 ) {
1372 set.add(RuntimeGlobals.makeDeferredNamespaceObject);
1373 }
1374 }
1375 return {
1376 sources,
1377 runtimeRequirements: set
1378 };
1379 }
1380
1381 /**
1382 * Returns the estimated size for the requested source type.
1383 * @param {string=} type the source type for which the size should be estimated
1384 * @returns {number} the estimated size of the module (must be non-zero)
1385 */
1386 size(type) {
1387 // base penalty
1388 let size = 160;
1389
1390 // if we don't have dependencies we stop here.
1391 for (const dependency of this.dependencies) {
1392 const element = /** @type {ContextElementDependency} */ (dependency);
1393 size += 5 + element.userRequest.length;
1394 }
1395 return size;
1396 }
1397
1398 /**
1399 * Serializes this instance into the provided serializer context.
1400 * @param {ObjectSerializerContext} context context
1401 */
1402 serialize(context) {
1403 const { write } = context;
1404 write(this._identifier);
1405 write(this._forceBuild);
1406 super.serialize(context);
1407 }
1408
1409 /**
1410 * Restores this instance from the provided deserializer context.
1411 * @param {ObjectDeserializerContext} context context
1412 */
1413 deserialize(context) {
1414 const { read } = context;
1415 this._identifier = read();
1416 this._forceBuild = read();
1417 super.deserialize(context);
1418 }
1419}
1420
1421makeSerializable(ContextModule, "webpack/lib/ContextModule");
1422
1423module.exports = ContextModule;
Note: See TracBrowser for help on using the repository browser.