HarmonyExportImportedSpecifierDependency.js 39 KB

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