JsonGenerator.js 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const { ConcatSource, RawSource } = require("webpack-sources");
  7. const stringifySafe = data => {
  8. const stringified = JSON.stringify(data);
  9. if (!stringified) {
  10. return undefined; // Invalid JSON
  11. }
  12. return stringified.replace(/\u2028|\u2029/g, str =>
  13. str === "\u2029" ? "\\u2029" : "\\u2028"
  14. ); // invalid in JavaScript but valid JSON
  15. };
  16. class JsonGenerator {
  17. generate(module, dependencyTemplates, runtimeTemplate) {
  18. const source = new ConcatSource();
  19. const data = module.buildInfo.jsonData;
  20. if (data === undefined) {
  21. return new RawSource(
  22. runtimeTemplate.missingModuleStatement({
  23. request: module.rawRequest
  24. })
  25. );
  26. }
  27. let finalJson;
  28. if (
  29. Array.isArray(module.buildMeta.providedExports) &&
  30. !module.isUsed("default")
  31. ) {
  32. // Only some exports are used: We can optimize here, by only generating a part of the JSON
  33. const reducedJson = {};
  34. for (const exportName of module.buildMeta.providedExports) {
  35. if (exportName === "default") continue;
  36. const used = module.isUsed(exportName);
  37. if (used) {
  38. reducedJson[used] = data[exportName];
  39. }
  40. }
  41. finalJson = reducedJson;
  42. } else {
  43. finalJson = data;
  44. }
  45. // Use JSON because JSON.parse() is much faster than JavaScript evaluation
  46. const jsonSource = JSON.stringify(stringifySafe(finalJson));
  47. const jsonExpr = `JSON.parse(${jsonSource})`;
  48. source.add(`${module.moduleArgument}.exports = ${jsonExpr};`);
  49. return source;
  50. }
  51. }
  52. module.exports = JsonGenerator;