source: imaps-frontend/node_modules/webpack/lib/dependencies/HarmonyExportImportedSpecifierDependency.js@ 79a0317

main
Last change on this file since 79a0317 was 79a0317, checked in by stefan toskovski <stefantoska84@…>, 3 days ago

F4 Finalna Verzija

  • Property mode set to 100644
File size: 38.5 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 ConditionalInitFragment = require("../ConditionalInitFragment");
9const Dependency = require("../Dependency");
10const { UsageState } = require("../ExportsInfo");
11const HarmonyLinkingError = require("../HarmonyLinkingError");
12const InitFragment = require("../InitFragment");
13const RuntimeGlobals = require("../RuntimeGlobals");
14const Template = require("../Template");
15const { countIterable } = require("../util/IterableHelpers");
16const { first, combine } = require("../util/SetHelpers");
17const makeSerializable = require("../util/makeSerializable");
18const propertyAccess = require("../util/propertyAccess");
19const { propertyName } = require("../util/propertyName");
20const {
21 getRuntimeKey,
22 keyToRuntime,
23 filterRuntime
24} = require("../util/runtime");
25const HarmonyExportInitFragment = require("./HarmonyExportInitFragment");
26const HarmonyImportDependency = require("./HarmonyImportDependency");
27const processExportInfo = require("./processExportInfo");
28
29/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
30/** @typedef {import("../ChunkGraph")} ChunkGraph */
31/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
32/** @typedef {import("../Dependency").GetConditionFn} GetConditionFn */
33/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */
34/** @typedef {import("../Dependency").TRANSITIVE} TRANSITIVE */
35/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
36/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
37/** @typedef {import("../ExportsInfo")} ExportsInfo */
38/** @typedef {import("../ExportsInfo").ExportInfo} ExportInfo */
39/** @typedef {import("../ExportsInfo").UsedName} UsedName */
40/** @typedef {import("../Generator").GenerateContext} GenerateContext */
41/** @typedef {import("../Module")} Module */
42/** @typedef {import("../Module").BuildMeta} BuildMeta */
43/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
44/** @typedef {import("../ModuleGraph")} ModuleGraph */
45/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */
46/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */
47/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
48/** @typedef {import("../WebpackError")} WebpackError */
49/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */
50/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
51/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
52/** @typedef {import("../util/Hash")} Hash */
53/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
54/** @typedef {import("./processExportInfo").ReferencedExports} ReferencedExports */
55
56/** @typedef {"missing"|"unused"|"empty-star"|"reexport-dynamic-default"|"reexport-named-default"|"reexport-namespace-object"|"reexport-fake-namespace-object"|"reexport-undefined"|"normal-reexport"|"dynamic-reexport"} ExportModeType */
57
58const { ExportPresenceModes } = HarmonyImportDependency;
59
60const idsSymbol = Symbol("HarmonyExportImportedSpecifierDependency.ids");
61
62class NormalReexportItem {
63 /**
64 * @param {string} name export name
65 * @param {string[]} ids reexported ids from other module
66 * @param {ExportInfo} exportInfo export info from other module
67 * @param {boolean} checked true, if it should be checked at runtime if this export exists
68 * @param {boolean} hidden true, if it is hidden behind another active export in the same module
69 */
70 constructor(name, ids, exportInfo, checked, hidden) {
71 this.name = name;
72 this.ids = ids;
73 this.exportInfo = exportInfo;
74 this.checked = checked;
75 this.hidden = hidden;
76 }
77}
78
79/** @typedef {Set<string>} ExportModeIgnored */
80/** @typedef {Set<string>} ExportModeHidden */
81
82class ExportMode {
83 /**
84 * @param {ExportModeType} type type of the mode
85 */
86 constructor(type) {
87 /** @type {ExportModeType} */
88 this.type = type;
89
90 // for "normal-reexport":
91 /** @type {NormalReexportItem[] | null} */
92 this.items = null;
93
94 // for "reexport-named-default" | "reexport-fake-namespace-object" | "reexport-namespace-object"
95 /** @type {string | null} */
96 this.name = null;
97 /** @type {ExportInfo | null} */
98 this.partialNamespaceExportInfo = null;
99
100 // for "dynamic-reexport":
101 /** @type {ExportModeIgnored | null} */
102 this.ignored = null;
103
104 // for "dynamic-reexport" | "empty-star":
105 /** @type {ExportModeHidden | undefined | null} */
106 this.hidden = null;
107
108 // for "missing":
109 /** @type {string | null} */
110 this.userRequest = null;
111
112 // for "reexport-fake-namespace-object":
113 /** @type {number} */
114 this.fakeType = 0;
115 }
116}
117
118/**
119 * @param {ModuleGraph} moduleGraph module graph
120 * @param {TODO} dependencies dependencies
121 * @param {TODO=} additionalDependency additional dependency
122 * @returns {TODO} result
123 */
124const determineExportAssignments = (
125 moduleGraph,
126 dependencies,
127 additionalDependency
128) => {
129 const names = new Set();
130 /** @type {number[]} */
131 const dependencyIndices = [];
132
133 if (additionalDependency) {
134 dependencies = dependencies.concat(additionalDependency);
135 }
136
137 for (const dep of dependencies) {
138 const i = dependencyIndices.length;
139 dependencyIndices[i] = names.size;
140 const otherImportedModule = moduleGraph.getModule(dep);
141 if (otherImportedModule) {
142 const exportsInfo = moduleGraph.getExportsInfo(otherImportedModule);
143 for (const exportInfo of exportsInfo.exports) {
144 if (
145 exportInfo.provided === true &&
146 exportInfo.name !== "default" &&
147 !names.has(exportInfo.name)
148 ) {
149 names.add(exportInfo.name);
150 dependencyIndices[i] = names.size;
151 }
152 }
153 }
154 }
155 dependencyIndices.push(names.size);
156
157 return { names: Array.from(names), dependencyIndices };
158};
159
160const findDependencyForName = (
161 { names, dependencyIndices },
162 name,
163 dependencies
164) => {
165 const dependenciesIt = dependencies[Symbol.iterator]();
166 const dependencyIndicesIt = dependencyIndices[Symbol.iterator]();
167 let dependenciesItResult = dependenciesIt.next();
168 let dependencyIndicesItResult = dependencyIndicesIt.next();
169 if (dependencyIndicesItResult.done) return;
170 for (let i = 0; i < names.length; i++) {
171 while (i >= dependencyIndicesItResult.value) {
172 dependenciesItResult = dependenciesIt.next();
173 dependencyIndicesItResult = dependencyIndicesIt.next();
174 if (dependencyIndicesItResult.done) return;
175 }
176 if (names[i] === name) return dependenciesItResult.value;
177 }
178 return undefined;
179};
180
181/**
182 * @param {ModuleGraph} moduleGraph the module graph
183 * @param {HarmonyExportImportedSpecifierDependency} dep the dependency
184 * @param {string} runtimeKey the runtime key
185 * @returns {ExportMode} the export mode
186 */
187const getMode = (moduleGraph, dep, runtimeKey) => {
188 const importedModule = moduleGraph.getModule(dep);
189
190 if (!importedModule) {
191 const mode = new ExportMode("missing");
192
193 mode.userRequest = dep.userRequest;
194
195 return mode;
196 }
197
198 const name = dep.name;
199 const runtime = keyToRuntime(runtimeKey);
200 const parentModule = /** @type {Module} */ (moduleGraph.getParentModule(dep));
201 const exportsInfo = moduleGraph.getExportsInfo(parentModule);
202
203 if (
204 name
205 ? exportsInfo.getUsed(name, runtime) === UsageState.Unused
206 : exportsInfo.isUsed(runtime) === false
207 ) {
208 const mode = new ExportMode("unused");
209
210 mode.name = name || "*";
211
212 return mode;
213 }
214
215 const importedExportsType = importedModule.getExportsType(
216 moduleGraph,
217 /** @type {BuildMeta} */ (parentModule.buildMeta).strictHarmonyModule
218 );
219
220 const ids = dep.getIds(moduleGraph);
221
222 // Special handling for reexporting the default export
223 // from non-namespace modules
224 if (name && ids.length > 0 && ids[0] === "default") {
225 switch (importedExportsType) {
226 case "dynamic": {
227 const mode = new ExportMode("reexport-dynamic-default");
228
229 mode.name = name;
230
231 return mode;
232 }
233 case "default-only":
234 case "default-with-named": {
235 const exportInfo = exportsInfo.getReadOnlyExportInfo(name);
236 const mode = new ExportMode("reexport-named-default");
237
238 mode.name = name;
239 mode.partialNamespaceExportInfo = exportInfo;
240
241 return mode;
242 }
243 }
244 }
245
246 // reexporting with a fixed name
247 if (name) {
248 let mode;
249 const exportInfo = exportsInfo.getReadOnlyExportInfo(name);
250
251 if (ids.length > 0) {
252 // export { name as name }
253 switch (importedExportsType) {
254 case "default-only":
255 mode = new ExportMode("reexport-undefined");
256 mode.name = name;
257 break;
258 default:
259 mode = new ExportMode("normal-reexport");
260 mode.items = [
261 new NormalReexportItem(name, ids, exportInfo, false, false)
262 ];
263 break;
264 }
265 } else {
266 // export * as name
267 switch (importedExportsType) {
268 case "default-only":
269 mode = new ExportMode("reexport-fake-namespace-object");
270 mode.name = name;
271 mode.partialNamespaceExportInfo = exportInfo;
272 mode.fakeType = 0;
273 break;
274 case "default-with-named":
275 mode = new ExportMode("reexport-fake-namespace-object");
276 mode.name = name;
277 mode.partialNamespaceExportInfo = exportInfo;
278 mode.fakeType = 2;
279 break;
280 case "dynamic":
281 default:
282 mode = new ExportMode("reexport-namespace-object");
283 mode.name = name;
284 mode.partialNamespaceExportInfo = exportInfo;
285 }
286 }
287
288 return mode;
289 }
290
291 // Star reexporting
292
293 const { ignoredExports, exports, checked, hidden } = dep.getStarReexports(
294 moduleGraph,
295 runtime,
296 exportsInfo,
297 importedModule
298 );
299 if (!exports) {
300 // We have too few info about the modules
301 // Delegate the logic to the runtime code
302
303 const mode = new ExportMode("dynamic-reexport");
304 mode.ignored = ignoredExports;
305 mode.hidden = hidden;
306
307 return mode;
308 }
309
310 if (exports.size === 0) {
311 const mode = new ExportMode("empty-star");
312 mode.hidden = hidden;
313
314 return mode;
315 }
316
317 const mode = new ExportMode("normal-reexport");
318
319 mode.items = Array.from(
320 exports,
321 exportName =>
322 new NormalReexportItem(
323 exportName,
324 [exportName],
325 exportsInfo.getReadOnlyExportInfo(exportName),
326 /** @type {Set<string>} */
327 (checked).has(exportName),
328 false
329 )
330 );
331 if (hidden !== undefined) {
332 for (const exportName of hidden) {
333 mode.items.push(
334 new NormalReexportItem(
335 exportName,
336 [exportName],
337 exportsInfo.getReadOnlyExportInfo(exportName),
338 false,
339 true
340 )
341 );
342 }
343 }
344
345 return mode;
346};
347
348/** @typedef {string[]} Ids */
349/** @typedef {Set<string>} Exports */
350/** @typedef {Set<string>} Checked */
351/** @typedef {Set<string>} Hidden */
352/** @typedef {Set<string>} IgnoredExports */
353
354class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
355 /**
356 * @param {string} request the request string
357 * @param {number} sourceOrder the order in the original source file
358 * @param {Ids} ids the requested export name of the imported module
359 * @param {string | null} name the export name of for this module
360 * @param {Set<string>} activeExports other named exports in the module
361 * @param {ReadonlyArray<HarmonyExportImportedSpecifierDependency> | Iterable<HarmonyExportImportedSpecifierDependency> | null} otherStarExports other star exports in the module before this import
362 * @param {number} exportPresenceMode mode of checking export names
363 * @param {HarmonyStarExportsList | null} allStarExports all star exports in the module
364 * @param {ImportAttributes=} attributes import attributes
365 */
366 constructor(
367 request,
368 sourceOrder,
369 ids,
370 name,
371 activeExports,
372 otherStarExports,
373 exportPresenceMode,
374 allStarExports,
375 attributes
376 ) {
377 super(request, sourceOrder, attributes);
378
379 this.ids = ids;
380 this.name = name;
381 this.activeExports = activeExports;
382 this.otherStarExports = otherStarExports;
383 this.exportPresenceMode = exportPresenceMode;
384 this.allStarExports = allStarExports;
385 }
386
387 /**
388 * @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module
389 */
390 couldAffectReferencingModule() {
391 return Dependency.TRANSITIVE;
392 }
393
394 // TODO webpack 6 remove
395 get id() {
396 throw new Error("id was renamed to ids and type changed to string[]");
397 }
398
399 // TODO webpack 6 remove
400 getId() {
401 throw new Error("id was renamed to ids and type changed to string[]");
402 }
403
404 // TODO webpack 6 remove
405 setId() {
406 throw new Error("id was renamed to ids and type changed to string[]");
407 }
408
409 get type() {
410 return "harmony export imported specifier";
411 }
412
413 /**
414 * @param {ModuleGraph} moduleGraph the module graph
415 * @returns {Ids} the imported id
416 */
417 getIds(moduleGraph) {
418 return moduleGraph.getMeta(this)[idsSymbol] || this.ids;
419 }
420
421 /**
422 * @param {ModuleGraph} moduleGraph the module graph
423 * @param {Ids} ids the imported ids
424 * @returns {void}
425 */
426 setIds(moduleGraph, ids) {
427 /** @type {TODO} */
428 (moduleGraph.getMeta(this))[idsSymbol] = ids;
429 }
430
431 /**
432 * @param {ModuleGraph} moduleGraph the module graph
433 * @param {RuntimeSpec} runtime the runtime
434 * @returns {ExportMode} the export mode
435 */
436 getMode(moduleGraph, runtime) {
437 return moduleGraph.dependencyCacheProvide(
438 this,
439 getRuntimeKey(runtime),
440 getMode
441 );
442 }
443
444 /**
445 * @param {ModuleGraph} moduleGraph the module graph
446 * @param {RuntimeSpec} runtime the runtime
447 * @param {ExportsInfo} exportsInfo exports info about the current module (optional)
448 * @param {Module} importedModule the imported module (optional)
449 * @returns {{exports?: Exports, checked?: Checked, ignoredExports: IgnoredExports, hidden?: Hidden}} information
450 */
451 getStarReexports(
452 moduleGraph,
453 runtime,
454 exportsInfo = moduleGraph.getExportsInfo(
455 /** @type {Module} */ (moduleGraph.getParentModule(this))
456 ),
457 importedModule = /** @type {Module} */ (moduleGraph.getModule(this))
458 ) {
459 const importedExportsInfo = moduleGraph.getExportsInfo(importedModule);
460 const noExtraExports =
461 importedExportsInfo.otherExportsInfo.provided === false;
462 const noExtraImports =
463 exportsInfo.otherExportsInfo.getUsed(runtime) === UsageState.Unused;
464
465 const ignoredExports = new Set(["default", ...this.activeExports]);
466
467 let hiddenExports;
468 const otherStarExports =
469 this._discoverActiveExportsFromOtherStarExports(moduleGraph);
470 if (otherStarExports !== undefined) {
471 hiddenExports = new Set();
472 for (let i = 0; i < otherStarExports.namesSlice; i++) {
473 hiddenExports.add(otherStarExports.names[i]);
474 }
475 for (const e of ignoredExports) hiddenExports.delete(e);
476 }
477
478 if (!noExtraExports && !noExtraImports) {
479 return {
480 ignoredExports,
481 hidden: hiddenExports
482 };
483 }
484
485 /** @type {Exports} */
486 const exports = new Set();
487 /** @type {Checked} */
488 const checked = new Set();
489 /** @type {Hidden | undefined} */
490 const hidden = hiddenExports !== undefined ? new Set() : undefined;
491
492 if (noExtraImports) {
493 for (const exportInfo of exportsInfo.orderedExports) {
494 const name = exportInfo.name;
495 if (ignoredExports.has(name)) continue;
496 if (exportInfo.getUsed(runtime) === UsageState.Unused) continue;
497 const importedExportInfo =
498 importedExportsInfo.getReadOnlyExportInfo(name);
499 if (importedExportInfo.provided === false) continue;
500 if (hiddenExports !== undefined && hiddenExports.has(name)) {
501 /** @type {Set<string>} */
502 (hidden).add(name);
503 continue;
504 }
505 exports.add(name);
506 if (importedExportInfo.provided === true) continue;
507 checked.add(name);
508 }
509 } else if (noExtraExports) {
510 for (const importedExportInfo of importedExportsInfo.orderedExports) {
511 const name = importedExportInfo.name;
512 if (ignoredExports.has(name)) continue;
513 if (importedExportInfo.provided === false) continue;
514 const exportInfo = exportsInfo.getReadOnlyExportInfo(name);
515 if (exportInfo.getUsed(runtime) === UsageState.Unused) continue;
516 if (hiddenExports !== undefined && hiddenExports.has(name)) {
517 /** @type {ExportModeHidden} */
518 (hidden).add(name);
519 continue;
520 }
521 exports.add(name);
522 if (importedExportInfo.provided === true) continue;
523 checked.add(name);
524 }
525 }
526
527 return { ignoredExports, exports, checked, hidden };
528 }
529
530 /**
531 * @param {ModuleGraph} moduleGraph module graph
532 * @returns {null | false | GetConditionFn} function to determine if the connection is active
533 */
534 getCondition(moduleGraph) {
535 return (connection, runtime) => {
536 const mode = this.getMode(moduleGraph, runtime);
537 return mode.type !== "unused" && mode.type !== "empty-star";
538 };
539 }
540
541 /**
542 * @param {ModuleGraph} moduleGraph the module graph
543 * @returns {ConnectionState} how this dependency connects the module to referencing modules
544 */
545 getModuleEvaluationSideEffectsState(moduleGraph) {
546 return false;
547 }
548
549 /**
550 * Returns list of exports referenced by this dependency
551 * @param {ModuleGraph} moduleGraph module graph
552 * @param {RuntimeSpec} runtime the runtime for which the module is analysed
553 * @returns {(string[] | ReferencedExport)[]} referenced exports
554 */
555 getReferencedExports(moduleGraph, runtime) {
556 const mode = this.getMode(moduleGraph, runtime);
557
558 switch (mode.type) {
559 case "missing":
560 case "unused":
561 case "empty-star":
562 case "reexport-undefined":
563 return Dependency.NO_EXPORTS_REFERENCED;
564
565 case "reexport-dynamic-default":
566 return Dependency.EXPORTS_OBJECT_REFERENCED;
567
568 case "reexport-named-default": {
569 if (!mode.partialNamespaceExportInfo)
570 return Dependency.EXPORTS_OBJECT_REFERENCED;
571 /** @type {ReferencedExports} */
572 const referencedExports = [];
573 processExportInfo(
574 runtime,
575 referencedExports,
576 [],
577 /** @type {ExportInfo} */ (mode.partialNamespaceExportInfo)
578 );
579 return referencedExports;
580 }
581
582 case "reexport-namespace-object":
583 case "reexport-fake-namespace-object": {
584 if (!mode.partialNamespaceExportInfo)
585 return Dependency.EXPORTS_OBJECT_REFERENCED;
586 /** @type {ReferencedExports} */
587 const referencedExports = [];
588 processExportInfo(
589 runtime,
590 referencedExports,
591 [],
592 /** @type {ExportInfo} */ (mode.partialNamespaceExportInfo),
593 mode.type === "reexport-fake-namespace-object"
594 );
595 return referencedExports;
596 }
597
598 case "dynamic-reexport":
599 return Dependency.EXPORTS_OBJECT_REFERENCED;
600
601 case "normal-reexport": {
602 /** @type {ReferencedExports} */
603 const referencedExports = [];
604 for (const {
605 ids,
606 exportInfo,
607 hidden
608 } of /** @type {NormalReexportItem[]} */ (mode.items)) {
609 if (hidden) continue;
610 processExportInfo(runtime, referencedExports, ids, exportInfo, false);
611 }
612 return referencedExports;
613 }
614
615 default:
616 throw new Error(`Unknown mode ${mode.type}`);
617 }
618 }
619
620 /**
621 * @param {ModuleGraph} moduleGraph the module graph
622 * @returns {{ names: string[], namesSlice: number, dependencyIndices: number[], dependencyIndex: number } | undefined} exported names and their origin dependency
623 */
624 _discoverActiveExportsFromOtherStarExports(moduleGraph) {
625 if (!this.otherStarExports) return;
626
627 const i =
628 "length" in this.otherStarExports
629 ? this.otherStarExports.length
630 : countIterable(this.otherStarExports);
631 if (i === 0) return;
632
633 if (this.allStarExports) {
634 const { names, dependencyIndices } = moduleGraph.cached(
635 determineExportAssignments,
636 this.allStarExports.dependencies
637 );
638
639 return {
640 names,
641 namesSlice: dependencyIndices[i - 1],
642 dependencyIndices,
643 dependencyIndex: i
644 };
645 }
646
647 const { names, dependencyIndices } = moduleGraph.cached(
648 determineExportAssignments,
649 this.otherStarExports,
650 this
651 );
652
653 return {
654 names,
655 namesSlice: dependencyIndices[i - 1],
656 dependencyIndices,
657 dependencyIndex: i
658 };
659 }
660
661 /**
662 * Returns the exported names
663 * @param {ModuleGraph} moduleGraph module graph
664 * @returns {ExportsSpec | undefined} export names
665 */
666 getExports(moduleGraph) {
667 const mode = this.getMode(moduleGraph, undefined);
668
669 switch (mode.type) {
670 case "missing":
671 return;
672 case "dynamic-reexport": {
673 const from =
674 /** @type {ModuleGraphConnection} */
675 (moduleGraph.getConnection(this));
676 return {
677 exports: true,
678 from,
679 canMangle: false,
680 excludeExports: mode.hidden
681 ? combine(
682 /** @type {ExportModeIgnored} */ (mode.ignored),
683 mode.hidden
684 )
685 : /** @type {ExportModeIgnored} */ (mode.ignored),
686 hideExports: mode.hidden,
687 dependencies: [from.module]
688 };
689 }
690 case "empty-star":
691 return {
692 exports: [],
693 hideExports: mode.hidden,
694 dependencies: [/** @type {Module} */ (moduleGraph.getModule(this))]
695 };
696 // falls through
697 case "normal-reexport": {
698 const from =
699 /** @type {ModuleGraphConnection} */
700 (moduleGraph.getConnection(this));
701 return {
702 exports: Array.from(
703 /** @type {NormalReexportItem[]} */ (mode.items),
704 item => ({
705 name: item.name,
706 from,
707 export: item.ids,
708 hidden: item.hidden
709 })
710 ),
711 priority: 1,
712 dependencies: [from.module]
713 };
714 }
715 case "reexport-dynamic-default": {
716 const from =
717 /** @type {ModuleGraphConnection} */
718 (moduleGraph.getConnection(this));
719 return {
720 exports: [
721 {
722 name: /** @type {string} */ (mode.name),
723 from,
724 export: ["default"]
725 }
726 ],
727 priority: 1,
728 dependencies: [from.module]
729 };
730 }
731 case "reexport-undefined":
732 return {
733 exports: [/** @type {string} */ (mode.name)],
734 dependencies: [/** @type {Module} */ (moduleGraph.getModule(this))]
735 };
736 case "reexport-fake-namespace-object": {
737 const from =
738 /** @type {ModuleGraphConnection} */
739 (moduleGraph.getConnection(this));
740 return {
741 exports: [
742 {
743 name: /** @type {string} */ (mode.name),
744 from,
745 export: null,
746 exports: [
747 {
748 name: "default",
749 canMangle: false,
750 from,
751 export: null
752 }
753 ]
754 }
755 ],
756 priority: 1,
757 dependencies: [from.module]
758 };
759 }
760 case "reexport-namespace-object": {
761 const from =
762 /** @type {ModuleGraphConnection} */
763 (moduleGraph.getConnection(this));
764 return {
765 exports: [
766 {
767 name: /** @type {string} */ (mode.name),
768 from,
769 export: null
770 }
771 ],
772 priority: 1,
773 dependencies: [from.module]
774 };
775 }
776 case "reexport-named-default": {
777 const from =
778 /** @type {ModuleGraphConnection} */
779 (moduleGraph.getConnection(this));
780 return {
781 exports: [
782 {
783 name: /** @type {string} */ (mode.name),
784 from,
785 export: ["default"]
786 }
787 ],
788 priority: 1,
789 dependencies: [from.module]
790 };
791 }
792 default:
793 throw new Error(`Unknown mode ${mode.type}`);
794 }
795 }
796
797 /**
798 * @param {ModuleGraph} moduleGraph module graph
799 * @returns {number} effective mode
800 */
801 _getEffectiveExportPresenceLevel(moduleGraph) {
802 if (this.exportPresenceMode !== ExportPresenceModes.AUTO)
803 return this.exportPresenceMode;
804 const module = /** @type {Module} */ (moduleGraph.getParentModule(this));
805 return /** @type {BuildMeta} */ (module.buildMeta).strictHarmonyModule
806 ? ExportPresenceModes.ERROR
807 : ExportPresenceModes.WARN;
808 }
809
810 /**
811 * Returns warnings
812 * @param {ModuleGraph} moduleGraph module graph
813 * @returns {WebpackError[] | null | undefined} warnings
814 */
815 getWarnings(moduleGraph) {
816 const exportsPresence = this._getEffectiveExportPresenceLevel(moduleGraph);
817 if (exportsPresence === ExportPresenceModes.WARN) {
818 return this._getErrors(moduleGraph);
819 }
820 return null;
821 }
822
823 /**
824 * Returns errors
825 * @param {ModuleGraph} moduleGraph module graph
826 * @returns {WebpackError[] | null | undefined} errors
827 */
828 getErrors(moduleGraph) {
829 const exportsPresence = this._getEffectiveExportPresenceLevel(moduleGraph);
830 if (exportsPresence === ExportPresenceModes.ERROR) {
831 return this._getErrors(moduleGraph);
832 }
833 return null;
834 }
835
836 /**
837 * @param {ModuleGraph} moduleGraph module graph
838 * @returns {WebpackError[] | undefined} errors
839 */
840 _getErrors(moduleGraph) {
841 const ids = this.getIds(moduleGraph);
842 let errors = this.getLinkingErrors(
843 moduleGraph,
844 ids,
845 `(reexported as '${this.name}')`
846 );
847 if (ids.length === 0 && this.name === null) {
848 const potentialConflicts =
849 this._discoverActiveExportsFromOtherStarExports(moduleGraph);
850 if (potentialConflicts && potentialConflicts.namesSlice > 0) {
851 const ownNames = new Set(
852 potentialConflicts.names.slice(
853 potentialConflicts.namesSlice,
854 potentialConflicts.dependencyIndices[
855 potentialConflicts.dependencyIndex
856 ]
857 )
858 );
859 const importedModule = moduleGraph.getModule(this);
860 if (importedModule) {
861 const exportsInfo = moduleGraph.getExportsInfo(importedModule);
862 /** @type {Map<string, string[]>} */
863 const conflicts = new Map();
864 for (const exportInfo of exportsInfo.orderedExports) {
865 if (exportInfo.provided !== true) continue;
866 if (exportInfo.name === "default") continue;
867 if (this.activeExports.has(exportInfo.name)) continue;
868 if (ownNames.has(exportInfo.name)) continue;
869 const conflictingDependency = findDependencyForName(
870 potentialConflicts,
871 exportInfo.name,
872 this.allStarExports
873 ? this.allStarExports.dependencies
874 : [...this.otherStarExports, this]
875 );
876 if (!conflictingDependency) continue;
877 const target = exportInfo.getTerminalBinding(moduleGraph);
878 if (!target) continue;
879 const conflictingModule =
880 /** @type {Module} */
881 (moduleGraph.getModule(conflictingDependency));
882 if (conflictingModule === importedModule) continue;
883 const conflictingExportInfo = moduleGraph.getExportInfo(
884 conflictingModule,
885 exportInfo.name
886 );
887 const conflictingTarget =
888 conflictingExportInfo.getTerminalBinding(moduleGraph);
889 if (!conflictingTarget) continue;
890 if (target === conflictingTarget) continue;
891 const list = conflicts.get(conflictingDependency.request);
892 if (list === undefined) {
893 conflicts.set(conflictingDependency.request, [exportInfo.name]);
894 } else {
895 list.push(exportInfo.name);
896 }
897 }
898 for (const [request, exports] of conflicts) {
899 if (!errors) errors = [];
900 errors.push(
901 new HarmonyLinkingError(
902 `The requested module '${
903 this.request
904 }' contains conflicting star exports for the ${
905 exports.length > 1 ? "names" : "name"
906 } ${exports
907 .map(e => `'${e}'`)
908 .join(", ")} with the previous requested module '${request}'`
909 )
910 );
911 }
912 }
913 }
914 }
915 return errors;
916 }
917
918 /**
919 * @param {ObjectSerializerContext} context context
920 */
921 serialize(context) {
922 const { write, setCircularReference } = context;
923
924 setCircularReference(this);
925 write(this.ids);
926 write(this.name);
927 write(this.activeExports);
928 write(this.otherStarExports);
929 write(this.exportPresenceMode);
930 write(this.allStarExports);
931
932 super.serialize(context);
933 }
934
935 /**
936 * @param {ObjectDeserializerContext} context context
937 */
938 deserialize(context) {
939 const { read, setCircularReference } = context;
940
941 setCircularReference(this);
942 this.ids = read();
943 this.name = read();
944 this.activeExports = read();
945 this.otherStarExports = read();
946 this.exportPresenceMode = read();
947 this.allStarExports = read();
948
949 super.deserialize(context);
950 }
951}
952
953makeSerializable(
954 HarmonyExportImportedSpecifierDependency,
955 "webpack/lib/dependencies/HarmonyExportImportedSpecifierDependency"
956);
957
958module.exports = HarmonyExportImportedSpecifierDependency;
959
960HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedSpecifierDependencyTemplate extends (
961 HarmonyImportDependency.Template
962) {
963 /**
964 * @param {Dependency} dependency the dependency for which the template should be applied
965 * @param {ReplaceSource} source the current replace source which can be modified
966 * @param {DependencyTemplateContext} templateContext the context object
967 * @returns {void}
968 */
969 apply(dependency, source, templateContext) {
970 const { moduleGraph, runtime, concatenationScope } = templateContext;
971
972 const dep = /** @type {HarmonyExportImportedSpecifierDependency} */ (
973 dependency
974 );
975
976 const mode = dep.getMode(moduleGraph, runtime);
977
978 if (concatenationScope) {
979 switch (mode.type) {
980 case "reexport-undefined":
981 concatenationScope.registerRawExport(
982 /** @type {NonNullable<ExportMode["name"]>} */ (mode.name),
983 "/* reexport non-default export from non-harmony */ undefined"
984 );
985 }
986 return;
987 }
988
989 if (mode.type !== "unused" && mode.type !== "empty-star") {
990 super.apply(dependency, source, templateContext);
991
992 this._addExportFragments(
993 templateContext.initFragments,
994 dep,
995 mode,
996 templateContext.module,
997 moduleGraph,
998 runtime,
999 templateContext.runtimeTemplate,
1000 templateContext.runtimeRequirements
1001 );
1002 }
1003 }
1004
1005 /**
1006 * @param {InitFragment<GenerateContext>[]} initFragments target array for init fragments
1007 * @param {HarmonyExportImportedSpecifierDependency} dep dependency
1008 * @param {ExportMode} mode the export mode
1009 * @param {Module} module the current module
1010 * @param {ModuleGraph} moduleGraph the module graph
1011 * @param {RuntimeSpec} runtime the runtime
1012 * @param {RuntimeTemplate} runtimeTemplate the runtime template
1013 * @param {RuntimeRequirements} runtimeRequirements runtime requirements
1014 * @returns {void}
1015 */
1016 _addExportFragments(
1017 initFragments,
1018 dep,
1019 mode,
1020 module,
1021 moduleGraph,
1022 runtime,
1023 runtimeTemplate,
1024 runtimeRequirements
1025 ) {
1026 const importedModule = /** @type {Module} */ (moduleGraph.getModule(dep));
1027 const importVar = dep.getImportVar(moduleGraph);
1028
1029 switch (mode.type) {
1030 case "missing":
1031 case "empty-star":
1032 initFragments.push(
1033 new InitFragment(
1034 "/* empty/unused harmony star reexport */\n",
1035 InitFragment.STAGE_HARMONY_EXPORTS,
1036 1
1037 )
1038 );
1039 break;
1040
1041 case "unused":
1042 initFragments.push(
1043 new InitFragment(
1044 `${Template.toNormalComment(
1045 `unused harmony reexport ${mode.name}`
1046 )}\n`,
1047 InitFragment.STAGE_HARMONY_EXPORTS,
1048 1
1049 )
1050 );
1051 break;
1052
1053 case "reexport-dynamic-default":
1054 initFragments.push(
1055 this.getReexportFragment(
1056 module,
1057 "reexport default from dynamic",
1058 moduleGraph
1059 .getExportsInfo(module)
1060 .getUsedName(/** @type {string} */ (mode.name), runtime),
1061 importVar,
1062 null,
1063 runtimeRequirements
1064 )
1065 );
1066 break;
1067
1068 case "reexport-fake-namespace-object":
1069 initFragments.push(
1070 ...this.getReexportFakeNamespaceObjectFragments(
1071 module,
1072 moduleGraph
1073 .getExportsInfo(module)
1074 .getUsedName(/** @type {string} */ (mode.name), runtime),
1075 importVar,
1076 mode.fakeType,
1077 runtimeRequirements
1078 )
1079 );
1080 break;
1081
1082 case "reexport-undefined":
1083 initFragments.push(
1084 this.getReexportFragment(
1085 module,
1086 "reexport non-default export from non-harmony",
1087 moduleGraph
1088 .getExportsInfo(module)
1089 .getUsedName(/** @type {string} */ (mode.name), runtime),
1090 "undefined",
1091 "",
1092 runtimeRequirements
1093 )
1094 );
1095 break;
1096
1097 case "reexport-named-default":
1098 initFragments.push(
1099 this.getReexportFragment(
1100 module,
1101 "reexport default export from named module",
1102 moduleGraph
1103 .getExportsInfo(module)
1104 .getUsedName(/** @type {string} */ (mode.name), runtime),
1105 importVar,
1106 "",
1107 runtimeRequirements
1108 )
1109 );
1110 break;
1111
1112 case "reexport-namespace-object":
1113 initFragments.push(
1114 this.getReexportFragment(
1115 module,
1116 "reexport module object",
1117 moduleGraph
1118 .getExportsInfo(module)
1119 .getUsedName(/** @type {string} */ (mode.name), runtime),
1120 importVar,
1121 "",
1122 runtimeRequirements
1123 )
1124 );
1125 break;
1126
1127 case "normal-reexport":
1128 for (const {
1129 name,
1130 ids,
1131 checked,
1132 hidden
1133 } of /** @type {NormalReexportItem[]} */ (mode.items)) {
1134 if (hidden) continue;
1135 if (checked) {
1136 const connection = moduleGraph.getConnection(dep);
1137 const key = `harmony reexport (checked) ${importVar} ${name}`;
1138 const runtimeCondition = dep.weak
1139 ? false
1140 : connection
1141 ? filterRuntime(runtime, r => connection.isTargetActive(r))
1142 : true;
1143 initFragments.push(
1144 new ConditionalInitFragment(
1145 `/* harmony reexport (checked) */ ${this.getConditionalReexportStatement(
1146 module,
1147 name,
1148 importVar,
1149 ids,
1150 runtimeRequirements
1151 )}`,
1152 moduleGraph.isAsync(importedModule)
1153 ? InitFragment.STAGE_ASYNC_HARMONY_IMPORTS
1154 : InitFragment.STAGE_HARMONY_IMPORTS,
1155 dep.sourceOrder,
1156 key,
1157 runtimeCondition
1158 )
1159 );
1160 } else {
1161 initFragments.push(
1162 this.getReexportFragment(
1163 module,
1164 "reexport safe",
1165 moduleGraph.getExportsInfo(module).getUsedName(name, runtime),
1166 importVar,
1167 moduleGraph
1168 .getExportsInfo(importedModule)
1169 .getUsedName(ids, runtime),
1170 runtimeRequirements
1171 )
1172 );
1173 }
1174 }
1175 break;
1176
1177 case "dynamic-reexport": {
1178 const ignored = mode.hidden
1179 ? combine(
1180 /** @type {ExportModeIgnored} */
1181 (mode.ignored),
1182 mode.hidden
1183 )
1184 : /** @type {ExportModeIgnored} */ (mode.ignored);
1185 const modern =
1186 runtimeTemplate.supportsConst() &&
1187 runtimeTemplate.supportsArrowFunction();
1188 let content =
1189 "/* harmony reexport (unknown) */ var __WEBPACK_REEXPORT_OBJECT__ = {};\n" +
1190 `/* harmony reexport (unknown) */ for(${
1191 modern ? "const" : "var"
1192 } __WEBPACK_IMPORT_KEY__ in ${importVar}) `;
1193
1194 // Filter out exports which are defined by other exports
1195 // and filter out default export because it cannot be reexported with *
1196 if (ignored.size > 1) {
1197 content += `if(${JSON.stringify(
1198 Array.from(ignored)
1199 )}.indexOf(__WEBPACK_IMPORT_KEY__) < 0) `;
1200 } else if (ignored.size === 1) {
1201 content += `if(__WEBPACK_IMPORT_KEY__ !== ${JSON.stringify(
1202 first(ignored)
1203 )}) `;
1204 }
1205
1206 content += "__WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = ";
1207 content += modern
1208 ? `() => ${importVar}[__WEBPACK_IMPORT_KEY__]`
1209 : `function(key) { return ${importVar}[key]; }.bind(0, __WEBPACK_IMPORT_KEY__)`;
1210
1211 runtimeRequirements.add(RuntimeGlobals.exports);
1212 runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
1213
1214 const exportsName = module.exportsArgument;
1215 initFragments.push(
1216 new InitFragment(
1217 `${content}\n/* harmony reexport (unknown) */ ${RuntimeGlobals.definePropertyGetters}(${exportsName}, __WEBPACK_REEXPORT_OBJECT__);\n`,
1218 moduleGraph.isAsync(importedModule)
1219 ? InitFragment.STAGE_ASYNC_HARMONY_IMPORTS
1220 : InitFragment.STAGE_HARMONY_IMPORTS,
1221 dep.sourceOrder
1222 )
1223 );
1224 break;
1225 }
1226
1227 default:
1228 throw new Error(`Unknown mode ${mode.type}`);
1229 }
1230 }
1231
1232 /**
1233 * @param {Module} module the current module
1234 * @param {string} comment comment
1235 * @param {UsedName} key key
1236 * @param {string} name name
1237 * @param {string | string[] | null | false} valueKey value key
1238 * @param {RuntimeRequirements} runtimeRequirements runtime requirements
1239 * @returns {HarmonyExportInitFragment} harmony export init fragment
1240 */
1241 getReexportFragment(
1242 module,
1243 comment,
1244 key,
1245 name,
1246 valueKey,
1247 runtimeRequirements
1248 ) {
1249 const returnValue = this.getReturnValue(name, valueKey);
1250
1251 runtimeRequirements.add(RuntimeGlobals.exports);
1252 runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
1253
1254 const map = new Map();
1255 map.set(key, `/* ${comment} */ ${returnValue}`);
1256
1257 return new HarmonyExportInitFragment(module.exportsArgument, map);
1258 }
1259
1260 /**
1261 * @param {Module} module module
1262 * @param {string | string[] | false} key key
1263 * @param {string} name name
1264 * @param {number} fakeType fake type
1265 * @param {RuntimeRequirements} runtimeRequirements runtime requirements
1266 * @returns {[InitFragment<GenerateContext>, HarmonyExportInitFragment]} init fragments
1267 */
1268 getReexportFakeNamespaceObjectFragments(
1269 module,
1270 key,
1271 name,
1272 fakeType,
1273 runtimeRequirements
1274 ) {
1275 runtimeRequirements.add(RuntimeGlobals.exports);
1276 runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
1277 runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
1278
1279 const map = new Map();
1280 map.set(
1281 key,
1282 `/* reexport fake namespace object from non-harmony */ ${name}_namespace_cache || (${name}_namespace_cache = ${
1283 RuntimeGlobals.createFakeNamespaceObject
1284 }(${name}${fakeType ? `, ${fakeType}` : ""}))`
1285 );
1286
1287 return [
1288 new InitFragment(
1289 `var ${name}_namespace_cache;\n`,
1290 InitFragment.STAGE_CONSTANTS,
1291 -1,
1292 `${name}_namespace_cache`
1293 ),
1294 new HarmonyExportInitFragment(module.exportsArgument, map)
1295 ];
1296 }
1297
1298 /**
1299 * @param {Module} module module
1300 * @param {string} key key
1301 * @param {string} name name
1302 * @param {string | string[] | false} valueKey value key
1303 * @param {RuntimeRequirements} runtimeRequirements runtime requirements
1304 * @returns {string} result
1305 */
1306 getConditionalReexportStatement(
1307 module,
1308 key,
1309 name,
1310 valueKey,
1311 runtimeRequirements
1312 ) {
1313 if (valueKey === false) {
1314 return "/* unused export */\n";
1315 }
1316
1317 const exportsName = module.exportsArgument;
1318 const returnValue = this.getReturnValue(name, valueKey);
1319
1320 runtimeRequirements.add(RuntimeGlobals.exports);
1321 runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
1322 runtimeRequirements.add(RuntimeGlobals.hasOwnProperty);
1323
1324 return `if(${RuntimeGlobals.hasOwnProperty}(${name}, ${JSON.stringify(
1325 valueKey[0]
1326 )})) ${
1327 RuntimeGlobals.definePropertyGetters
1328 }(${exportsName}, { ${propertyName(
1329 key
1330 )}: function() { return ${returnValue}; } });\n`;
1331 }
1332
1333 /**
1334 * @param {string} name name
1335 * @param {null | false | string | string[]} valueKey value key
1336 * @returns {string | undefined} value
1337 */
1338 getReturnValue(name, valueKey) {
1339 if (valueKey === null) {
1340 return `${name}_default.a`;
1341 }
1342
1343 if (valueKey === "") {
1344 return name;
1345 }
1346
1347 if (valueKey === false) {
1348 return "/* unused export */ undefined";
1349 }
1350
1351 return `${name}${propertyAccess(valueKey)}`;
1352 }
1353};
1354
1355class HarmonyStarExportsList {
1356 constructor() {
1357 /** @type {HarmonyExportImportedSpecifierDependency[]} */
1358 this.dependencies = [];
1359 }
1360
1361 /**
1362 * @param {HarmonyExportImportedSpecifierDependency} dep dependency
1363 * @returns {void}
1364 */
1365 push(dep) {
1366 this.dependencies.push(dep);
1367 }
1368
1369 slice() {
1370 return this.dependencies.slice();
1371 }
1372
1373 /**
1374 * @param {ObjectSerializerContext} context context
1375 */
1376 serialize({ write, setCircularReference }) {
1377 setCircularReference(this);
1378 write(this.dependencies);
1379 }
1380
1381 /**
1382 * @param {ObjectDeserializerContext} context context
1383 */
1384 deserialize({ read, setCircularReference }) {
1385 setCircularReference(this);
1386 this.dependencies = read();
1387 }
1388}
1389
1390makeSerializable(
1391 HarmonyStarExportsList,
1392 "webpack/lib/dependencies/HarmonyExportImportedSpecifierDependency",
1393 "HarmonyStarExportsList"
1394);
1395
1396module.exports.HarmonyStarExportsList = HarmonyStarExportsList;
Note: See TracBrowser for help on using the repository browser.