HarmonyExportImportedSpecifierDependency.js 43 KB

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