gaoluyang
5 天以前 c7566bba45e6f90594d36ec4b80ac4ff89f577ee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// 用 @vue/compiler-sfc(与 @vitejs/plugin-vue 同一套编译器)校验 SFC 能否正常编译。
// 用途:校验尚未被任何页面引用的公共组件;已被引用的文件交给 npm run build:prod 兜底。
// 用法:node scripts/check-sfc.mjs <file...>
import { readFileSync } from 'node:fs'
import { parse, compileScript, compileTemplate } from '@vue/compiler-sfc'
 
const files = process.argv.slice(2)
if (!files.length) {
  console.error('用法:node scripts/check-sfc.mjs <file...>')
  process.exit(2)
}
 
let failed = 0
for (const file of files) {
  const filename = file.replace(/\\/g, '/')
  const errors = []
  try {
    const { descriptor, errors: parseErrors } = parse(readFileSync(file, 'utf8'), { filename })
    errors.push(...parseErrors)
    if (!errors.length) {
      // 纯模板组件(如官方 ParentView)没有 script 块,compileScript 会直接报错,跳过
      const hasScript = !!(descriptor.script || descriptor.scriptSetup)
      const script = hasScript ? compileScript(descriptor, { id: filename }) : { bindings: {} }
      if (descriptor.template) {
        const { errors: templateErrors } = compileTemplate({
          source: descriptor.template.content,
          filename,
          id: filename,
          scoped: descriptor.styles.some(s => s.scoped),
          compilerOptions: { bindingMetadata: script.bindings }
        })
        errors.push(...templateErrors)
      }
    }
  } catch (e) {
    errors.push(e)
  }
 
  if (errors.length) {
    failed++
    console.error(`✗ ${file}`)
    errors.forEach(e => console.error('   ', e.message || e))
  } else {
    console.log(`✓ ${file}`)
  }
}
 
process.exit(failed ? 1 : 0)