#!/usr/bin/env node 'use strict'; /** * Vue SFC 结构与脚本语法校验。 * * audit-project.js 只做交叉引用检查,不解析 `; const goodBlocks = splitSFC(good); check('正常 SFC 能拆出 template', goodBlocks.template.length, 1); check('正常 SFC 能拆出 script', goodBlocks.script.length, 1); check('正常脚本语法通过', checkScriptSyntax(goodBlocks.script[0].body, 'good'), null); // 语法错误的脚本必须被抓到 const bad = ` `; const badBlocks = splitSFC(bad); check('错误脚本语法被识别', checkScriptSyntax(badBlocks.script[0].body, 'bad') !== null, true); // 空 script 应被识别 const empty = ``; check('空 script 被识别', splitSFC(empty).script[0].body.trim().length, 0); // 自闭合 template 不应被当成块 const selfClosed = ``; check('自闭合 template 不计入块', splitSFC(selfClosed).template.filter((b) => b.body.includes(' methodsIndent; } function main() { const files = walk(ROOT); if (SELFTEST) { const cases = selfTest(); console.log(''); console.log('Vue 校验器自测:'); for (const c of cases) { console.log(` ${c.ok ? '✓' : '✗'} ${c.label}${c.ok ? '' : `(期望 ${c.expected},实得 ${c.actual})`}`); } const failed = cases.filter((c) => !c.ok).length; console.log(''); console.log(failed ? `✗ ${failed} 项失败` : '✓ 校验器工作正常'); return failed ? 1 : 0; } for (const f of files) checkFile(f); if (JSON_OUT) { console.log(JSON.stringify({ ok: errors.length === 0, errors, warnings, scanned: files.length }, null, 2)); return errors.length ? 1 : 0; } console.log(''); console.log('═══════════════════════════════════════════════'); console.log(' Vue SFC 校验报告'); console.log('═══════════════════════════════════════════════'); console.log(` 扫描 ${files.length} 个 .vue 文件\n`); const fmt = (list) => list.map((x) => ` ${x.file}:${x.line}\n ▸ ${x.msg}`).join('\n'); if (errors.length) { console.log(`✗ 错误 ${errors.length} 项`); console.log(fmt(errors)); console.log(''); } if (warnings.length) { console.log(`⚠ 警告 ${warnings.length} 项`); console.log(fmt(warnings)); console.log(''); } if (!errors.length && !warnings.length) console.log('✓ 全部通过\n'); console.log(`结论: ${errors.length} 错误 / ${warnings.length} 警告`); console.log('═══════════════════════════════════════════════'); return errors.length ? 1 : 0; } process.exit(main());