UNPKG

@regele/devtools

Version:

A collection of developer utilities for code processing and text analysis

150 lines (125 loc) 5.56 kB
#!/usr/bin/env node try { // Direct implementation of comment removal const fs = require('fs'); const path = require('path'); const { Command } = require('commander'); const chalk = require('chalk'); const ora = require('ora'); const fg = require('fast-glob'); // Ensure ora is properly imported const createSpinner = ora.default || ora; // Function to remove comments from JavaScript code function removeJavaScriptComments(code) { let result = code; try { // First, preserve strings and regexes to avoid modifying comments inside them const preservedItems = []; let preservedCount = 0; // Temporarily replace strings and regexes with placeholders result = result.replace( /(["'`])(?:\\[\s\S]|(?!\1)[^\\])*\1|\/(?![*+?])(?:[^\r\n\[/\\]|\\.|\[(?:[^\r\n\]\\]|\\.)*\])+\/(?:[gimuy]+\b)?/g, (match) => { const placeholder = `__PRESERVED_ITEM_${preservedCount}__`; preservedItems[preservedCount] = match; preservedCount++; return placeholder; } ); // Remove JSX comments result = result.replace(/\{\/\*[\s\S]*?\*\/\}/g, ''); // Remove multi-line comments result = result.replace(/\/\*[\s\S]*?\*\//g, ''); // Remove single-line comments // Handle comments at start of line result = result.replace(/^[ \t]*\/\/.*$/gm, ''); // Handle comments after code (but not in URLs) result = result.replace(/([^:/])\/\/.*$/gm, '$1'); // Restore preserved strings and regexes for (let i = 0; i < preservedCount; i++) { const placeholder = `__PRESERVED_ITEM_${i}__`; const regex = new RegExp(placeholder, 'g'); result = result.replace(regex, () => preservedItems[i]); } // Remove empty lines // Remove lines that contain only whitespace result = result.replace(/^\s*[\r\n]/gm, ''); // Remove consecutive empty lines (preserving indentation) result = result.replace(/\n(\s*)\n(\s*)\n/g, '\n$2\n'); // Remove empty lines at the beginning and end of the file result = result.replace(/^(\s*\n)+/, ''); result = result.replace(/(\n\s*)+$/, ''); return result.trim(); } catch (error) { console.error(`JavaScript comment removal failed: ${error.message}`); return code; } } // Test function async function testGlob(pattern) { try { console.log(`Testing pattern: ${pattern}`); // Normalize pattern for Windows paths const normalizedPattern = pattern.replace(/\\/g, '/'); // Find files const files = await fg(normalizedPattern, { onlyFiles: true, absolute: true }); console.log(`Found ${files.length} files`); // Print first 10 files if (files.length > 0) { console.log('First 10 files:'); files.slice(0, 10).forEach(file => { console.log(`- ${file}`); }); // Process the first file as a test if (files.length > 0) { const testFile = files[0]; console.log(`\nProcessing test file: ${testFile}`); // Read the file const content = fs.readFileSync(testFile, 'utf8'); console.log(`Original size: ${content.length} bytes`); // Process based on extension const ext = path.extname(testFile).toLowerCase(); let newContent; if (['.js', '.jsx', '.ts', '.tsx', '.json'].includes(ext)) { newContent = removeJavaScriptComments(content); } else if (['.html', '.htm', '.xml'].includes(ext)) { // For HTML files, remove HTML comments newContent = content.replace(/<!--[\s\S]*?-->/g, ''); // Also process script and style tags for JS and CSS comments newContent = newContent.replace(/(<script\b[^>]*>)([\s\S]*?)(<\/script>)/gi, (match, openTag, content, closeTag) => { return openTag + removeJavaScriptComments(content) + closeTag; }); newContent = newContent.replace(/(<style\b[^>]*>)([\s\S]*?)(<\/style>)/gi, (match, openTag, content, closeTag) => { return openTag + removeJavaScriptComments(content) + closeTag; }); } else if (['.css', '.scss', '.less'].includes(ext)) { // For CSS files, remove CSS comments newContent = content.replace(/\/\*[\s\S]*?\*\//g, ''); // Remove empty lines newContent = newContent.replace(/^\s*[\r\n]/gm, ''); newContent = newContent.replace(/\n\s*\n/g, '\n'); } else { newContent = removeJavaScriptComments(content); } console.log(`New size: ${newContent.length} bytes`); console.log(`Removed: ${content.length - newContent.length} bytes (${((content.length - newContent.length) / content.length * 100).toFixed(2)}%)`); // Write to a test file const testOutputFile = testFile + '.cleaned'; fs.writeFileSync(testOutputFile, newContent, 'utf8'); console.log(`Cleaned file written to: ${testOutputFile}`); } } } catch (error) { console.error('Error:', error.message); } } // Get pattern from command line const pattern = process.argv[2] || 'C:/Users/darw1/Downloads/testing/**/*.{js,ts,jsx,tsx,css,html,json}'; testGlob(pattern); } catch (error) { console.error('Error:', error.message); process.exit(1); }