index.js 4.7 KB

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