source: frontend/node_modules/webpack/lib/ModuleGraph.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: 32.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 ExportsInfo = require("./ExportsInfo");
10const ModuleGraphConnection = require("./ModuleGraphConnection");
11const HarmonyImportDependency = require("./dependencies/HarmonyImportDependency");
12const { ImportPhaseUtils } = require("./dependencies/ImportPhase");
13const SortableSet = require("./util/SortableSet");
14const WeakTupleMap = require("./util/WeakTupleMap");
15const { sortWithSourceOrder } = require("./util/comparators");
16
17/** @typedef {import("./Compilation").ModuleMemCaches} ModuleMemCaches */
18/** @typedef {import("./DependenciesBlock")} DependenciesBlock */
19/** @typedef {import("./Dependency")} Dependency */
20/** @typedef {import("./ExportsInfo").ExportInfo} ExportInfo */
21/** @typedef {import("./ExportsInfo").ExportInfoName} ExportInfoName */
22/** @typedef {import("./Module")} Module */
23/** @typedef {import("./ModuleProfile")} ModuleProfile */
24/** @typedef {import("./RequestShortener")} RequestShortener */
25/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
26/** @typedef {import("./dependencies/HarmonyImportSideEffectDependency")} HarmonyImportSideEffectDependency */
27/** @typedef {import("./dependencies/HarmonyImportSpecifierDependency")} HarmonyImportSpecifierDependency */
28/** @typedef {import("./util/comparators").DependencySourceOrder} DependencySourceOrder */
29
30/**
31 * Defines the optimization bailout function callback.
32 * @callback OptimizationBailoutFunction
33 * @param {RequestShortener} requestShortener
34 * @returns {string}
35 */
36
37/** @type {Iterable<ModuleGraphConnection>} */
38const EMPTY_SET = new Set();
39
40/**
41 * Gets connections by key.
42 * @template {Module | null | undefined} T
43 * @param {SortableSet<ModuleGraphConnection>} set input
44 * @param {(connection: ModuleGraphConnection) => T} getKey function to extract key from connection
45 * @returns {ReadonlyMap<T, ReadonlyArray<ModuleGraphConnection>>} mapped by key
46 */
47const getConnectionsByKey = (set, getKey) => {
48 /** @type {Map<T, ModuleGraphConnection[]>} */
49 const map = new Map();
50 /** @type {T | 0} */
51 let lastKey = 0;
52 /** @type {ModuleGraphConnection[] | undefined} */
53 let lastList;
54 for (const connection of set) {
55 const key = getKey(connection);
56 if (lastKey === key) {
57 /** @type {ModuleGraphConnection[]} */
58 (lastList).push(connection);
59 } else {
60 lastKey = key;
61 const list = map.get(key);
62 if (list !== undefined) {
63 lastList = list;
64 list.push(connection);
65 } else {
66 const list = [connection];
67 lastList = list;
68 map.set(key, list);
69 }
70 }
71 }
72 return map;
73};
74
75/**
76 * Gets connections by origin module.
77 * @param {SortableSet<ModuleGraphConnection>} set input
78 * @returns {ReadonlyMap<Module | undefined | null, ReadonlyArray<ModuleGraphConnection>>} mapped by origin module
79 */
80const getConnectionsByOriginModule = (set) =>
81 getConnectionsByKey(set, (connection) => connection.originModule);
82
83/**
84 * Gets connections by module.
85 * @param {SortableSet<ModuleGraphConnection>} set input
86 * @returns {ReadonlyMap<Module | undefined, ReadonlyArray<ModuleGraphConnection>>} mapped by module
87 */
88const getConnectionsByModule = (set) =>
89 getConnectionsByKey(set, (connection) => connection.module);
90
91/** @typedef {SortableSet<ModuleGraphConnection>} IncomingConnections */
92/** @typedef {SortableSet<ModuleGraphConnection>} OutgoingConnections */
93/** @typedef {Module | null | undefined} Issuer */
94/** @typedef {(string | OptimizationBailoutFunction)[]} OptimizationBailouts */
95
96class ModuleGraphModule {
97 constructor() {
98 /** @type {IncomingConnections} */
99 this.incomingConnections = new SortableSet();
100 /** @type {OutgoingConnections | undefined} */
101 this.outgoingConnections = undefined;
102 /** @type {Issuer} */
103 this.issuer = undefined;
104 /** @type {OptimizationBailouts} */
105 this.optimizationBailout = [];
106 /** @type {ExportsInfo} */
107 this.exports = new ExportsInfo();
108 /** @type {number | null} */
109 this.preOrderIndex = null;
110 /** @type {number | null} */
111 this.postOrderIndex = null;
112 /** @type {number | null} */
113 this.depth = null;
114 /** @type {ModuleProfile | undefined} */
115 this.profile = undefined;
116 /** @type {boolean} */
117 this.async = false;
118 /** @type {ModuleGraphConnection[] | undefined} */
119 this._unassignedConnections = undefined;
120 }
121}
122
123/** @typedef {(moduleGraphConnection: ModuleGraphConnection) => boolean} FilterConnection */
124
125/** @typedef {EXPECTED_OBJECT} MetaKey */
126
127/** @typedef {import("./dependencies/CommonJsExportRequireDependency").idsSymbol} CommonJsExportRequireDependencyIDsSymbol */
128/** @typedef {import("./dependencies/HarmonyImportSpecifierDependency").idsSymbol} HarmonyImportSpecifierDependencyIDsSymbol */
129/** @typedef {import("./dependencies/HarmonyExportImportedSpecifierDependency").idsSymbol} HarmonyExportImportedSpecifierDependencyIDsSymbol */
130
131/**
132 * Defines the known meta type used by this module.
133 * @typedef {object} KnownMeta
134 * @property {Map<Module, string>=} importVarMap
135 * @property {Map<Module, string>=} deferredImportVarMap
136 */
137
138/** @typedef {KnownMeta & Record<CommonJsExportRequireDependencyIDsSymbol | HarmonyImportSpecifierDependencyIDsSymbol | HarmonyExportImportedSpecifierDependencyIDsSymbol, string[]> & Record<string, EXPECTED_ANY>} Meta */
139
140class ModuleGraph {
141 constructor() {
142 /**
143 * @type {WeakMap<Dependency, ModuleGraphConnection | null>}
144 * @private
145 */
146 this._dependencyMap = new WeakMap();
147 /**
148 * @type {Map<Module, ModuleGraphModule>}
149 * @private
150 */
151 this._moduleMap = new Map();
152 /**
153 * @type {WeakMap<MetaKey, Meta>}
154 * @private
155 */
156 this._metaMap = new WeakMap();
157 /**
158 * @type {WeakTupleMap<EXPECTED_ANY[], EXPECTED_ANY> | undefined}
159 * @private
160 */
161 this._cache = undefined;
162 /**
163 * @type {ModuleMemCaches | undefined}
164 * @private
165 */
166 this._moduleMemCaches = undefined;
167
168 /**
169 * @type {string | undefined}
170 * @private
171 */
172 this._cacheStage = undefined;
173
174 /**
175 * @type {WeakMap<Dependency, DependencySourceOrder>}
176 * @private
177 */
178 this._dependencySourceOrderMap = new WeakMap();
179
180 /**
181 * @type {Set<Module>}
182 * @private
183 */
184 this._modulesNeedingSort = new Set();
185 }
186
187 /**
188 * Get module graph module.
189 * @param {Module} module the module
190 * @returns {ModuleGraphModule} the internal module
191 */
192 _getModuleGraphModule(module) {
193 let mgm = this._moduleMap.get(module);
194 if (mgm === undefined) {
195 mgm = new ModuleGraphModule();
196 this._moduleMap.set(module, mgm);
197 }
198 return mgm;
199 }
200
201 /**
202 * Updates parents using the provided dependency.
203 * @param {Dependency} dependency the dependency
204 * @param {DependenciesBlock} block parent block
205 * @param {Module} module parent module
206 * @param {number=} indexInBlock position in block
207 * @returns {void}
208 */
209 setParents(dependency, block, module, indexInBlock = -1) {
210 dependency._parentDependenciesBlockIndex = indexInBlock;
211 dependency._parentDependenciesBlock = block;
212 dependency._parentModule = module;
213 }
214
215 /**
216 * Sets parent dependencies block index.
217 * @param {Dependency} dependency the dependency
218 * @param {number} index the index
219 * @returns {void}
220 */
221 setParentDependenciesBlockIndex(dependency, index) {
222 dependency._parentDependenciesBlockIndex = index;
223 }
224
225 /**
226 * Gets parent module.
227 * @param {Dependency} dependency the dependency
228 * @returns {Module | undefined} parent module
229 */
230 getParentModule(dependency) {
231 return dependency._parentModule;
232 }
233
234 /**
235 * Returns parent block.
236 * @param {Dependency} dependency the dependency
237 * @returns {DependenciesBlock | undefined} parent block
238 */
239 getParentBlock(dependency) {
240 return dependency._parentDependenciesBlock;
241 }
242
243 /**
244 * Gets parent block index.
245 * @param {Dependency} dependency the dependency
246 * @returns {number} index
247 */
248 getParentBlockIndex(dependency) {
249 return dependency._parentDependenciesBlockIndex;
250 }
251
252 /**
253 * Sets resolved module.
254 * @param {Module | null} originModule the referencing module
255 * @param {Dependency} dependency the referencing dependency
256 * @param {Module} module the referenced module
257 * @returns {void}
258 */
259 setResolvedModule(originModule, dependency, module) {
260 const connection = new ModuleGraphConnection(
261 originModule,
262 dependency,
263 module,
264 undefined,
265 dependency.weak,
266 dependency.getCondition(this)
267 );
268 const connections = this._getModuleGraphModule(module).incomingConnections;
269 connections.add(connection);
270 if (originModule) {
271 const mgm = this._getModuleGraphModule(originModule);
272 if (mgm._unassignedConnections === undefined) {
273 mgm._unassignedConnections = [];
274 }
275 mgm._unassignedConnections.push(connection);
276 if (mgm.outgoingConnections === undefined) {
277 mgm.outgoingConnections = new SortableSet();
278 }
279 mgm.outgoingConnections.add(connection);
280 } else {
281 this._dependencyMap.set(dependency, connection);
282 }
283 }
284
285 /**
286 * Updates module using the provided dependency.
287 * @param {Dependency} dependency the referencing dependency
288 * @param {Module} module the referenced module
289 * @returns {void}
290 */
291 updateModule(dependency, module) {
292 const connection =
293 /** @type {ModuleGraphConnection} */
294 (this.getConnection(dependency));
295 if (connection.module === module) return;
296 const newConnection = connection.clone();
297 newConnection.module = module;
298 this._dependencyMap.set(dependency, newConnection);
299 connection.setActive(false);
300 const originMgm = this._getModuleGraphModule(
301 /** @type {Module} */ (connection.originModule)
302 );
303 /** @type {OutgoingConnections} */
304 (originMgm.outgoingConnections).add(newConnection);
305 const targetMgm = this._getModuleGraphModule(module);
306 targetMgm.incomingConnections.add(newConnection);
307 }
308
309 /**
310 * Updates parent using the provided dependency.
311 * @param {Dependency} dependency the need update dependency
312 * @param {ModuleGraphConnection=} connection the target connection
313 * @param {Module=} parentModule the parent module
314 * @returns {void}
315 */
316 updateParent(dependency, connection, parentModule) {
317 if (this._dependencySourceOrderMap.has(dependency)) {
318 return;
319 }
320 if (!connection || !parentModule) {
321 return;
322 }
323 const originDependency = connection.dependency;
324
325 // src/index.js
326 // import { c } from "lib/c" -> c = 0
327 // import { a, b } from "lib" -> a and b have the same source order -> a = b = 1
328 // import { d } from "lib/d" -> d = 2
329 const currentSourceOrder =
330 /** @type {HarmonyImportSideEffectDependency | HarmonyImportSpecifierDependency} */
331 (dependency).sourceOrder;
332
333 // lib/index.js (reexport)
334 // import { a } from "lib/a" -> a = 0
335 // import { b } from "lib/b" -> b = 1
336 const originSourceOrder =
337 /** @type {HarmonyImportSideEffectDependency | HarmonyImportSpecifierDependency} */
338 (originDependency).sourceOrder;
339 if (
340 typeof currentSourceOrder === "number" &&
341 typeof originSourceOrder === "number"
342 ) {
343 // src/index.js
344 // import { c } from "lib/c" -> c = 0
345 // import { a } from "lib/a" -> a = 1.0 = 1(main) + 0.0(sub)
346 // import { b } from "lib/b" -> b = 1.1 = 1(main) + 0.1(sub)
347 // import { d } from "lib/d" -> d = 2
348 this._dependencySourceOrderMap.set(dependency, {
349 main: currentSourceOrder,
350 sub: originSourceOrder
351 });
352
353 // Save for later batch sorting
354 this._modulesNeedingSort.add(parentModule);
355 }
356 }
357
358 /**
359 * Finish update parent.
360 * @returns {void}
361 */
362 finishUpdateParent() {
363 if (this._modulesNeedingSort.size === 0) {
364 return;
365 }
366 for (const mod of this._modulesNeedingSort) {
367 // If dependencies like HarmonyImportSideEffectDependency and HarmonyImportSpecifierDependency have a SourceOrder,
368 // we sort based on it; otherwise, we preserve the original order.
369 sortWithSourceOrder(
370 mod.dependencies,
371 this._dependencySourceOrderMap,
372 (dep, index) => this.setParentDependenciesBlockIndex(dep, index)
373 );
374 }
375 this._modulesNeedingSort.clear();
376 }
377
378 /**
379 * Removes connection.
380 * @param {Dependency} dependency the referencing dependency
381 * @returns {void}
382 */
383 removeConnection(dependency) {
384 const connection =
385 /** @type {ModuleGraphConnection} */
386 (this.getConnection(dependency));
387 const targetMgm = this._getModuleGraphModule(connection.module);
388 targetMgm.incomingConnections.delete(connection);
389 const originMgm = this._getModuleGraphModule(
390 /** @type {Module} */ (connection.originModule)
391 );
392 /** @type {OutgoingConnections} */
393 (originMgm.outgoingConnections).delete(connection);
394 this._dependencyMap.set(dependency, null);
395 }
396
397 /**
398 * Adds the provided dependency to the module graph.
399 * @param {Dependency} dependency the referencing dependency
400 * @param {string} explanation an explanation
401 * @returns {void}
402 */
403 addExplanation(dependency, explanation) {
404 const connection =
405 /** @type {ModuleGraphConnection} */
406 (this.getConnection(dependency));
407 connection.addExplanation(explanation);
408 }
409
410 /**
411 * Clones module attributes.
412 * @param {Module} sourceModule the source module
413 * @param {Module} targetModule the target module
414 * @returns {void}
415 */
416 cloneModuleAttributes(sourceModule, targetModule) {
417 const oldMgm = this._getModuleGraphModule(sourceModule);
418 const newMgm = this._getModuleGraphModule(targetModule);
419 newMgm.postOrderIndex = oldMgm.postOrderIndex;
420 newMgm.preOrderIndex = oldMgm.preOrderIndex;
421 newMgm.depth = oldMgm.depth;
422 newMgm.exports = oldMgm.exports;
423 newMgm.async = oldMgm.async;
424 }
425
426 /**
427 * Removes module attributes.
428 * @param {Module} module the module
429 * @returns {void}
430 */
431 removeModuleAttributes(module) {
432 const mgm = this._getModuleGraphModule(module);
433 mgm.postOrderIndex = null;
434 mgm.preOrderIndex = null;
435 mgm.depth = null;
436 mgm.async = false;
437 }
438
439 /**
440 * Removes all module attributes.
441 * @returns {void}
442 */
443 removeAllModuleAttributes() {
444 for (const mgm of this._moduleMap.values()) {
445 mgm.postOrderIndex = null;
446 mgm.preOrderIndex = null;
447 mgm.depth = null;
448 mgm.async = false;
449 }
450 }
451
452 /**
453 * Move module connections.
454 * @param {Module} oldModule the old referencing module
455 * @param {Module} newModule the new referencing module
456 * @param {FilterConnection} filterConnection filter predicate for replacement
457 * @returns {void}
458 */
459 moveModuleConnections(oldModule, newModule, filterConnection) {
460 if (oldModule === newModule) return;
461 const oldMgm = this._getModuleGraphModule(oldModule);
462 const newMgm = this._getModuleGraphModule(newModule);
463 // Outgoing connections
464 const oldConnections = oldMgm.outgoingConnections;
465 if (oldConnections !== undefined) {
466 if (newMgm.outgoingConnections === undefined) {
467 newMgm.outgoingConnections = new SortableSet();
468 }
469 const newConnections = newMgm.outgoingConnections;
470 for (const connection of oldConnections) {
471 if (filterConnection(connection)) {
472 connection.originModule = newModule;
473 newConnections.add(connection);
474 oldConnections.delete(connection);
475 }
476 }
477 }
478 // Incoming connections
479 const oldConnections2 = oldMgm.incomingConnections;
480 const newConnections2 = newMgm.incomingConnections;
481 for (const connection of oldConnections2) {
482 if (filterConnection(connection)) {
483 connection.module = newModule;
484 newConnections2.add(connection);
485 oldConnections2.delete(connection);
486 }
487 }
488 }
489
490 /**
491 * Copies outgoing module connections.
492 * @param {Module} oldModule the old referencing module
493 * @param {Module} newModule the new referencing module
494 * @param {FilterConnection} filterConnection filter predicate for replacement
495 * @returns {void}
496 */
497 copyOutgoingModuleConnections(oldModule, newModule, filterConnection) {
498 if (oldModule === newModule) return;
499 const oldMgm = this._getModuleGraphModule(oldModule);
500 const newMgm = this._getModuleGraphModule(newModule);
501 // Outgoing connections
502 const oldConnections = oldMgm.outgoingConnections;
503 if (oldConnections !== undefined) {
504 if (newMgm.outgoingConnections === undefined) {
505 newMgm.outgoingConnections = new SortableSet();
506 }
507 const newConnections = newMgm.outgoingConnections;
508 for (const connection of oldConnections) {
509 if (filterConnection(connection)) {
510 const newConnection = connection.clone();
511 newConnection.originModule = newModule;
512 newConnections.add(newConnection);
513 if (newConnection.module !== undefined) {
514 const otherMgm = this._getModuleGraphModule(newConnection.module);
515 otherMgm.incomingConnections.add(newConnection);
516 }
517 }
518 }
519 }
520 }
521
522 /**
523 * Adds the provided module to the module graph.
524 * @param {Module} module the referenced module
525 * @param {string} explanation an explanation why it's referenced
526 * @returns {void}
527 */
528 addExtraReason(module, explanation) {
529 const connections = this._getModuleGraphModule(module).incomingConnections;
530 connections.add(new ModuleGraphConnection(null, null, module, explanation));
531 }
532
533 /**
534 * Gets resolved module.
535 * @param {Dependency} dependency the dependency to look for a referenced module
536 * @returns {Module | null} the referenced module
537 */
538 getResolvedModule(dependency) {
539 const connection = this.getConnection(dependency);
540 return connection !== undefined ? connection.resolvedModule : null;
541 }
542
543 /**
544 * Returns the connection.
545 * @param {Dependency} dependency the dependency to look for a referenced module
546 * @returns {ModuleGraphConnection | undefined} the connection
547 */
548 getConnection(dependency) {
549 const connection = this._dependencyMap.get(dependency);
550 if (connection === undefined) {
551 const module = this.getParentModule(dependency);
552 if (module !== undefined) {
553 const mgm = this._getModuleGraphModule(module);
554 if (
555 mgm._unassignedConnections &&
556 mgm._unassignedConnections.length !== 0
557 ) {
558 /** @type {undefined | ModuleGraphConnection} */
559 let foundConnection;
560 for (const connection of mgm._unassignedConnections) {
561 this._dependencyMap.set(
562 /** @type {Dependency} */ (connection.dependency),
563 connection
564 );
565 if (connection.dependency === dependency) {
566 foundConnection = connection;
567 }
568 }
569 mgm._unassignedConnections.length = 0;
570 if (foundConnection !== undefined) {
571 return foundConnection;
572 }
573 }
574 }
575 this._dependencyMap.set(dependency, null);
576 return;
577 }
578 return connection === null ? undefined : connection;
579 }
580
581 /**
582 * Returns the referenced module.
583 * @param {Dependency} dependency the dependency to look for a referenced module
584 * @returns {Module | null} the referenced module
585 */
586 getModule(dependency) {
587 const connection = this.getConnection(dependency);
588 return connection !== undefined ? connection.module : null;
589 }
590
591 /**
592 * Returns the referencing module.
593 * @param {Dependency} dependency the dependency to look for a referencing module
594 * @returns {Module | null} the referencing module
595 */
596 getOrigin(dependency) {
597 const connection = this.getConnection(dependency);
598 return connection !== undefined ? connection.originModule : null;
599 }
600
601 /**
602 * Gets resolved origin.
603 * @param {Dependency} dependency the dependency to look for a referencing module
604 * @returns {Module | null} the original referencing module
605 */
606 getResolvedOrigin(dependency) {
607 const connection = this.getConnection(dependency);
608 return connection !== undefined ? connection.resolvedOriginModule : null;
609 }
610
611 /**
612 * Gets incoming connections.
613 * @param {Module} module the module
614 * @returns {Iterable<ModuleGraphConnection>} reasons why a module is included
615 */
616 getIncomingConnections(module) {
617 const connections = this._getModuleGraphModule(module).incomingConnections;
618 return connections;
619 }
620
621 /**
622 * Gets outgoing connections.
623 * @param {Module} module the module
624 * @returns {Iterable<ModuleGraphConnection>} list of outgoing connections
625 */
626 getOutgoingConnections(module) {
627 const connections = this._getModuleGraphModule(module).outgoingConnections;
628 return connections === undefined ? EMPTY_SET : connections;
629 }
630
631 /**
632 * Gets incoming connections by origin module.
633 * @param {Module} module the module
634 * @returns {ReadonlyMap<Module | undefined | null, ReadonlyArray<ModuleGraphConnection>>} reasons why a module is included, in a map by source module
635 */
636 getIncomingConnectionsByOriginModule(module) {
637 const connections = this._getModuleGraphModule(module).incomingConnections;
638 return connections.getFromUnorderedCache(getConnectionsByOriginModule);
639 }
640
641 /**
642 * Gets outgoing connections by module.
643 * @param {Module} module the module
644 * @returns {ReadonlyMap<Module | undefined, ReadonlyArray<ModuleGraphConnection>> | undefined} connections to modules, in a map by module
645 */
646 getOutgoingConnectionsByModule(module) {
647 const connections = this._getModuleGraphModule(module).outgoingConnections;
648 return connections === undefined
649 ? undefined
650 : connections.getFromUnorderedCache(getConnectionsByModule);
651 }
652
653 /**
654 * Returns the module profile.
655 * @param {Module} module the module
656 * @returns {ModuleProfile | undefined} the module profile
657 */
658 getProfile(module) {
659 const mgm = this._getModuleGraphModule(module);
660 return mgm.profile;
661 }
662
663 /**
664 * Updates profile using the provided module.
665 * @param {Module} module the module
666 * @param {ModuleProfile | undefined} profile the module profile
667 * @returns {void}
668 */
669 setProfile(module, profile) {
670 const mgm = this._getModuleGraphModule(module);
671 mgm.profile = profile;
672 }
673
674 /**
675 * Returns the issuer module.
676 * @param {Module} module the module
677 * @returns {Issuer} the issuer module
678 */
679 getIssuer(module) {
680 const mgm = this._getModuleGraphModule(module);
681 return mgm.issuer;
682 }
683
684 /**
685 * Updates issuer using the provided module.
686 * @param {Module} module the module
687 * @param {Module | null} issuer the issuer module
688 * @returns {void}
689 */
690 setIssuer(module, issuer) {
691 const mgm = this._getModuleGraphModule(module);
692 mgm.issuer = issuer;
693 }
694
695 /**
696 * Sets issuer if unset.
697 * @param {Module} module the module
698 * @param {Module | null} issuer the issuer module
699 * @returns {void}
700 */
701 setIssuerIfUnset(module, issuer) {
702 const mgm = this._getModuleGraphModule(module);
703 if (mgm.issuer === undefined) mgm.issuer = issuer;
704 }
705
706 /**
707 * Gets optimization bailout.
708 * @param {Module} module the module
709 * @returns {OptimizationBailouts} optimization bailouts
710 */
711 getOptimizationBailout(module) {
712 const mgm = this._getModuleGraphModule(module);
713 return mgm.optimizationBailout;
714 }
715
716 /**
717 * Gets provided exports.
718 * @param {Module} module the module
719 * @returns {null | true | ExportInfoName[]} the provided exports
720 */
721 getProvidedExports(module) {
722 const mgm = this._getModuleGraphModule(module);
723 return mgm.exports.getProvidedExports();
724 }
725
726 /**
727 * Checks whether this module graph is export provided.
728 * @param {Module} module the module
729 * @param {ExportInfoName | ExportInfoName[]} exportName a name of an export
730 * @returns {boolean | null} true, if the export is provided by the module.
731 * null, if it's unknown.
732 * false, if it's not provided.
733 */
734 isExportProvided(module, exportName) {
735 const mgm = this._getModuleGraphModule(module);
736 const result = mgm.exports.isExportProvided(exportName);
737 return result === undefined ? null : result;
738 }
739
740 /**
741 * Returns info about the exports.
742 * @param {Module} module the module
743 * @returns {ExportsInfo} info about the exports
744 */
745 getExportsInfo(module) {
746 const mgm = this._getModuleGraphModule(module);
747 return mgm.exports;
748 }
749
750 /**
751 * Returns info about the export.
752 * @param {Module} module the module
753 * @param {string} exportName the export
754 * @returns {ExportInfo} info about the export
755 */
756 getExportInfo(module, exportName) {
757 const mgm = this._getModuleGraphModule(module);
758 return mgm.exports.getExportInfo(exportName);
759 }
760
761 /**
762 * Gets read only export info.
763 * @param {Module} module the module
764 * @param {string} exportName the export
765 * @returns {ExportInfo} info about the export (do not modify)
766 */
767 getReadOnlyExportInfo(module, exportName) {
768 const mgm = this._getModuleGraphModule(module);
769 return mgm.exports.getReadOnlyExportInfo(exportName);
770 }
771
772 /**
773 * Returns the used exports.
774 * @param {Module} module the module
775 * @param {RuntimeSpec} runtime the runtime
776 * @returns {false | true | SortableSet<string> | null} the used exports
777 * false: module is not used at all.
778 * true: the module namespace/object export is used.
779 * SortableSet<string>: these export names are used.
780 * empty SortableSet<string>: module is used but no export.
781 * null: unknown, worst case should be assumed.
782 */
783 getUsedExports(module, runtime) {
784 const mgm = this._getModuleGraphModule(module);
785 return mgm.exports.getUsedExports(runtime);
786 }
787
788 /**
789 * Gets pre order index.
790 * @param {Module} module the module
791 * @returns {number | null} the index of the module
792 */
793 getPreOrderIndex(module) {
794 const mgm = this._getModuleGraphModule(module);
795 return mgm.preOrderIndex;
796 }
797
798 /**
799 * Gets post order index.
800 * @param {Module} module the module
801 * @returns {number | null} the index of the module
802 */
803 getPostOrderIndex(module) {
804 const mgm = this._getModuleGraphModule(module);
805 return mgm.postOrderIndex;
806 }
807
808 /**
809 * Sets pre order index.
810 * @param {Module} module the module
811 * @param {number} index the index of the module
812 * @returns {void}
813 */
814 setPreOrderIndex(module, index) {
815 const mgm = this._getModuleGraphModule(module);
816 mgm.preOrderIndex = index;
817 }
818
819 /**
820 * Sets pre order index if unset.
821 * @param {Module} module the module
822 * @param {number} index the index of the module
823 * @returns {boolean} true, if the index was set
824 */
825 setPreOrderIndexIfUnset(module, index) {
826 const mgm = this._getModuleGraphModule(module);
827 if (mgm.preOrderIndex === null) {
828 mgm.preOrderIndex = index;
829 return true;
830 }
831 return false;
832 }
833
834 /**
835 * Sets post order index.
836 * @param {Module} module the module
837 * @param {number} index the index of the module
838 * @returns {void}
839 */
840 setPostOrderIndex(module, index) {
841 const mgm = this._getModuleGraphModule(module);
842 mgm.postOrderIndex = index;
843 }
844
845 /**
846 * Sets post order index if unset.
847 * @param {Module} module the module
848 * @param {number} index the index of the module
849 * @returns {boolean} true, if the index was set
850 */
851 setPostOrderIndexIfUnset(module, index) {
852 const mgm = this._getModuleGraphModule(module);
853 if (mgm.postOrderIndex === null) {
854 mgm.postOrderIndex = index;
855 return true;
856 }
857 return false;
858 }
859
860 /**
861 * Returns the depth of the module.
862 * @param {Module} module the module
863 * @returns {number | null} the depth of the module
864 */
865 getDepth(module) {
866 const mgm = this._getModuleGraphModule(module);
867 return mgm.depth;
868 }
869
870 /**
871 * Updates depth using the provided module.
872 * @param {Module} module the module
873 * @param {number} depth the depth of the module
874 * @returns {void}
875 */
876 setDepth(module, depth) {
877 const mgm = this._getModuleGraphModule(module);
878 mgm.depth = depth;
879 }
880
881 /**
882 * Sets depth if lower.
883 * @param {Module} module the module
884 * @param {number} depth the depth of the module
885 * @returns {boolean} true, if the depth was set
886 */
887 setDepthIfLower(module, depth) {
888 const mgm = this._getModuleGraphModule(module);
889 if (mgm.depth === null || mgm.depth > depth) {
890 mgm.depth = depth;
891 return true;
892 }
893 return false;
894 }
895
896 /**
897 * Checks whether this module graph is async.
898 * @param {Module} module the module
899 * @returns {boolean} true, if the module is async
900 */
901 isAsync(module) {
902 const mgm = this._getModuleGraphModule(module);
903 return mgm.async;
904 }
905
906 /**
907 * Checks whether this module graph is deferred.
908 * @param {Module} module the module
909 * @returns {boolean} true, if the module is used as a deferred module at least once
910 */
911 isDeferred(module) {
912 if (this.isAsync(module)) return false;
913 const connections = this.getIncomingConnections(module);
914 for (const connection of connections) {
915 if (
916 !connection.dependency ||
917 !(connection.dependency instanceof HarmonyImportDependency)
918 ) {
919 continue;
920 }
921 if (ImportPhaseUtils.isDefer(connection.dependency.phase)) return true;
922 }
923 return false;
924 }
925
926 /**
927 * Updates async using the provided module.
928 * @param {Module} module the module
929 * @returns {void}
930 */
931 setAsync(module) {
932 const mgm = this._getModuleGraphModule(module);
933 mgm.async = true;
934 }
935
936 /**
937 * Returns metadata.
938 * @param {MetaKey} thing any thing
939 * @returns {Meta} metadata
940 */
941 getMeta(thing) {
942 let meta = this._metaMap.get(thing);
943 if (meta === undefined) {
944 meta = /** @type {Meta} */ (Object.create(null));
945 this._metaMap.set(thing, meta);
946 }
947 return meta;
948 }
949
950 /**
951 * Gets meta if existing.
952 * @param {MetaKey} thing any thing
953 * @returns {Meta | undefined} metadata
954 */
955 getMetaIfExisting(thing) {
956 return this._metaMap.get(thing);
957 }
958
959 /**
960 * Processes the provided cache stage.
961 * @param {string=} cacheStage a persistent stage name for caching
962 */
963 freeze(cacheStage) {
964 this._cache = new WeakTupleMap();
965 this._cacheStage = cacheStage;
966 }
967
968 unfreeze() {
969 this._cache = undefined;
970 this._cacheStage = undefined;
971 }
972
973 /**
974 * Returns computed value or cached.
975 * @template {EXPECTED_ANY[]} T
976 * @template R
977 * @param {(moduleGraph: ModuleGraph, ...args: T) => R} fn computer
978 * @param {T} args arguments
979 * @returns {R} computed value or cached
980 */
981 cached(fn, ...args) {
982 if (this._cache === undefined) return fn(this, ...args);
983 return this._cache.provide(fn, ...args, () => fn(this, ...args));
984 }
985
986 /**
987 * Sets module mem caches.
988 * @param {ModuleMemCaches} moduleMemCaches mem caches for modules for better caching
989 */
990 setModuleMemCaches(moduleMemCaches) {
991 this._moduleMemCaches = moduleMemCaches;
992 }
993
994 /**
995 * Dependency cache provide.
996 * @template {Dependency} D
997 * @template {EXPECTED_ANY[]} ARGS
998 * @template R
999 * @param {D} dependency dependency
1000 * @param {[...ARGS, (moduleGraph: ModuleGraph, dependency: D, ...args: ARGS) => R]} args arguments, last argument is a function called with moduleGraph, dependency, ...args
1001 * @returns {R} computed value or cached
1002 */
1003 dependencyCacheProvide(dependency, ...args) {
1004 const fn =
1005 /** @type {(moduleGraph: ModuleGraph, dependency: D, ...args: EXPECTED_ANY[]) => R} */
1006 (args.pop());
1007 if (this._moduleMemCaches && this._cacheStage) {
1008 const memCache = this._moduleMemCaches.get(
1009 /** @type {Module} */
1010 (this.getParentModule(dependency))
1011 );
1012 if (memCache !== undefined) {
1013 return memCache.provide(dependency, this._cacheStage, ...args, () =>
1014 fn(this, dependency, ...args)
1015 );
1016 }
1017 }
1018 if (this._cache === undefined) return fn(this, dependency, ...args);
1019 return this._cache.provide(dependency, ...args, () =>
1020 fn(this, dependency, ...args)
1021 );
1022 }
1023
1024 // TODO remove in webpack 6
1025 /**
1026 * Gets module graph for module.
1027 * @deprecated
1028 * @param {Module} module the module
1029 * @param {string} deprecateMessage message for the deprecation message
1030 * @param {string} deprecationCode code for the deprecation
1031 * @returns {ModuleGraph} the module graph
1032 */
1033 static getModuleGraphForModule(module, deprecateMessage, deprecationCode) {
1034 const fn = deprecateMap.get(deprecateMessage);
1035 if (fn) return fn(module);
1036 const newFn = util.deprecate(
1037 /**
1038 * Handles the callback logic for this hook.
1039 * @param {Module} module the module
1040 * @returns {ModuleGraph} the module graph
1041 */
1042 (module) => {
1043 const moduleGraph = moduleGraphForModuleMap.get(module);
1044 if (!moduleGraph) {
1045 throw new Error(
1046 `${
1047 deprecateMessage
1048 }There was no ModuleGraph assigned to the Module for backward-compat (Use the new API)`
1049 );
1050 }
1051 return moduleGraph;
1052 },
1053 `${deprecateMessage}: Use new ModuleGraph API`,
1054 deprecationCode
1055 );
1056 deprecateMap.set(deprecateMessage, newFn);
1057 return newFn(module);
1058 }
1059
1060 // TODO remove in webpack 6
1061 /**
1062 * Sets module graph for module.
1063 * @deprecated
1064 * @param {Module} module the module
1065 * @param {ModuleGraph} moduleGraph the module graph
1066 * @returns {void}
1067 */
1068 static setModuleGraphForModule(module, moduleGraph) {
1069 moduleGraphForModuleMap.set(module, moduleGraph);
1070 }
1071
1072 // TODO remove in webpack 6
1073 /**
1074 * Clear module graph for module.
1075 * @deprecated
1076 * @param {Module} module the module
1077 * @returns {void}
1078 */
1079 static clearModuleGraphForModule(module) {
1080 moduleGraphForModuleMap.delete(module);
1081 }
1082}
1083
1084// TODO remove in webpack 6
1085/** @type {WeakMap<Module, ModuleGraph>} */
1086const moduleGraphForModuleMap = new WeakMap();
1087
1088// TODO remove in webpack 6
1089/** @type {Map<string, (module: Module) => ModuleGraph>} */
1090const deprecateMap = new Map();
1091
1092module.exports = ModuleGraph;
1093module.exports.ModuleGraphConnection = ModuleGraphConnection;
Note: See TracBrowser for help on using the repository browser.