scan-vue-template-critical.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. const fs = require('fs')
  2. const path = require('path')
  3. const roots = [
  4. path.join(__dirname, '../src/views'),
  5. path.join(__dirname, '../../saas-mgnui/src/views'),
  6. path.join(__dirname, '../../adminui/src/views')
  7. ]
  8. function walk(dir, files = []) {
  9. if (!fs.existsSync(dir)) return files
  10. for (const name of fs.readdirSync(dir)) {
  11. const full = path.join(dir, name)
  12. if (fs.statSync(full).isDirectory()) walk(full, files)
  13. else if (name.endsWith('.vue')) files.push(full)
  14. }
  15. return files
  16. }
  17. function scan(content) {
  18. const issues = []
  19. const m = content.match(/<template>([\s\S]*?)<\/template>/)
  20. if (!m) return issues
  21. const tpl = m[1]
  22. const qIdx = tpl.indexOf('ref="queryForm"')
  23. if (qIdx >= 0) {
  24. const formStart = tpl.lastIndexOf('<el-form', qIdx)
  25. const formEnd = tpl.indexOf('</el-form>', qIdx)
  26. if (formStart >= 0 && formEnd >= 0) {
  27. let formBody = tpl.slice(formStart, formEnd + '</el-form>'.length)
  28. formBody = formBody.replace(/<!--[\s\S]*?-->/g, '')
  29. const openFi = (formBody.match(/<el-form-item\b/g) || []).length
  30. const closeFi = (formBody.match(/<\/el-form-item>/g) || []).length
  31. if (openFi !== closeFi) issues.push(`form-item-balance:${openFi}/${closeFi}`)
  32. }
  33. }
  34. // list-search-actions opened but closed by </el-form> first
  35. const brokenActions = tpl.match(
  36. /<el-form-item[^>]*list-search-actions[^>]*>[\s\S]*?(?=<\/el-form>)/g
  37. )
  38. if (brokenActions) {
  39. for (const block of brokenActions) {
  40. if (!block.includes('</el-form-item>')) {
  41. if (/<el-form-item\b/.test(block)) issues.push('unclosed-actions-with-nested')
  42. else issues.push('unclosed-actions')
  43. } else if (/<el-form-item[^>]*list-search-actions[^>]*>[\s\S]*<el-form-item\b/.test(block)) {
  44. issues.push('nested-in-actions')
  45. }
  46. }
  47. }
  48. return issues
  49. }
  50. const all = []
  51. for (const root of roots) {
  52. for (const file of walk(root)) {
  53. const issues = scan(fs.readFileSync(file, 'utf8'))
  54. if (issues.length) all.push({ file, issues })
  55. }
  56. }
  57. console.log('Critical files:', all.length)
  58. for (const r of all) {
  59. console.log(r.file.replace(/\\/g, '/'))
  60. console.log(' ', r.issues.join(', '))
  61. }