// DOM 环境冒烟:mock 浏览器 API,跑通入口 main.js 的初始化 + 若干帧 const noop = () => { }; const els = new Map(); function mkEl(id = '') { const el = { id, tagName: 'DIV', value: '', textContent: '', innerHTML: '', style: {}, dataset: {}, children: [], width: 800, height: 608, classList: { add: noop, remove: noop, toggle: noop, contains: () => false }, addEventListener: noop, removeEventListener: noop, appendChild: noop, querySelector: () => mkEl(), querySelectorAll: () => [], getBoundingClientRect: () => ({ left: 0, top: 0, width: 800, height: 608 }), getContext: () => ctx2d, focus: noop, click: noop, }; return el; } const ctx2d = new Proxy({ canvas: { width: 800, height: 608 }, measureText: () => ({ width: 12 }), createLinearGradient: () => ({ addColorStop: noop }), createRadialGradient: () => ({ addColorStop: noop }), getImageData: () => ({ data: [] }), }, { get(t, k) { return k in t ? t[k] : noop; }, set(t, k, v) { t[k] = v; return true; }, }); const handlers = {}; const addL = (t, fn) => { (handlers[t] = handlers[t] || []).push(fn); }; globalThis.window = { addEventListener: addL, removeEventListener: noop, AudioContext: null, webkitAudioContext: null, innerWidth: 1280, innerHeight: 800, }; globalThis.addEventListener = addL; globalThis.removeEventListener = noop; globalThis.confirm = () => true; globalThis.alert = noop; globalThis.localStorage = { _d: {}, getItem(k) { return this._d[k] ?? null; }, setItem(k, v) { this._d[k] = String(v); }, removeItem(k) { delete this._d[k]; }, }; globalThis.document = { getElementById(id) { if (!els.has(id)) els.set(id, mkEl(id)); return els.get(id); }, querySelector(s) { return mkEl(s); }, querySelectorAll() { return []; }, createElement(t) { const e = mkEl(); e.tagName = t.toUpperCase(); return e; }, addEventListener: addL, body: mkEl('body'), }; let frames = 0; globalThis.requestAnimationFrame = (fn) => { if (frames++ > 12) return 0; setTimeout(() => fn(performance.now() + frames * 16.7), 0); return frames; }; try { await import('../js/main.js'); console.log('✅ main.js 初始化成功'); } catch (e) { console.log('❌ main.js 初始化失败: ' + e.message); console.log(e.stack.split('\n').slice(0, 5).join('\n')); process.exit(1); } // 等几帧 await new Promise(r => setTimeout(r, 200)); const { LEVELS } = await import('../js/levels/index.js'); const api = globalThis.window.__IW; console.log('✅ 已跑 ' + frames + ' 帧,状态=' + (api ? api.G.state : '?')); if (api) { // 逐个关卡启动一次,确认不炸 let bad = 0; for (const lv of LEVELS) { try { api.startLevel(lv, lv.index ?? -1); for (let i = 0; i < 90; i++) { /* 由 rAF 驱动,这里只验证构造 */ } if (!api.G.level || !api.G.player) throw new Error('未创建关卡'); } catch (e) { console.log(' ✗ ' + lv.id + ': ' + e.message); bad++; } } console.log(bad ? `❌ ${bad} 个关卡启动失败` : `✅ 全部 ${LEVELS.length} 关均可启动`); } process.exit(0);