Make errors and warnings nicer (#50)

* Make errors and warnings nicer

* Fix license stripping to not be eager

* Minor tweaks
This commit is contained in:
Dan Abramov
2016-07-21 05:04:57 +01:00
committed by GitHub
parent 9652973e64
commit 9df1c2ff16
6 changed files with 221 additions and 211 deletions

View File

@@ -70,7 +70,7 @@ prompt('Are you sure you want to eject? This action is permanent. [y/N]', functi
console.log('Copying ' + file + ' to ' + hostPath);
var content = fs.readFileSync(path.join(selfPath, file), 'utf8');
// Remove license header
content = content.replace(/\/\*[\s\S]+\*\//, '').trim() + '\n';
content = content.replace(/^\/\*\*(\*(?!\/)|[^*])*\*\//, '').trim() + '\n';
fs.writeFileSync(path.join(hostPath, file), content);
});

View File

@@ -9,6 +9,7 @@
process.env.NODE_ENV = 'development';
var chalk = require('chalk');
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('../config/webpack.config.dev');
@@ -18,7 +19,7 @@ var opn = require('opn');
var handleCompile;
if (process.argv[2] === '--smoke-test') {
handleCompile = function (err, stats) {
if (err || stats.toJson().errors.length || stats.toJson().warnings.length) {
if (err || stats.hasErrors() || stats.hasWarnings()) {
process.exit(1);
} else {
process.exit(0);
@@ -26,31 +27,99 @@ if (process.argv[2] === '--smoke-test') {
};
}
new WebpackDevServer(webpack(config, handleCompile), {
publicPath: config.output.publicPath,
var friendlySyntaxErrorLabel = 'Syntax error:';
function isLikelyASyntaxError(message) {
return message.indexOf(friendlySyntaxErrorLabel) !== -1;
}
// This is a little hacky.
// It would be easier if webpack provided a rich error object.
function formatMessage(message) {
return message
// Make some common errors shorter:
.replace(
// Babel syntax error
'Module build failed: SyntaxError:',
friendlySyntaxErrorLabel
)
.replace(
// Webpack file not found error
/Module not found: Error: Cannot resolve 'file' or 'directory'/,
'Module not found:'
)
// Internal stacks are generally useless so we strip them
.replace(/^\s*at\s.*\(.*:\d+:\d+\.*\).*\n/gm, '') // at ... (...:x:y)
// Webpack loader names obscure CSS filenames
.replace('./~/css-loader!./~/postcss-loader!', '');
}
var compiler = webpack(config, handleCompile);
compiler.plugin('done', function (stats) {
// Clear the console and reset the cursor
process.stdout.write('\x1B[2J\x1B[0f');
var hasErrors = stats.hasErrors();
var hasWarnings = stats.hasWarnings();
if (!hasErrors && !hasWarnings) {
console.log(chalk.green('Compiled successfully!'));
console.log();
console.log('The app is running at http://localhost:3000/');
console.log();
return;
}
var json = stats.toJson();
var formattedErrors = json.errors.map(message =>
'Error in ' + formatMessage(message)
);
var formattedWarnings = json.warnings.map(message =>
'Warning in ' + formatMessage(message)
);
if (hasErrors) {
console.log(chalk.red('There were errors compiling.'));
console.log();
if (formattedErrors.some(isLikelyASyntaxError)) {
// If there are any syntax errors, show just them.
// This prevents a confusing ESLint parsing error
// preceding a much more useful Babel syntax error.
formattedErrors = formattedErrors.filter(isLikelyASyntaxError);
}
formattedErrors.forEach(message => {
console.log(message);
console.log();
});
// If errors exist, ignore warnings.
return;
}
if (hasWarnings) {
console.log(chalk.yellow('Compiled with warnings.'));
console.log();
formattedWarnings.forEach(message => {
console.log(message);
console.log();
});
console.log('You may use special comments to disable some warnings.');
console.log('Use ' + chalk.yellow('// eslint-disable-next-line') + ' to ignore the next line.');
console.log('Use ' + chalk.yellow('/* eslint-disable */') + ' to ignore all warnings in a file.');
}
});
new WebpackDevServer(compiler, {
historyApiFallback: true,
hot: true, // Note: only CSS is currently hot reloaded
stats: {
hash: false,
version: false,
timings: false,
assets: false,
chunks: false,
modules: false,
reasons: false,
children: false,
source: false,
publicPath: false,
colors: true,
errors: true,
errorDetails: true,
warnings: true,
}
publicPath: config.output.publicPath,
quiet: true
}).listen(3000, 'localhost', function (err, result) {
if (err) {
return console.log(err);
}
console.log('Running development server at http://localhost:3000/');
console.log('Starting the development server...');
opn('http://localhost:3000/');
});