index.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = loader;
  6. var _loaderUtils = require("loader-utils");
  7. var _schemaUtils = require("schema-utils");
  8. var _postcss = _interopRequireDefault(require("postcss"));
  9. var _semver = require("semver");
  10. var _package = _interopRequireDefault(require("postcss/package.json"));
  11. var _Warning = _interopRequireDefault(require("./Warning"));
  12. var _Error = _interopRequireDefault(require("./Error"));
  13. var _options = _interopRequireDefault(require("./options.json"));
  14. var _utils = require("./utils");
  15. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  16. /**
  17. * **PostCSS Loader**
  18. *
  19. * Loads && processes CSS with [PostCSS](https://github.com/postcss/postcss)
  20. *
  21. * @method loader
  22. *
  23. * @param {String} content Source
  24. * @param {Object} sourceMap Source Map
  25. * @param {Object} meta Meta
  26. *
  27. * @return {callback} callback Result
  28. */
  29. async function loader(content, sourceMap, meta) {
  30. const options = (0, _loaderUtils.getOptions)(this);
  31. (0, _schemaUtils.validate)(_options.default, options, {
  32. name: 'PostCSS Loader',
  33. baseDataPath: 'options'
  34. });
  35. const callback = this.async();
  36. const configOption = typeof options.postcssOptions === 'undefined' || typeof options.postcssOptions.config === 'undefined' ? true : options.postcssOptions.config;
  37. let loadedConfig;
  38. if (configOption) {
  39. try {
  40. loadedConfig = await (0, _utils.loadConfig)(this, configOption);
  41. } catch (error) {
  42. callback(error);
  43. return;
  44. }
  45. }
  46. const useSourceMap = typeof options.sourceMap !== 'undefined' ? options.sourceMap : this.sourceMap;
  47. const {
  48. plugins,
  49. processOptions
  50. } = (0, _utils.getPostcssOptions)(this, loadedConfig, options.postcssOptions);
  51. if (useSourceMap) {
  52. processOptions.map = {
  53. inline: false,
  54. annotation: false,
  55. ...processOptions.map
  56. };
  57. }
  58. if (sourceMap && processOptions.map) {
  59. processOptions.map.prev = (0, _utils.normalizeSourceMap)(sourceMap, this.context);
  60. }
  61. let root; // Reuse PostCSS AST from other loaders
  62. if (meta && meta.ast && meta.ast.type === 'postcss' && (0, _semver.satisfies)(meta.ast.version, `^${_package.default.version}`)) {
  63. ({
  64. root
  65. } = meta.ast);
  66. }
  67. if (!root && options.execute) {
  68. // eslint-disable-next-line no-param-reassign
  69. content = (0, _utils.exec)(content, this);
  70. }
  71. let result;
  72. try {
  73. result = await (0, _postcss.default)(plugins).process(root || content, processOptions);
  74. } catch (error) {
  75. if (error.file) {
  76. this.addDependency(error.file);
  77. }
  78. if (error.name === 'CssSyntaxError') {
  79. callback(new _Error.default(error));
  80. } else {
  81. callback(error);
  82. }
  83. return;
  84. }
  85. for (const warning of result.warnings()) {
  86. this.emitWarning(new _Warning.default(warning));
  87. }
  88. for (const message of result.messages) {
  89. if (message.type === 'dependency') {
  90. this.addDependency(message.file);
  91. }
  92. if (message.type === 'asset' && message.content && message.file) {
  93. this.emitFile(message.file, message.content, message.sourceMap, message.info);
  94. }
  95. } // eslint-disable-next-line no-undefined
  96. let map = result.map ? result.map.toJSON() : undefined;
  97. if (map && useSourceMap) {
  98. map = (0, _utils.normalizeSourceMapAfterPostcss)(map, this.context);
  99. }
  100. const ast = {
  101. type: 'postcss',
  102. version: result.processor.version,
  103. root: result.root
  104. };
  105. callback(null, result.css, map, {
  106. ast
  107. });
  108. }