JsonExportsDependency.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const makeSerializable = require("../util/makeSerializable");
  7. const NullDependency = require("./NullDependency");
  8. /**
  9. * @import {
  10. * ExportSpec,
  11. * ExportsSpec,
  12. * UpdateHashContext
  13. * } from "../Dependency"
  14. */
  15. /** @import ModuleGraph from "../ModuleGraph" */
  16. /** @import JsonData from "../json/JsonData" */
  17. /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext<[JsonData, number]>} ObjectDeserializerContext */
  18. /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext<[JsonData, number]>} ObjectSerializerContext */
  19. /** @import { JsonValue } from "../util/fs" */
  20. /** @import Hash from "../util/Hash" */
  21. /**
  22. * Defines the get exports from data fn callback.
  23. * @callback GetExportsFromDataFn
  24. * @param {JsonValue} data raw json data
  25. * @param {number=} curDepth current depth
  26. * @returns {ExportSpec[] | null} export spec or nothing
  27. */
  28. /**
  29. * Gets exports with depth.
  30. * @param {number} exportsDepth exportsDepth
  31. * @returns {GetExportsFromDataFn} value
  32. */
  33. const getExportsWithDepth = (exportsDepth) =>
  34. /** @type {GetExportsFromDataFn} */
  35. function getExportsFromData(data, curDepth = 1) {
  36. if (curDepth > exportsDepth) {
  37. return null;
  38. }
  39. if (data && typeof data === "object") {
  40. if (Array.isArray(data)) {
  41. return data.length < 100
  42. ? data.map((item, idx) => ({
  43. name: `${idx}`,
  44. canMangle: true,
  45. exports: getExportsFromData(item, curDepth + 1) || undefined
  46. }))
  47. : null;
  48. }
  49. /** @type {ExportSpec[]} */
  50. const exports = [];
  51. for (const key of Object.keys(data)) {
  52. exports.push({
  53. name: key,
  54. canMangle: true,
  55. exports:
  56. getExportsFromData(
  57. /** @type {JsonValue} */
  58. (data[key]),
  59. curDepth + 1
  60. ) || undefined
  61. });
  62. }
  63. return exports;
  64. }
  65. return null;
  66. };
  67. class JsonExportsDependency extends NullDependency {
  68. /**
  69. * Creates an instance of JsonExportsDependency.
  70. * @param {JsonData} data json data
  71. * @param {number} exportsDepth the depth of json exports to analyze
  72. */
  73. constructor(data, exportsDepth) {
  74. super();
  75. /** @type {JsonData} */
  76. this.data = data;
  77. /** @type {number} */
  78. this.exportsDepth = exportsDepth;
  79. }
  80. get type() {
  81. return "json exports";
  82. }
  83. /**
  84. * Returns the exported names
  85. * @param {ModuleGraph} moduleGraph module graph
  86. * @returns {ExportsSpec | undefined} export names
  87. */
  88. getExports(moduleGraph) {
  89. return {
  90. exports: getExportsWithDepth(this.exportsDepth)(
  91. this.data && /** @type {JsonValue} */ (this.data.get())
  92. ),
  93. dependencies: undefined
  94. };
  95. }
  96. /**
  97. * Updates the hash with the data contributed by this instance.
  98. * @param {Hash} hash hash to be updated
  99. * @param {UpdateHashContext} context context
  100. * @returns {void}
  101. */
  102. updateHash(hash, context) {
  103. this.data.updateHash(hash);
  104. }
  105. /**
  106. * Serializes this instance into the provided serializer context.
  107. * @param {ObjectSerializerContext} context context
  108. */
  109. serialize(context) {
  110. context.write(this.data).write(this.exportsDepth);
  111. super.serialize(context);
  112. }
  113. /**
  114. * Restores this instance from the provided deserializer context.
  115. * @param {ObjectDeserializerContext} context context
  116. */
  117. deserialize(context) {
  118. this.data = context.read();
  119. const c1 = context.rest;
  120. this.exportsDepth = c1.read();
  121. super.deserialize(c1.rest);
  122. }
  123. }
  124. makeSerializable(
  125. JsonExportsDependency,
  126. "webpack/lib/dependencies/JsonExportsDependency"
  127. );
  128. module.exports = JsonExportsDependency;