probe-size-litter.mjs 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. // 票 15 盘点(只读):仅扫描 <style> 块与 .css 文件中的裸尺寸(字号 / 间距 / 关键几何)
  2. import { readFileSync, readdirSync, statSync } from 'node:fs'
  3. import { join, relative } from 'node:path'
  4. const root = 'src/modules/cockpit'
  5. const files = []
  6. ;(function walk(dir) {
  7. for (const e of readdirSync(dir)) {
  8. const p = join(dir, e)
  9. if (statSync(p).isDirectory()) walk(p)
  10. else if (/\.(vue|css)$/.test(e)) files.push(p)
  11. }
  12. })(root)
  13. function styleBlocks(src) {
  14. const out = []
  15. for (const m of src.matchAll(/<style[^>]*>([\s\S]*?)<\/style>/g)) out.push(m[1])
  16. if (/\.css$/.test('x.css') && !/<style/.test(src)) out.push(src)
  17. return out
  18. }
  19. const fontSizes = new Map()
  20. const decls = []
  21. for (const f of files) {
  22. const src = readFileSync(f, 'utf8')
  23. const rel = relative('.', f)
  24. for (const block of styleBlocks(src)) {
  25. for (const m of block.matchAll(/font-size:\s*([^;]+);/g)) {
  26. const v = m[1].trim()
  27. fontSizes.set(v, (fontSizes.get(v) || 0) + 1)
  28. }
  29. for (const m of block.matchAll(/(gap|padding|margin|width|height|min-height|min-width|max-height|max-width|letter-spacing):\s*([^;]+);/g)) {
  30. const v = m[2].trim()
  31. if (/var\(--/.test(v) || /^0$|^auto$|^100%$|^inherit$/.test(v)) continue
  32. if (!/\d+(px|u\b)/.test(v)) continue
  33. decls.push({ file: rel, prop: m[1], value: v })
  34. }
  35. }
  36. }
  37. console.log('=== font-size 声明(按出现次数)')
  38. console.log([...fontSizes.entries()].sort((a, b) => b[1] - a[1]).map(([k, v]) => `${k} ×${v}`).join('\n'))
  39. const byFile = new Map()
  40. for (const d of decls) {
  41. const cur = byFile.get(d.file) || []
  42. cur.push(`${d.prop}: ${d.value}`)
  43. byFile.set(d.file, cur)
  44. }
  45. console.log('\n=== 裸尺寸声明(非 var,按文件)')
  46. for (const [file, list] of [...byFile.entries()].sort((a, b) => b[1].length - a[1].length)) {
  47. console.log(`\n ${file} (${list.length})`)
  48. console.log(' ' + list.slice(0, 30).join('\n '))
  49. }
  50. console.log(`\n合计 ${decls.length} 条裸尺寸声明,跨 ${byFile.size} 个文件`)