123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- 'use strict';
-
- const path = require('path');
- const chalk = require('chalk');
- const os = require('os');
- const transformErrors = require('./core/transformErrors');
- const formatErrors = require('./core/formatErrors');
- const output = require('./output');
- const utils = require('./utils');
-
- const concat = utils.concat;
- const uniqueBy = utils.uniqueBy;
-
- const defaultTransformers = [
- require('./transformers/babelSyntax'),
- require('./transformers/moduleNotFound'),
- require('./transformers/esLintError'),
- ];
-
- const defaultFormatters = [
- require('./formatters/moduleNotFound'),
- require('./formatters/eslintError'),
- require('./formatters/defaultError'),
- ];
-
- class FriendlyErrorsWebpackPlugin {
-
- constructor(options) {
- options = options || {};
- this.compilationSuccessInfo = options.compilationSuccessInfo || {};
- this.onErrors = options.onErrors;
- this.shouldClearConsole = options.clearConsole == null ? true : Boolean(options.clearConsole);
- this.formatters = concat(defaultFormatters, options.additionalFormatters);
- this.transformers = concat(defaultTransformers, options.additionalTransformers);
- }
-
- apply(compiler) {
-
- const doneFn = stats => {
- this.clearConsole();
-
- const hasErrors = stats.hasErrors();
- const hasWarnings = stats.hasWarnings();
-
- if (!hasErrors && !hasWarnings) {
- this.displaySuccess(stats);
- return;
- }
-
- if (hasErrors) {
- this.displayErrors(extractErrorsFromStats(stats, 'errors'), 'error');
- return;
- }
-
- if (hasWarnings) {
- this.displayErrors(extractErrorsFromStats(stats, 'warnings'), 'warning');
- }
- };
-
- const invalidFn = () => {
- this.clearConsole();
- output.title('info', 'WAIT', 'Compiling...');
- };
-
- if (compiler.hooks) {
- const plugin = { name: 'FriendlyErrorsWebpackPlugin' };
-
- compiler.hooks.done.tap(plugin, doneFn);
- compiler.hooks.invalid.tap(plugin, invalidFn);
- } else {
- compiler.plugin('done', doneFn);
- compiler.plugin('invalid', invalidFn);
- }
- }
-
- clearConsole() {
- if (this.shouldClearConsole) {
- output.clearConsole();
- }
- }
-
- displaySuccess(stats) {
- const time = getCompileTime(stats);
- output.title('success', 'DONE', 'Compiled successfully in ' + time + 'ms');
-
- if (this.compilationSuccessInfo.messages) {
- this.compilationSuccessInfo.messages.forEach(message => output.info(message));
- }
- if (this.compilationSuccessInfo.notes) {
- output.log();
- this.compilationSuccessInfo.notes.forEach(note => output.note(note));
- }
- }
-
- displayErrors(errors, severity) {
- const processedErrors = transformErrors(errors, this.transformers);
-
- const topErrors = getMaxSeverityErrors(processedErrors);
- const nbErrors = topErrors.length;
-
- const subtitle = severity === 'error' ?
- `Failed to compile with ${nbErrors} ${severity}s` :
- `Compiled with ${nbErrors} ${severity}s`;
- output.title(severity, severity.toUpperCase(), subtitle);
-
- if (this.onErrors) {
- this.onErrors(severity, topErrors);
- }
-
- formatErrors(topErrors, this.formatters, severity)
- .forEach(chunk => output.log(chunk));
- }
- }
-
- function extractErrorsFromStats(stats, type) {
- if (isMultiStats(stats)) {
- const errors = stats.stats
- .reduce((errors, stats) => errors.concat(extractErrorsFromStats(stats, type)), []);
- // Dedupe to avoid showing the same error many times when multiple
- // compilers depend on the same module.
- return uniqueBy(errors, error => error.message);
- }
- return stats.compilation[type];
- }
-
- function getCompileTime(stats) {
- if (isMultiStats(stats)) {
- // Webpack multi compilations run in parallel so using the longest duration.
- // https://webpack.github.io/docs/configuration.html#multiple-configurations
- return stats.stats
- .reduce((time, stats) => Math.max(time, getCompileTime(stats)), 0);
- }
- return stats.endTime - stats.startTime;
- }
-
- function isMultiStats(stats) {
- return stats.stats;
- }
-
- function getMaxSeverityErrors(errors) {
- const maxSeverity = getMaxInt(errors, 'severity');
- return errors.filter(e => e.severity === maxSeverity);
- }
-
- function getMaxInt(collection, propertyName) {
- return collection.reduce((res, curr) => {
- return curr[propertyName] > res ? curr[propertyName] : res;
- }, 0)
- }
-
- module.exports = FriendlyErrorsWebpackPlugin;
|