source: frontend/node_modules/webpack/lib/dependencies/HarmonyExportImportedSpecifierDependency.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 13 days ago

Fix frontend appearance

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