HarmonyExportImportedSpecifierDependency.js 39 KB

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