Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add custom eslint formatter #2136

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 0 additions & 49 deletions packages/react-dev-utils/formatWebpackMessages.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,55 +85,6 @@ function formatMessage(message, isError) {
);
}

// TODO: Ideally we should write a custom ESLint formatter instead.

// If the second line already includes a filename, and it's a warning,
// this is likely coming from ESLint. Skip it because Webpack also prints it.
// Let's omit that in this case.
var BEGIN_ESLINT_FILENAME = String.fromCharCode(27) + '[4m';
// Also filter out ESLint summaries for each file
var BEGIN_ESLINT_WARNING_SUMMARY = String.fromCharCode(27) +
'[33m' +
String.fromCharCode(27) +
'[1m' +
String.fromCharCode(10006);
var BEGIN_ESLINT_ERROR_SUMMARY = String.fromCharCode(27) +
'[31m' +
String.fromCharCode(27) +
'[1m' +
String.fromCharCode(10006);
// ESLint puts separators like this between groups. We don't need them:
var ESLINT_EMPTY_SEPARATOR = String.fromCharCode(27) +
'[22m' +
String.fromCharCode(27) +
'[39m';
// Go!
lines = lines.filter(function(line) {
if (line === ESLINT_EMPTY_SEPARATOR) {
return false;
}
if (
line.indexOf(BEGIN_ESLINT_FILENAME) === 0 ||
line.indexOf(BEGIN_ESLINT_WARNING_SUMMARY) === 0 ||
line.indexOf(BEGIN_ESLINT_ERROR_SUMMARY) === 0
) {
return false;
}
return true;
});

var ESLINT_WARNING_LABEL = String.fromCharCode(27) +
'[33m' +
'warning' +
String.fromCharCode(27) +
'[39m';
// If there were errors, omit any warnings.
if (isError) {
lines = lines.filter(function(line) {
return line.indexOf(ESLINT_WARNING_LABEL) === -1;
});
}

// Prepend filename with an explanation.
lines[0] =
// Underline
Expand Down
63 changes: 63 additions & 0 deletions packages/react-scripts/config/formatter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
'use strict';

const chalk = require('chalk');
const table = require('text-table');

function isError(message) {
if (message.fatal || message.severity === 2) {
return true;
}
return false;
}

function formatter(results) {
let output = '\n';

results.forEach(result => {
let messages = result.messages;
if (messages.length === 0) {
return '';
}

let thereAreErrors = false;
messages = messages.map(message => {
let messageType;
if (isError(message)) {
messageType = 'error';
thereAreErrors = true;
} else {
messageType = 'warn';
}
let line = message.line || 0;
let column = message.column || 0;
let position = chalk.dim(`${line}:${column}`);
return [
'',
position,
messageType,
message.message.replace(/\.$/, ''),
chalk.dim(message.ruleId || ''),
];
});
// if there are error messages, we want to show only errors
if (thereAreErrors) {
messages = messages.filter(m => m[2] === 'error');
}
// add color to messageTypes
messages = messages.map(m => {
m[2] = m[2] === 'error' ? chalk.red(m[2]) : chalk.yellow(m[2]);
return m;
});
let outputTable = table(messages, {
align: ['l', 'l', 'l'],
stringLength(str) {
return chalk.stripColor(str).length;
},
});
output += `${outputTable}\n\n`;
});

return output;
}

module.exports = formatter;
2 changes: 2 additions & 0 deletions packages/react-scripts/config/webpack.config.dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
const getClientEnvironment = require('./env');
const paths = require('./paths');
const formatter = require('formatter');

// Webpack uses `publicPath` to determine where the app is being served from.
// In development, we always serve from the root. This makes config easier.
Expand Down Expand Up @@ -123,6 +124,7 @@ module.exports = {
// @remove-on-eject-begin
// Point ESLint to our predefined config.
options: {
formatter,
baseConfig: {
extends: ['react-app'],
},
Expand Down