100 lines
4.0 KiB
TypeScript
100 lines
4.0 KiB
TypeScript
import { PluginOption } from 'vite';
|
|
import colors from 'picocolors';
|
|
|
|
// 用于跟踪当前正在处理的文件
|
|
let currentProcessingFile: string | null = null;
|
|
|
|
/**
|
|
* 增强构建错误报告的 Vite 插件
|
|
* 用于捕获和显示详细的 Vue 编译错误信息
|
|
*/
|
|
export function configErrorReporterPlugin(): PluginOption {
|
|
return {
|
|
name: 'vite-plugin-error-reporter',
|
|
enforce: 'pre',
|
|
|
|
// 捕获转换开始
|
|
transform(code, id) {
|
|
if (id.endsWith('.vue')) {
|
|
currentProcessingFile = id;
|
|
}
|
|
return null;
|
|
},
|
|
|
|
// 捕获构建错误
|
|
buildEnd(error) {
|
|
if (error) {
|
|
console.error('\n');
|
|
console.error(colors.red('╔══════════════════════════════════════════════════════════════════╗'));
|
|
console.error(colors.red('║ 构建错误详细信息 ║'));
|
|
console.error(colors.red('╚══════════════════════════════════════════════════════════════════╝'));
|
|
console.error('\n');
|
|
|
|
// 显示当前正在处理的文件
|
|
if (currentProcessingFile) {
|
|
console.error(colors.red('当前正在处理的文件:'));
|
|
console.error(colors.cyan(currentProcessingFile));
|
|
console.error('\n');
|
|
}
|
|
|
|
// 显示错误堆栈
|
|
if (error.stack) {
|
|
console.error(colors.yellow('错误堆栈:'));
|
|
console.error(error.stack);
|
|
console.error('\n');
|
|
}
|
|
|
|
// 尝试提取文件路径
|
|
const errorMessage = (error as any).message || '';
|
|
const fileMatch = errorMessage.match(/in\s+([\w\-/.\\]+\.vue)/i) ||
|
|
errorMessage.match(/at\s+([\w\-/.\\]+\.vue)/i) ||
|
|
errorMessage.match(/([\w\-/.\\]+\.vue)/i);
|
|
|
|
if (fileMatch) {
|
|
console.error(colors.yellow('可能出错的文件:'));
|
|
console.error(colors.cyan(fileMatch[1]));
|
|
console.error('\n');
|
|
}
|
|
|
|
// 显示原始错误信息
|
|
console.error(colors.yellow('错误信息:'));
|
|
console.error(errorMessage);
|
|
console.error('\n');
|
|
|
|
// 提示常见解决方案
|
|
console.error(colors.yellow('常见解决方案:'));
|
|
console.error('1. 检查 Vue 模板中 <template #slotName v-if="..."> 的用法');
|
|
console.error(' 应改为: <template v-if="..." #slotName>');
|
|
console.error('2. 检查 <template> 标签上是否使用了 v-show (应该改用 v-if)');
|
|
console.error('3. 检查模板中是否有未闭合的标签');
|
|
console.error('4. 检查 <template #[dynamicSlotName] v-if="..."> 的用法');
|
|
console.error(' 应改为: <template v-if="..." #[dynamicSlotName]>');
|
|
console.error('\n');
|
|
|
|
// 搜索建议
|
|
console.error(colors.yellow('建议搜索以下模式来定位问题:'));
|
|
console.error(colors.cyan(' grep -r "<template.*#.*v-if" src --include="*.vue"'));
|
|
console.error(colors.cyan(' grep -r "<template.*#.*v-show" src --include="*.vue"'));
|
|
console.error(colors.cyan(' grep -r "<template.*#\[.*v-if" src --include="*.vue"'));
|
|
console.error('\n');
|
|
|
|
throw error;
|
|
}
|
|
},
|
|
|
|
// 配置服务器错误处理
|
|
configureServer(server) {
|
|
server.middlewares.use((req, res, next) => {
|
|
const originalEnd = res.end.bind(res);
|
|
res.end = function(chunk: any, encoding?: any, cb?: any) {
|
|
if (res.statusCode >= 400) {
|
|
console.error(colors.yellow(`\n请求错误: ${req.url} - 状态码: ${res.statusCode}\n`));
|
|
}
|
|
return originalEnd(chunk, encoding, cb);
|
|
};
|
|
next();
|
|
});
|
|
},
|
|
};
|
|
}
|