|
import { buildExtendedLogMessage } from './log.js'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function toRollupError(error, options) { |
|
const { filename, frame, start, code, name, stack } = error; |
|
|
|
const rollupError = { |
|
name, |
|
id: filename, |
|
message: buildExtendedLogMessage(error), |
|
frame: formatFrameForVite(frame), |
|
code, |
|
stack: options.isBuild || options.isDebug || !frame ? stack : '' |
|
}; |
|
if (start) { |
|
rollupError.loc = { |
|
line: start.line, |
|
column: start.column, |
|
file: filename |
|
}; |
|
} |
|
return rollupError; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function toESBuildError(error, options) { |
|
const { filename, frame, start, stack } = error; |
|
|
|
const partialMessage = { |
|
text: buildExtendedLogMessage(error) |
|
}; |
|
if (start) { |
|
partialMessage.location = { |
|
line: start.line, |
|
column: start.column, |
|
file: filename, |
|
lineText: lineFromFrame(start.line, frame) |
|
}; |
|
} |
|
if (options.isBuild || options.isDebug || !frame) { |
|
partialMessage.detail = stack; |
|
} |
|
return partialMessage; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function lineFromFrame(lineNo, frame) { |
|
if (!frame) { |
|
return ''; |
|
} |
|
const lines = frame.split('\n'); |
|
const errorLine = lines.find((line) => line.trimStart().startsWith(`${lineNo}: `)); |
|
return errorLine ? errorLine.substring(errorLine.indexOf(': ') + 3) : ''; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function formatFrameForVite(frame) { |
|
if (!frame) { |
|
return ''; |
|
} |
|
return frame |
|
.split('\n') |
|
.map((line) => (line.match(/^\s+\^/) ? ' ' + line : ' ' + line.replace(':', ' | '))) |
|
.join('\n'); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
export function enhanceCompileError(err, originalCode, preprocessors) { |
|
preprocessors = arraify(preprocessors ?? []); |
|
|
|
|
|
const additionalMessages = []; |
|
|
|
|
|
if (err.code === 'parse-error') { |
|
|
|
const scriptRe = |
|
/<!--[^]*?-->|<script((?:\s+[^=>'"/]+=(?:"[^"]*"|'[^']*'|[^>\s]+)|\s+[^=>'"/]+)*\s*)(?:\/>|>([\S\s]*?)<\/script>)/g; |
|
const errIndex = err.pos ?? -1; |
|
|
|
let m; |
|
while ((m = scriptRe.exec(originalCode))) { |
|
const matchStart = m.index; |
|
const matchEnd = matchStart + m[0].length; |
|
const isErrorInScript = matchStart <= errIndex && errIndex <= matchEnd; |
|
if (isErrorInScript) { |
|
|
|
const hasLangTs = m[1]?.includes('lang="ts"'); |
|
if (!hasLangTs) { |
|
additionalMessages.push('Did you forget to add lang="ts" to your script tag?'); |
|
} |
|
|
|
if (preprocessors.every((p) => p.script == null)) { |
|
const preprocessorType = hasLangTs ? 'TypeScript' : 'script'; |
|
additionalMessages.push( |
|
`Did you forget to add a ${preprocessorType} preprocessor? See https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/preprocess.md for more information.` |
|
); |
|
} |
|
} |
|
} |
|
} |
|
|
|
|
|
if (err.code === 'css-syntax-error') { |
|
|
|
const styleRe = |
|
/<!--[^]*?-->|<style((?:\s+[^=>'"/]+=(?:"[^"]*"|'[^']*'|[^>\s]+)|\s+[^=>'"/]+)*\s*)(?:\/>|>([\S\s]*?)<\/style>)/g; |
|
|
|
let m; |
|
while ((m = styleRe.exec(originalCode))) { |
|
|
|
if (!m[1]?.includes('lang=')) { |
|
additionalMessages.push('Did you forget to add a lang attribute to your style tag?'); |
|
} |
|
|
|
if ( |
|
preprocessors.every((p) => p.style == null || p.name === 'inject-scope-everything-rule') |
|
) { |
|
const preprocessorType = m[1]?.match(/lang="(.+?)"/)?.[1] ?? 'style'; |
|
additionalMessages.push( |
|
`Did you forget to add a ${preprocessorType} preprocessor? See https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/preprocess.md for more information.` |
|
); |
|
} |
|
} |
|
} |
|
|
|
if (additionalMessages.length) { |
|
err.message += '\n\n- ' + additionalMessages.join('\n- '); |
|
} |
|
|
|
return err; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
function arraify(value) { |
|
return Array.isArray(value) ? value : [value]; |
|
} |
|
|