UNPKG

ngperf-audit

Version:

A comprehensive Angular performance analyzer that identifies performance bottlenecks, memory leaks, and optimization opportunities in Angular applications

249 lines (241 loc) • 9.99 kB
#!/usr/bin/env node "use strict"; /** * CLI Entry Point for Angular Performance Analyzer */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.commands = void 0; const path = __importStar(require("path")); const performance_analyzer_1 = require("./performance-analyzer"); // Helper function to resolve project path function resolveProjectPath(inputPath) { if (!inputPath) { return process.cwd(); } if (path.isAbsolute(inputPath)) { return inputPath; } return path.resolve(process.cwd(), inputPath); } // Helper function to create output directory if needed async function ensureOutputDirectory(outputPath) { const fs = await Promise.resolve().then(() => __importStar(require('fs/promises'))); const outputDir = path.dirname(outputPath); try { await fs.access(outputDir); } catch { await fs.mkdir(outputDir, { recursive: true }); console.log(`šŸ“ Created output directory: ${outputDir}`); } } // Helper function to parse command line arguments function parseArgs(args) { const parsed = { _: [] }; for (let i = 0; i < args.length; i++) { const arg = args[i]; if (arg.startsWith('--')) { // Long flag: --output const key = arg.slice(2); const nextArg = args[i + 1]; if (nextArg && !nextArg.startsWith('-')) { parsed[key] = nextArg; i++; // Skip next arg since we consumed it } else { parsed[key] = true; } } else if (arg.startsWith('-') && arg.length === 2) { // Short flag: -o const key = arg.slice(1); const nextArg = args[i + 1]; if (nextArg && !nextArg.startsWith('-')) { parsed[key] = nextArg; i++; // Skip next arg since we consumed it } else { parsed[key] = true; } } else { // Positional argument parsed._.push(arg); } } return parsed; } // Command handlers const commands = { // Analyze entire project async project(projectPath, outputPath, format) { const resolvedPath = resolveProjectPath(projectPath); console.log(`šŸ” Analyzing project: ${resolvedPath}`); if (outputPath) { await ensureOutputDirectory(outputPath); } if (format === 'json') { // Handle JSON format const { analyses, summary } = performance_analyzer_1.PerformanceAnalyzerCLI.analyzeProjectWithSummary(resolvedPath); const jsonReport = { summary, analyses, generatedAt: new Date().toISOString() }; const outputFile = outputPath || './performance-report.json'; await performance_analyzer_1.PerformanceAnalyzerCLI.saveReportToFile(JSON.stringify(jsonReport, null, 2), outputFile); console.log(`šŸ“„ JSON report saved to: ${outputFile}`); return { analyses, summary, reportPath: outputFile }; } else { // Default markdown format return performance_analyzer_1.PerformanceAnalyzerCLI.runAnalysis(resolvedPath, outputPath); } }, // Analyze single component async component(componentPath) { if (!componentPath) { throw new Error('Component path is required'); } const resolvedPath = path.resolve(componentPath); console.log(`šŸ” Analyzing component: ${resolvedPath}`); const analyzer = new performance_analyzer_1.PerformanceAnalyzer(); const analysis = analyzer.analyzeComponent(resolvedPath); console.log(`\nšŸ“Š Component Analysis Results:`); console.log(` Name: ${analysis.componentName}`); console.log(` Performance Score: ${analysis.performanceScore}/100`); const totalIssues = analysis.changeDetectionIssues.length + analysis.templateIssues.length + analysis.subscriptionIssues.length; console.log(` Issues Found: ${totalIssues}`); if (analysis.recommendations.length > 0) { console.log(`\nšŸ’” Top Recommendations:`); analysis.recommendations.slice(0, 3).forEach((rec, index) => { console.log(` ${index + 1}. ${rec.title} (${rec.priority} priority)`); }); } return analysis; }, // Generate detailed report async report(projectPath, outputPath) { const resolvedPath = resolveProjectPath(projectPath); const defaultOutput = outputPath || './performance-report.md'; console.log(`šŸ“‹ Generating detailed report for: ${resolvedPath}`); await ensureOutputDirectory(defaultOutput); const { analyses, summary } = performance_analyzer_1.PerformanceAnalyzerCLI.analyzeProjectWithSummary(resolvedPath); const report = performance_analyzer_1.PerformanceAnalyzerCLI.generateReportWithSummary(analyses, summary); await performance_analyzer_1.PerformanceAnalyzerCLI.saveReportToFile(report, defaultOutput); // Also log summary to console console.log(`\nšŸ“Š Analysis Summary:`); console.log(` Components: ${summary.totalComponents}`); console.log(` Average Score: ${summary.averagePerformanceScore}/100`); console.log(` Total Issues: ${summary.totalIssues}`); return { analyses, summary, reportPath: defaultOutput }; }, // Show help help() { console.log(` šŸš€ Angular Performance Analyzer CLI USAGE: ngperf-audit <command> [options] COMMANDS: project [path] Analyze entire project component <path> Analyze single component report [path] Generate detailed report help Show this help OPTIONS: -o, --output <file> Output file path -f, --format <type> Report format: 'markdown' or 'json' (default: markdown) EXAMPLES: ngperf-audit help # Show this help ngperf-audit project # Analyze current project ngperf-audit project ./src/app # Analyze src/app folder ngperf-audit project ./src/app -o ./reports/report.md # Save to custom file ngperf-audit project ./src/app -f json # Generate JSON report ngperf-audit project ./src/app -o ./report.json -f json # JSON report with custom path ngperf-audit component ./src/app/app.component.ts # Analyze single component ngperf-audit report # Generate detailed report ngperf-audit report ./src/app -o ./my-report.md # Custom output path DEVELOPMENT USAGE (in project root): npm run ngperf-audit project # If added to package.json scripts npx tsx src/ngperf/cli.ts project # Direct TypeScript execution For more information: https://github.com/eawebmaster20/ngperf `); } }; exports.commands = commands; // Main CLI handler async function main() { const args = process.argv.slice(2); const parsed = parseArgs(args); const command = parsed._[0]; if (!command || command === 'help' || !commands[command]) { commands.help(); return; } try { console.log('šŸš€ Angular Performance Analyzer'); console.log('================================\n'); const startTime = Date.now(); switch (command) { case 'project': const projectPath = parsed._[1]; const outputPath = parsed.output || parsed.o; const format = parsed.format || parsed.f || 'markdown'; await commands.project(projectPath, outputPath, format); break; case 'component': await commands.component(parsed._[1]); break; case 'report': const reportPath = parsed._[1]; const reportOutput = parsed.output || parsed.o; await commands.report(reportPath, reportOutput); break; } const duration = Date.now() - startTime; console.log(`\nāœ… Completed in ${duration}ms`); } catch (error) { console.error('āŒ Error:', error instanceof Error ? error.message : error); process.exit(1); } } // Run if called directly if (require.main === module) { main(); } //# sourceMappingURL=cli.js.map