HarmonyExportImportedSpecifierDependency.js 42 KB

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