index.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = loader;
  6. var _path = _interopRequireDefault(require("path"));
  7. var _options = _interopRequireDefault(require("./options.json"));
  8. var _utils = require("./utils");
  9. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  10. /*
  11. MIT License http://www.opensource.org/licenses/mit-license.php
  12. Author Tobias Koppers @sokra
  13. */
  14. async function loader(input, inputMap) {
  15. const options = this.getOptions(_options.default);
  16. const {
  17. sourceMappingURL,
  18. replacementString
  19. } = (0, _utils.getSourceMappingURL)(input);
  20. const callback = this.async();
  21. if (!sourceMappingURL) {
  22. callback(null, input, inputMap);
  23. return;
  24. }
  25. let behaviourSourceMappingUrl;
  26. try {
  27. behaviourSourceMappingUrl = typeof options.filterSourceMappingUrl !== "undefined" ? options.filterSourceMappingUrl(sourceMappingURL, this.resourcePath) : "consume";
  28. } catch (error) {
  29. callback(error);
  30. return;
  31. } // eslint-disable-next-line default-case
  32. switch (behaviourSourceMappingUrl) {
  33. case "skip":
  34. callback(null, input, inputMap);
  35. return;
  36. case false:
  37. case "remove":
  38. callback(null, input.replace(replacementString, ""), inputMap);
  39. return;
  40. }
  41. let sourceURL;
  42. let sourceContent;
  43. try {
  44. ({
  45. sourceURL,
  46. sourceContent
  47. } = await (0, _utils.fetchFromURL)(this, this.context, sourceMappingURL));
  48. } catch (error) {
  49. this.emitWarning(error);
  50. callback(null, input, inputMap);
  51. return;
  52. }
  53. if (sourceURL) {
  54. this.addDependency(sourceURL);
  55. }
  56. let map;
  57. try {
  58. map = JSON.parse(sourceContent.replace(/^\)\]\}'/, ""));
  59. } catch (parseError) {
  60. this.emitWarning(new Error(`Failed to parse source map from '${sourceMappingURL}': ${parseError}`));
  61. callback(null, input, inputMap);
  62. return;
  63. }
  64. const context = sourceURL ? _path.default.dirname(sourceURL) : this.context;
  65. if (map.sections) {
  66. // eslint-disable-next-line no-param-reassign
  67. map = await (0, _utils.flattenSourceMap)(map);
  68. }
  69. const resolvedSources = await Promise.all(map.sources.map(async (source, i) => {
  70. // eslint-disable-next-line no-shadow
  71. let sourceURL; // eslint-disable-next-line no-shadow
  72. let sourceContent;
  73. const originalSourceContent = map.sourcesContent && typeof map.sourcesContent[i] !== "undefined" && map.sourcesContent[i] !== null ? map.sourcesContent[i] : // eslint-disable-next-line no-undefined
  74. undefined;
  75. const skipReading = typeof originalSourceContent !== "undefined";
  76. let errored = false; // We do not skipReading here, because we need absolute paths in sources.
  77. // This is necessary so that for sourceMaps with the same file structure in sources, name collisions do not occur.
  78. // https://github.com/webpack-contrib/source-map-loader/issues/51
  79. try {
  80. ({
  81. sourceURL,
  82. sourceContent
  83. } = await (0, _utils.fetchFromURL)(this, context, source, map.sourceRoot, skipReading));
  84. } catch (error) {
  85. errored = true;
  86. this.emitWarning(error);
  87. }
  88. if (skipReading) {
  89. sourceContent = originalSourceContent;
  90. } else if (!errored && sourceURL && !(0, _utils.isURL)(sourceURL)) {
  91. this.addDependency(sourceURL);
  92. } // Return original value of `source` when error happens
  93. return {
  94. sourceURL: errored ? source : sourceURL,
  95. sourceContent
  96. };
  97. }));
  98. const newMap = { ...map
  99. };
  100. newMap.sources = [];
  101. newMap.sourcesContent = [];
  102. delete newMap.sourceRoot;
  103. resolvedSources.forEach(source => {
  104. // eslint-disable-next-line no-shadow
  105. const {
  106. sourceURL,
  107. sourceContent
  108. } = source;
  109. newMap.sources.push(sourceURL || "");
  110. newMap.sourcesContent.push(sourceContent || "");
  111. });
  112. const sourcesContentIsEmpty = newMap.sourcesContent.filter(entry => Boolean(entry)).length === 0;
  113. if (sourcesContentIsEmpty) {
  114. delete newMap.sourcesContent;
  115. }
  116. callback(null, input.replace(replacementString, ""), newMap);
  117. }