| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | import stripAnsi from 'next/dist/compiled/strip-ansi' |
| | |
| | |
| |
|
| | const friendlySyntaxErrorLabel = 'Syntax error:' |
| |
|
| | const WEBPACK_BREAKING_CHANGE_POLYFILLS = |
| | '\n\nBREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.' |
| |
|
| | function isLikelyASyntaxError(message: string) { |
| | return stripAnsi(message).includes(friendlySyntaxErrorLabel) |
| | } |
| |
|
| | let hadMissingSassError = false |
| |
|
| | |
| | function formatMessage( |
| | message: any, |
| | verbose?: boolean, |
| | importTraceNote?: boolean |
| | ) { |
| | |
| | if (typeof message === 'object' && message.message) { |
| | const filteredModuleTrace = |
| | message.moduleTrace && |
| | message.moduleTrace.filter( |
| | (trace: any) => |
| | !/next-(middleware|client-pages|route|edge-function)-loader\.js/.test( |
| | trace.originName |
| | ) |
| | ) |
| |
|
| | let body = message.message |
| | const breakingChangeIndex = body.indexOf(WEBPACK_BREAKING_CHANGE_POLYFILLS) |
| | if (breakingChangeIndex >= 0) { |
| | body = body.slice(0, breakingChangeIndex) |
| | } |
| |
|
| | |
| | |
| | if ( |
| | process.env.NEXT_RSPACK && |
| | !message.moduleName && |
| | !message.file && |
| | message.moduleIdentifier |
| | ) { |
| | const parts = message.moduleIdentifier.split('!') |
| | message.moduleName = parts[parts.length - 1] |
| | } |
| |
|
| | message = |
| | (message.moduleName ? stripAnsi(message.moduleName) + '\n' : '') + |
| | (message.file ? stripAnsi(message.file) + '\n' : '') + |
| | body + |
| | (message.details && verbose ? '\n' + message.details : '') + |
| | (filteredModuleTrace && filteredModuleTrace.length |
| | ? (importTraceNote || '\n\nImport trace for requested module:') + |
| | filteredModuleTrace |
| | .map((trace: any) => `\n${trace.moduleName}`) |
| | .join('') |
| | : '') + |
| | (message.stack && verbose ? '\n' + message.stack : '') |
| | } |
| | let lines = message.split('\n') |
| |
|
| | |
| | |
| | lines = lines.filter((line: string) => !/Module [A-z ]+\(from/.test(line)) |
| |
|
| | |
| | |
| | lines = lines.map((line: string) => { |
| | 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') |
| | |
| | message = message.replace( |
| | /SyntaxError\s+\((\d+):(\d+)\)\s*(.+?)\n/g, |
| | `${friendlySyntaxErrorLabel} $3 ($1:$2)\n` |
| | ) |
| | |
| | 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') |
| |
|
| | |
| | if (lines.length > 2 && lines[1].trim() === '') { |
| | lines.splice(1, 1) |
| | } |
| |
|
| | |
| | if (lines[1] && lines[1].startsWith('Module not found: ')) { |
| | lines = [ |
| | lines[0], |
| | lines[1] |
| | .replace('Error: ', '') |
| | .replace('Module not found: Cannot find file:', 'Cannot find file:'), |
| | ...lines.slice(2), |
| | ] |
| | } |
| |
|
| | |
| | if (lines[1] && lines[1].match(/Cannot find module.+sass/)) { |
| | |
| | const firstLine = lines[0].split('!') |
| | lines[0] = firstLine[firstLine.length - 1] |
| |
|
| | lines[1] = |
| | "To use Next.js' built-in Sass support, you first need to install `sass`.\n" |
| | lines[1] += 'Run `npm i sass` or `yarn add sass` inside your workspace.\n' |
| | lines[1] += '\nLearn more: https://nextjs.org/docs/messages/install-sass' |
| |
|
| | |
| | lines = lines.slice(0, 2) |
| | hadMissingSassError = true |
| | } else if ( |
| | hadMissingSassError && |
| | message.match(/(sass-loader|resolve-url-loader: CSS error)/) |
| | ) { |
| | |
| | lines = [] |
| | } |
| |
|
| | if (!verbose) { |
| | message = lines.join('\n') |
| | |
| | |
| | |
| | |
| | message = message.replace( |
| | /^\s*at\s((?!webpack:).)*:\d+:\d+[\s)]*(\n|$)/gm, |
| | '' |
| | ) |
| | message = message.replace(/^\s*at\s<anonymous>(\n|$)/gm, '') |
| |
|
| | message = message.replace( |
| | /File was processed with these loaders:\n(.+[\\/](next[\\/]dist[\\/].+|@next[\\/]react-refresh-utils[\\/]loader)\.js\n)*You may need an additional loader to handle the result of these loaders.\n/g, |
| | '' |
| | ) |
| |
|
| | lines = message.split('\n') |
| | } |
| |
|
| | |
| | lines = (lines as string[]).filter( |
| | (line, index, arr) => |
| | index === 0 || line.trim() !== '' || line.trim() !== arr[index - 1].trim() |
| | ) |
| |
|
| | |
| | message = lines.join('\n') |
| | return message.trim() |
| | } |
| |
|
| | export default function formatWebpackMessages(json: any, verbose?: boolean) { |
| | const formattedErrors = json.errors.map((message: any) => { |
| | const isUnknownNextFontError = message.message.includes( |
| | 'An error occurred in `next/font`.' |
| | ) |
| | return formatMessage(message, isUnknownNextFontError || verbose) |
| | }) |
| | const formattedWarnings = json.warnings.map((message: any) => { |
| | return formatMessage(message, verbose) |
| | }) |
| |
|
| | |
| | let reactServerComponentsError = -1 |
| |
|
| | for (let i = 0; i < formattedErrors.length; i++) { |
| | const error = formattedErrors[i] |
| | if (error.includes('ReactServerComponentsError')) { |
| | reactServerComponentsError = i |
| | break |
| | } |
| | } |
| |
|
| | |
| | if (reactServerComponentsError !== -1) { |
| | const error = formattedErrors.splice(reactServerComponentsError, 1) |
| | formattedErrors.unshift(error[0]) |
| | } |
| |
|
| | const result = { |
| | ...json, |
| | errors: formattedErrors, |
| | warnings: formattedWarnings, |
| | } |
| | if (!verbose && result.errors.some(isLikelyASyntaxError)) { |
| | |
| | result.errors = result.errors.filter(isLikelyASyntaxError) |
| | result.warnings = [] |
| | } |
| | return result |
| | } |
| |
|