UNPKG

figma-restoration-mcp-vue-tools

Version:

Professional Figma Component Restoration Kit - MCP tools with snapDOM-powered high-quality screenshots, intelligent shadow detection, and advanced diff analysis for Vue component restoration. Features enhanced figma_compare with color-coded region analysi

210 lines (187 loc) 5.69 kB
/** * Puppeteer Manager - 统一管理 Puppeteer 浏览器实例 * 使用 Puppeteer 内置 Chromium,简化配置和错误处理 */ import puppeteer from 'puppeteer'; import chalk from 'chalk'; import { PuppeteerLaunchError, NetworkError, PermissionError, TimeoutError, MemoryError } from './puppeteer-errors.js'; export class PuppeteerManager { constructor() { this.browser = null; this.pagePool = []; this.maxPoolSize = 5; // 限制页面池大小 this.isWarmedUp = false; } /** * 检查并警告废弃的环境变量 */ checkDeprecatedEnvVars() { if (process.env.PUPPETEER_EXECUTABLE_PATH) { console.warn(chalk.yellow('⚠️ PUPPETEER_EXECUTABLE_PATH is deprecated and will be ignored')); console.warn(chalk.yellow(' Puppeteer now uses bundled Chromium automatically')); } if (process.env.CHROME_EXECUTABLE_PATH) { console.warn(chalk.yellow('⚠️ CHROME_EXECUTABLE_PATH is deprecated and will be ignored')); console.warn(chalk.yellow(' Puppeteer now uses bundled Chromium automatically')); } } /** * 启动浏览器实例 - 使用 Puppeteer 内置 Chromium */ async launchBrowser(options = {}) { // 检查废弃的环境变量 this.checkDeprecatedEnvVars(); const defaultOptions = { headless: "new", args: [ '--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage', '--disable-accelerated-2d-canvas', '--no-first-run', '--no-zygote', '--disable-gpu' ], timeout: 30000 }; const launchOptions = { ...defaultOptions, ...options }; try { console.log(chalk.gray('🚀 Launching browser with bundled Chromium...')); this.browser = await puppeteer.launch(launchOptions); console.log(chalk.green('✅ Browser launched successfully')); return this.browser; } catch (error) { // 分类错误并提供具体解决方案 if (error.message.includes('ECONNREFUSED') || error.message.includes('network')) { throw new NetworkError('Failed to download or connect to Chromium', error); } else if (error.message.includes('Permission denied') || error.message.includes('EACCES')) { throw new PermissionError('Insufficient permissions to launch browser', error); } else if (error.message.includes('timeout') || error.message.includes('timed out')) { throw new TimeoutError('Browser launch timed out', error); } else if (error.message.includes('memory') || error.message.includes('ENOMEM')) { throw new MemoryError('Insufficient memory to launch browser', error); } else { throw new PuppeteerLaunchError(error); } } } /** * 获取页面实例 - 支持页面池复用 */ async getPage() { if (this.pagePool.length > 0) { return this.pagePool.pop(); } if (!this.browser) { this.browser = await this.launchBrowser(); } return await this.browser.newPage(); } /** * 释放页面实例回到池中 */ async releasePage(page) { // 如果页面池已满,直接关闭页面 if (this.pagePool.length >= this.maxPoolSize) { try { await page.close(); } catch (error) { // 忽略关闭错误 } return; } try { // 清理页面状态 await page.goto('about:blank'); await page.evaluate(() => { // 清理全局变量和事件监听器 if (typeof window !== 'undefined') { window.stop(); } }); this.pagePool.push(page); } catch (error) { // 如果清理失败,直接关闭页面 console.warn(chalk.yellow(`⚠️ Failed to clean page, closing: ${error.message}`)); try { await page.close(); } catch (closeError) { // 忽略关闭错误 } } } /** * 关闭浏览器实例 */ async closeBrowser() { if (this.browser) { try { // 清理页面池 for (const page of this.pagePool) { try { await page.close(); } catch (error) { // 忽略单个页面关闭错误 } } this.pagePool = []; await this.browser.close(); console.log(chalk.gray('🔒 Browser closed')); } catch (error) { console.warn(chalk.yellow(`⚠️ Warning: Failed to close browser: ${error.message}`)); } finally { this.browser = null; } } } /** * 预热浏览器实例 */ async warmup() { if (!this.browser) { console.log(chalk.gray('🔥 Pre-warming browser instance...')); this.browser = await this.launchBrowser(); } } /** * 检查 Puppeteer 是否可用 */ async checkAvailability() { try { // 简单检查 Puppeteer 模块是否加载 const puppeteerVersion = puppeteer.version || 'unknown'; return { available: true, puppeteerLoaded: true, puppeteerVersion, chromiumBundled: true, message: 'Puppeteer with bundled Chromium is ready' }; } catch (error) { return { available: false, puppeteerLoaded: false, chromiumBundled: false, error: error.message, message: 'Puppeteer is not available' }; } } /** * 获取单例实例 */ static getInstance() { if (!PuppeteerManager.instance) { PuppeteerManager.instance = new PuppeteerManager(); } return PuppeteerManager.instance; } } // 导出单例实例 export const puppeteerManager = PuppeteerManager.getInstance();