JsonParser.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const Parser = require("../Parser");
  7. const JsonExportsDependency = require("../dependencies/JsonExportsDependency");
  8. const memoize = require("../util/memoize");
  9. const JsonData = require("./JsonData");
  10. /** @typedef {import("../../declarations/plugins/JsonModulesPluginParser").JsonModulesPluginParserOptions} JsonModulesPluginParserOptions */
  11. /** @typedef {import("../Module").BuildInfo} BuildInfo */
  12. /** @typedef {import("../Module").BuildMeta} BuildMeta */
  13. /** @typedef {import("../Parser").ParserState} ParserState */
  14. /** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
  15. /** @typedef {import("./JsonModulesPlugin").RawJsonData} RawJsonData */
  16. const getParseJson = memoize(() => require("json-parse-even-better-errors"));
  17. class JsonParser extends Parser {
  18. /**
  19. * @param {JsonModulesPluginParserOptions} options parser options
  20. */
  21. constructor(options) {
  22. super();
  23. this.options = options || {};
  24. }
  25. /**
  26. * @param {string | Buffer | PreparsedAst} source the source to parse
  27. * @param {ParserState} state the parser state
  28. * @returns {ParserState} the parser state
  29. */
  30. parse(source, state) {
  31. if (Buffer.isBuffer(source)) {
  32. source = source.toString("utf-8");
  33. }
  34. /** @type {NonNullable<JsonModulesPluginParserOptions["parse"]>} */
  35. const parseFn =
  36. typeof this.options.parse === "function"
  37. ? this.options.parse
  38. : getParseJson();
  39. /** @type {Buffer | RawJsonData | undefined} */
  40. let data;
  41. try {
  42. data =
  43. typeof source === "object"
  44. ? source
  45. : parseFn(source[0] === "\ufeff" ? source.slice(1) : source);
  46. } catch (e) {
  47. throw new Error(`Cannot parse JSON: ${/** @type {Error} */ (e).message}`);
  48. }
  49. const jsonData = new JsonData(/** @type {Buffer | RawJsonData} */ (data));
  50. const buildInfo = /** @type {BuildInfo} */ (state.module.buildInfo);
  51. buildInfo.jsonData = jsonData;
  52. buildInfo.strict = true;
  53. const buildMeta = /** @type {BuildMeta} */ (state.module.buildMeta);
  54. buildMeta.exportsType = "default";
  55. buildMeta.defaultObject =
  56. typeof data === "object" ? "redirect-warn" : false;
  57. state.module.addDependency(new JsonExportsDependency(jsonData));
  58. return state;
  59. }
  60. }
  61. module.exports = JsonParser;