_peek_component.mjs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. import { readFileSync } from 'node:fs'
  2. import { fileURLToPath, pathToFileURL } from 'node:url'
  3. import { dirname, resolve } from 'node:path'
  4. import { JSDOM, VirtualConsole } from 'jsdom'
  5. const HERE = dirname(fileURLToPath(import.meta.url))
  6. const GATEWAY = process.argv[2]
  7. const CLASSIC = resolve(HERE, '../../../release/web/detail_v2.html')
  8. const state = { apis: {}, cache: new Map() }
  9. function installFetch(window, state) {
  10. window.fetch = async (input) => {
  11. const raw = typeof input === 'string' ? input : (input && input.url) || String(input)
  12. const url = raw.startsWith('http') ? raw : GATEWAY + (raw.startsWith('/') ? raw : '/' + raw)
  13. if (state.cache.has(url)) { const c = state.cache.get(url); return { ok: true, status: 200, headers: new Map(), text: async () => c, json: async () => JSON.parse(c) } }
  14. const r = await fetch(url); const b = await r.text(); if (r.ok) state.cache.set(url, b)
  15. return { ok: r.ok, status: r.status, headers: r.headers, text: async () => b, json: async () => JSON.parse(b) }
  16. }
  17. }
  18. const dom = new JSDOM(readFileSync(CLASSIC, 'utf8'), { url: GATEWAY + '/detail/v2#tab=component', runScripts: 'dangerously', pretendToBeVisual: true, virtualConsole: new VirtualConsole(), beforeParse: (w) => installFetch(w, state) })
  19. const doc = dom.window.document
  20. for (let i = 0; i < 120; i++) { const r = doc.getElementById('root'); if (r && r.querySelector('.page-head')) break; await new Promise((x) => setTimeout(x, 500)) }
  21. let last = -1, same = 0
  22. for (let i = 0; i < 40; i++) { const r = doc.getElementById('root'); const n = r ? r.querySelectorAll('*').length : 0; if (n === last) { if (++same >= 3) break } else same = 0; last = n; await new Promise((x) => setTimeout(x, 700)) }
  23. const root = doc.getElementById('root')
  24. // 基线:找第 240 个元素的父级上下文
  25. const all = Array.from(root.querySelectorAll('*'))
  26. console.log('BASELINE_TOTAL', all.length)
  27. for (let i = 236; i < 246 && i < all.length; i++) {
  28. const el = all[i]
  29. console.log('B#' + i, el.tagName.toLowerCase() + (el.className ? '.' + String(el.className).trim().split(/\s+/).join('.') : ''), '|parent=' + (el.parentElement ? el.parentElement.tagName.toLowerCase() + '.' + String(el.parentElement.className || '').trim().split(/\s+/).join('.') : '-'))
  30. }
  31. const entry = pathToFileURL(resolve(HERE, '../target/ssr/entry-server.js')).href
  32. const html = await (await import(entry)).renderTab(state.cache.get(GATEWAY + '/api/fleet') ? JSON.parse(state.cache.get(GATEWAY + '/api/fleet')) : null, 'component', null, null, null, {})
  33. const vd = new JSDOM('<div id="wrap">' + html + '</div>')
  34. const wrap = vd.window.document.getElementById('wrap')
  35. const nav = wrap.querySelector('.wb-tabs'); if (nav) nav.remove()
  36. const vAll = Array.from(wrap.querySelectorAll('*'))
  37. console.log('VUE_TOTAL', vAll.length)
  38. for (let i = 236; i < 246 && i < vAll.length; i++) {
  39. const el = vAll[i]
  40. console.log('V#' + i, el.tagName.toLowerCase() + (el.className ? '.' + String(el.className).trim().split(/\s+/).join('.') : ''), '|parent=' + (el.parentElement ? el.parentElement.tagName.toLowerCase() + '.' + String(el.parentElement.className || '').trim().split(/\s+/).join('.') : '-'))
  41. }