index.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. "use strict";
  2. var babel = require("babel-core");
  3. var loaderUtils = require("loader-utils");
  4. var path = require("path");
  5. var cache = require("./fs-cache.js");
  6. var exists = require("./utils/exists");
  7. var relative = require("./utils/relative");
  8. var read = require("./utils/read");
  9. var resolveRc = require("./resolve-rc.js");
  10. var pkg = require("../package.json");
  11. var fs = require("fs");
  12. /**
  13. * Error thrown by Babel formatted to conform to Webpack reporting.
  14. */
  15. function BabelLoaderError(name, message, codeFrame, hideStack, error) {
  16. Error.call(this);
  17. this.name = "BabelLoaderError";
  18. this.message = formatMessage(name, message, codeFrame);
  19. this.hideStack = hideStack;
  20. this.error = error;
  21. Error.captureStackTrace(this, BabelLoaderError);
  22. }
  23. BabelLoaderError.prototype = Object.create(Error.prototype);
  24. BabelLoaderError.prototype.constructor = BabelLoaderError;
  25. var STRIP_FILENAME_RE = /^[^:]+: /;
  26. var formatMessage = function formatMessage(name, message, codeFrame) {
  27. return (name ? name + ": " : "") + message + "\n\n" + codeFrame + "\n";
  28. };
  29. var transpile = function transpile(source, options) {
  30. var forceEnv = options.forceEnv;
  31. var tmpEnv = void 0;
  32. delete options.forceEnv;
  33. if (forceEnv) {
  34. tmpEnv = process.env.BABEL_ENV;
  35. process.env.BABEL_ENV = forceEnv;
  36. }
  37. var result = void 0;
  38. try {
  39. result = babel.transform(source, options);
  40. } catch (error) {
  41. if (forceEnv) restoreBabelEnv(tmpEnv);
  42. if (error.message && error.codeFrame) {
  43. var message = error.message;
  44. var name = void 0;
  45. var hideStack = void 0;
  46. if (error instanceof SyntaxError) {
  47. message = message.replace(STRIP_FILENAME_RE, "");
  48. name = "SyntaxError";
  49. hideStack = true;
  50. } else if (error instanceof TypeError) {
  51. message = message.replace(STRIP_FILENAME_RE, "");
  52. hideStack = true;
  53. }
  54. throw new BabelLoaderError(name, message, error.codeFrame, hideStack, error);
  55. } else {
  56. throw error;
  57. }
  58. }
  59. var code = result.code;
  60. var map = result.map;
  61. var metadata = result.metadata;
  62. if (map && (!map.sourcesContent || !map.sourcesContent.length)) {
  63. map.sourcesContent = [source];
  64. }
  65. if (forceEnv) restoreBabelEnv(tmpEnv);
  66. return {
  67. code: code,
  68. map: map,
  69. metadata: metadata
  70. };
  71. };
  72. function restoreBabelEnv(prevValue) {
  73. if (prevValue === undefined) {
  74. delete process.env.BABEL_ENV;
  75. } else {
  76. process.env.BABEL_ENV = prevValue;
  77. }
  78. }
  79. function passMetadata(s, context, metadata) {
  80. if (context[s]) {
  81. context[s](metadata);
  82. }
  83. }
  84. module.exports = function (source, inputSourceMap) {
  85. var _this = this;
  86. var filename = this.resourcePath;
  87. // Handle options
  88. var loaderOptions = loaderUtils.getOptions(this) || {};
  89. var fileSystem = this.fs ? this.fs : fs;
  90. var babelrcPath = null;
  91. if (loaderOptions.babelrc !== false) {
  92. babelrcPath = typeof loaderOptions.babelrc === "string" && exists(fileSystem, loaderOptions.babelrc) ? loaderOptions.babelrc : resolveRc(fileSystem, path.dirname(filename));
  93. }
  94. if (babelrcPath) {
  95. this.addDependency(babelrcPath);
  96. }
  97. var defaultOptions = {
  98. metadataSubscribers: [],
  99. inputSourceMap: inputSourceMap,
  100. sourceRoot: process.cwd(),
  101. filename: filename,
  102. cacheIdentifier: JSON.stringify({
  103. "babel-loader": pkg.version,
  104. "babel-core": babel.version,
  105. babelrc: babelrcPath ? read(fileSystem, babelrcPath) : null,
  106. env: loaderOptions.forceEnv || process.env.BABEL_ENV || process.env.NODE_ENV || "development"
  107. })
  108. };
  109. var options = Object.assign({}, defaultOptions, loaderOptions);
  110. if (loaderOptions.sourceMap === undefined) {
  111. options.sourceMap = this.sourceMap;
  112. }
  113. if (options.sourceFileName === undefined) {
  114. options.sourceFileName = relative(options.sourceRoot, options.filename);
  115. }
  116. var cacheDirectory = options.cacheDirectory;
  117. var cacheIdentifier = options.cacheIdentifier;
  118. var metadataSubscribers = options.metadataSubscribers;
  119. delete options.cacheDirectory;
  120. delete options.cacheIdentifier;
  121. delete options.metadataSubscribers;
  122. if (cacheDirectory) {
  123. var callback = this.async();
  124. return cache({
  125. directory: cacheDirectory,
  126. identifier: cacheIdentifier,
  127. source: source,
  128. options: options,
  129. transform: transpile
  130. }, function (err) {
  131. var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
  132. code = _ref.code,
  133. map = _ref.map,
  134. metadata = _ref.metadata;
  135. if (err) return callback(err);
  136. metadataSubscribers.forEach(function (s) {
  137. return passMetadata(s, _this, metadata);
  138. });
  139. return callback(null, code, map);
  140. });
  141. }
  142. var _transpile = transpile(source, options),
  143. code = _transpile.code,
  144. map = _transpile.map,
  145. metadata = _transpile.metadata;
  146. metadataSubscribers.forEach(function (s) {
  147. return passMetadata(s, _this, metadata);
  148. });
  149. this.callback(null, code, map);
  150. };