Dashboard sipadu mbip
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

friendly-errors-plugin.js 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. 'use strict';
  2. const path = require('path');
  3. const chalk = require('chalk');
  4. const os = require('os');
  5. const transformErrors = require('./core/transformErrors');
  6. const formatErrors = require('./core/formatErrors');
  7. const output = require('./output');
  8. const utils = require('./utils');
  9. const concat = utils.concat;
  10. const uniqueBy = utils.uniqueBy;
  11. const defaultTransformers = [
  12. require('./transformers/babelSyntax'),
  13. require('./transformers/moduleNotFound'),
  14. require('./transformers/esLintError'),
  15. ];
  16. const defaultFormatters = [
  17. require('./formatters/moduleNotFound'),
  18. require('./formatters/eslintError'),
  19. require('./formatters/defaultError'),
  20. ];
  21. class FriendlyErrorsWebpackPlugin {
  22. constructor(options) {
  23. options = options || {};
  24. this.compilationSuccessInfo = options.compilationSuccessInfo || {};
  25. this.onErrors = options.onErrors;
  26. this.shouldClearConsole = options.clearConsole == null ? true : Boolean(options.clearConsole);
  27. this.formatters = concat(defaultFormatters, options.additionalFormatters);
  28. this.transformers = concat(defaultTransformers, options.additionalTransformers);
  29. }
  30. apply(compiler) {
  31. const doneFn = stats => {
  32. this.clearConsole();
  33. const hasErrors = stats.hasErrors();
  34. const hasWarnings = stats.hasWarnings();
  35. if (!hasErrors && !hasWarnings) {
  36. this.displaySuccess(stats);
  37. return;
  38. }
  39. if (hasErrors) {
  40. this.displayErrors(extractErrorsFromStats(stats, 'errors'), 'error');
  41. return;
  42. }
  43. if (hasWarnings) {
  44. this.displayErrors(extractErrorsFromStats(stats, 'warnings'), 'warning');
  45. }
  46. };
  47. const invalidFn = () => {
  48. this.clearConsole();
  49. output.title('info', 'WAIT', 'Compiling...');
  50. };
  51. if (compiler.hooks) {
  52. const plugin = { name: 'FriendlyErrorsWebpackPlugin' };
  53. compiler.hooks.done.tap(plugin, doneFn);
  54. compiler.hooks.invalid.tap(plugin, invalidFn);
  55. } else {
  56. compiler.plugin('done', doneFn);
  57. compiler.plugin('invalid', invalidFn);
  58. }
  59. }
  60. clearConsole() {
  61. if (this.shouldClearConsole) {
  62. output.clearConsole();
  63. }
  64. }
  65. displaySuccess(stats) {
  66. const time = getCompileTime(stats);
  67. output.title('success', 'DONE', 'Compiled successfully in ' + time + 'ms');
  68. if (this.compilationSuccessInfo.messages) {
  69. this.compilationSuccessInfo.messages.forEach(message => output.info(message));
  70. }
  71. if (this.compilationSuccessInfo.notes) {
  72. output.log();
  73. this.compilationSuccessInfo.notes.forEach(note => output.note(note));
  74. }
  75. }
  76. displayErrors(errors, severity) {
  77. const processedErrors = transformErrors(errors, this.transformers);
  78. const topErrors = getMaxSeverityErrors(processedErrors);
  79. const nbErrors = topErrors.length;
  80. const subtitle = severity === 'error' ?
  81. `Failed to compile with ${nbErrors} ${severity}s` :
  82. `Compiled with ${nbErrors} ${severity}s`;
  83. output.title(severity, severity.toUpperCase(), subtitle);
  84. if (this.onErrors) {
  85. this.onErrors(severity, topErrors);
  86. }
  87. formatErrors(topErrors, this.formatters, severity)
  88. .forEach(chunk => output.log(chunk));
  89. }
  90. }
  91. function extractErrorsFromStats(stats, type) {
  92. if (isMultiStats(stats)) {
  93. const errors = stats.stats
  94. .reduce((errors, stats) => errors.concat(extractErrorsFromStats(stats, type)), []);
  95. // Dedupe to avoid showing the same error many times when multiple
  96. // compilers depend on the same module.
  97. return uniqueBy(errors, error => error.message);
  98. }
  99. return stats.compilation[type];
  100. }
  101. function getCompileTime(stats) {
  102. if (isMultiStats(stats)) {
  103. // Webpack multi compilations run in parallel so using the longest duration.
  104. // https://webpack.github.io/docs/configuration.html#multiple-configurations
  105. return stats.stats
  106. .reduce((time, stats) => Math.max(time, getCompileTime(stats)), 0);
  107. }
  108. return stats.endTime - stats.startTime;
  109. }
  110. function isMultiStats(stats) {
  111. return stats.stats;
  112. }
  113. function getMaxSeverityErrors(errors) {
  114. const maxSeverity = getMaxInt(errors, 'severity');
  115. return errors.filter(e => e.severity === maxSeverity);
  116. }
  117. function getMaxInt(collection, propertyName) {
  118. return collection.reduce((res, curr) => {
  119. return curr[propertyName] > res ? curr[propertyName] : res;
  120. }, 0)
  121. }
  122. module.exports = FriendlyErrorsWebpackPlugin;