// 找出模板里残留的 `this.xxx`。
|
//
|
// Vue3 模板作用域不再挂 `this`,`{{ this.a }}` 会渲染成 undefined,
|
// `v-if="this.a"` 恒为 false,`@click="this.fn()"` 直接报错。
|
// 编译器不会报错,所以必须静态扫一遍。
|
//
|
// 用法:node scripts/migrate/find-this-in-template.mjs <dir...>
|
import { readFileSync, readdirSync, statSync } from 'node:fs'
|
import { join, extname } from 'node:path'
|
import { parse } from '@vue/compiler-sfc'
|
|
function collect(dir, out = []) {
|
for (const e of readdirSync(dir)) {
|
const p = join(dir, e)
|
if (statSync(p).isDirectory()) collect(p, out)
|
else if (extname(p) === '.vue') out.push(p)
|
}
|
return out
|
}
|
|
const targets = process.argv.slice(2)
|
const files = targets.flatMap(t => (statSync(t).isDirectory() ? collect(t) : [t]))
|
let hits = 0
|
const filesHit = new Set()
|
|
for (const f of files) {
|
let descriptor
|
try {
|
descriptor = parse(readFileSync(f, 'utf8'), { filename: f }).descriptor
|
} catch {
|
continue
|
}
|
if (!descriptor.template) continue
|
const src = descriptor.template.content
|
const base = descriptor.template.loc.start.line - 1
|
const re = /\bthis\s*\./g
|
let m
|
while ((m = re.exec(src))) {
|
hits++
|
filesHit.add(f)
|
const line = base + src.slice(0, m.index).split('\n').length
|
console.log(` ${f} L${line} ${src.slice(m.index, m.index + 60).replace(/\s+/g, ' ')}`)
|
}
|
}
|
|
console.log(`\n=== 模板内残留 this. :${hits} 处 / ${filesHit.size} 文件`)
|