JsonExportsDependency.js 3.6 KB

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