1
0
Fork 0
mirror of https://github.com/terribleplan/next.js.git synced 2024-01-19 02:48:18 +00:00

Update webpack message formatter (#6299)

This commit is contained in:
Joe Haddad 2019-02-14 11:13:35 -05:00 committed by GitHub
parent 4051ffcb01
commit 9bb8fbf535
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,7 +1,7 @@
/** /**
MIT License MIT License
Copyright (c) 2013-present, Facebook, Inc. Copyright (c) 2015-present, Facebook, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@ -21,16 +21,12 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
// This file is based on https://github.com/facebook/create-react-app/blob/v1.1.4/packages/react-dev-utils/formatWebpackMessages.js // This file is based on https://github.com/facebook/create-react-app/blob/7b1a32be6ec9f99a6c9a3c66813f3ac09c4736b9/packages/react-dev-utils/formatWebpackMessages.js
// It's been edited to remove chalk // It's been edited to remove chalk and CRA-specific logic
'use strict' 'use strict'
// Some custom utilities to prettify Webpack output. const friendlySyntaxErrorLabel = 'Syntax error:'
// This is quite hacky and hopefully won't be needed when Webpack fixes this.
// https://github.com/webpack/webpack/issues/2878
var friendlySyntaxErrorLabel = 'Syntax error:'
function isLikelyASyntaxError (message) { function isLikelyASyntaxError (message) {
return message.indexOf(friendlySyntaxErrorLabel) !== -1 return message.indexOf(friendlySyntaxErrorLabel) !== -1
@ -39,112 +35,99 @@ function isLikelyASyntaxError (message) {
// Cleans up webpack error messages. // Cleans up webpack error messages.
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
function formatMessage (message, isError) { function formatMessage (message, isError) {
var lines = message.split('\n') let lines = message.split('\n')
if (lines.length > 2 && lines[1] === '') { // Strip Webpack-added headers off errors/warnings
// Remove extra newline. // https://github.com/webpack/webpack/blob/master/lib/ModuleError.js
lines = lines.filter(line => !/Module [A-z ]+\(from/.test(line))
// Transform parsing error into syntax error
// TODO: move this to our ESLint formatter?
lines = lines.map(line => {
const parsingError = /Line (\d+):(?:(\d+):)?\s*Parsing error: (.+)$/.exec(
line
)
if (!parsingError) {
return line
}
const [, errorLine, errorColumn, errorMessage] = parsingError
return `${friendlySyntaxErrorLabel} ${errorMessage} (${errorLine}:${errorColumn})`
})
message = lines.join('\n')
// Smoosh syntax errors (commonly found in CSS)
message = message.replace(
/SyntaxError\s+\((\d+):(\d+)\)\s*(.+?)\n/g,
`${friendlySyntaxErrorLabel} $3 ($1:$2)\n`
)
// Remove columns from ESLint formatter output (we added these for more
// accurate syntax errors)
message = message.replace(/Line (\d+):\d+:/g, 'Line $1:')
// Clean up export errors
message = message.replace(
/^.*export '(.+?)' was not found in '(.+?)'.*$/gm,
`Attempted import error: '$1' is not exported from '$2'.`
)
message = message.replace(
/^.*export 'default' \(imported as '(.+?)'\) was not found in '(.+?)'.*$/gm,
`Attempted import error: '$2' does not contain a default export (imported as '$1').`
)
message = message.replace(
/^.*export '(.+?)' \(imported as '(.+?)'\) was not found in '(.+?)'.*$/gm,
`Attempted import error: '$1' is not exported from '$3' (imported as '$2').`
)
lines = message.split('\n')
// Remove leading newline
if (lines.length > 2 && lines[1].trim() === '') {
lines.splice(1, 1) lines.splice(1, 1)
} }
// Clean up file name
// Remove webpack-specific loader notation from filename. lines[0] = lines[0].replace(/^(.*) \d+:\d+-\d+$/, '$1')
// Before:
// ./~/css-loader!./~/postcss-loader!./src/App.css
// After:
// ./src/App.css
if (lines[0].lastIndexOf('!') !== -1) {
lines[0] = lines[0].substr(lines[0].lastIndexOf('!') + 1)
}
// Remove unnecessary stack added by `thread-loader`
var threadLoaderIndex = -1
lines.forEach(function (line, index) {
if (threadLoaderIndex !== -1) {
return
}
if (/thread.loader/i.test(line)) {
threadLoaderIndex = index
}
})
if (threadLoaderIndex !== -1) {
lines = lines.slice(0, threadLoaderIndex)
}
lines = lines.filter(function (line) {
// Webpack adds a list of entry points to warning messages:
// @ ./src/index.js
// @ multi react-scripts/~/react-dev-utils/webpackHotDevClient.js ...
// It is misleading (and unrelated to the warnings) so we clean it up.
// It is only useful for syntax errors but we have beautiful frames for them.
return line.indexOf(' @ ') !== 0
})
// line #0 is filename
// line #1 is the main error message
if (!lines[0] || !lines[1]) {
return lines.join('\n')
}
// Cleans up verbose "module not found" messages for files and packages. // Cleans up verbose "module not found" messages for files and packages.
if (lines[1].indexOf('Module not found: ') === 0) { if (lines[1] && lines[1].indexOf('Module not found: ') === 0) {
lines = [ lines = [
lines[0], lines[0],
// Clean up message because "Module not found: " is descriptive enough.
lines[1] lines[1]
.replace("Cannot resolve 'file' or 'directory' ", '')
.replace('Cannot resolve module ', '')
.replace('Error: ', '') .replace('Error: ', '')
.replace('[CaseSensitivePathsPlugin] ', '') .replace('Module not found: Cannot find file:', 'Cannot find file:')
] ]
} }
// Cleans up syntax error messages.
if (lines[1].indexOf('Module build failed: ') === 0) {
lines[1] = lines[1].replace(
'Module build failed: SyntaxError:',
friendlySyntaxErrorLabel
)
}
// Clean up export errors.
// TODO: we should really send a PR to Webpack for this.
var exportError = /\s*(.+?)\s*(")?export '(.+?)' was not found in '(.+?)'/
if (lines[1].match(exportError)) {
lines[1] = lines[1].replace(
exportError,
"$1 '$4' does not contain an export named '$3'."
)
}
// Reassemble the message.
message = lines.join('\n') message = lines.join('\n')
// Internal stacks are generally useless so we strip them... with the // Internal stacks are generally useless so we strip them... with the
// exception of stacks containing `webpack:` because they're normally // exception of stacks containing `webpack:` because they're normally
// from user code generated by WebPack. For more information see // from user code generated by Webpack. For more information see
// https://github.com/facebook/create-react-app/pull/1050 // https://github.com/facebook/create-react-app/pull/1050
message = message.replace( message = message.replace(
/^\s*at\s((?!webpack:).)*:\d+:\d+[\s)]*(\n|$)/gm, /^\s*at\s((?!webpack:).)*:\d+:\d+[\s)]*(\n|$)/gm,
'' ''
) // at ... ...:x:y ) // at ... ...:x:y
message = message.replace(/^\s*at\s<anonymous>(\n|$)/gm, '') // at <anonymous>
lines = message.split('\n')
// Remove duplicated newlines
lines = lines.filter(
(line, index, arr) =>
index === 0 || line.trim() !== '' || line.trim() !== arr[index - 1].trim()
)
// Reassemble the message
message = lines.join('\n')
return message.trim() return message.trim()
} }
function formatWebpackMessages (json) { function formatWebpackMessages (json) {
var formattedErrors = json.errors.map(function (message) { const formattedErrors = json.errors.map(function (message) {
return formatMessage(message, true) return formatMessage(message, true)
}) })
var formattedWarnings = json.warnings.map(function (message) { const formattedWarnings = json.warnings.map(function (message) {
return formatMessage(message, false) return formatMessage(message, false)
}) })
var result = { const result = { errors: formattedErrors, warnings: formattedWarnings }
errors: formattedErrors,
warnings: formattedWarnings
}
if (result.errors.some(isLikelyASyntaxError)) { if (result.errors.some(isLikelyASyntaxError)) {
// If there are any syntax errors, show just them. // If there are any syntax errors, show just them.
// This prevents a confusing ESLint parsing error
// preceding a much more useful Babel syntax error.
result.errors = result.errors.filter(isLikelyASyntaxError) result.errors = result.errors.filter(isLikelyASyntaxError)
} }
return result return result