#!/usr/bin/env node /** * Console.log 교체 스크립트 * 프로젝트 전체의 console.log를 환경별 로거로 교체 */ const fs = require("fs"); const path = require("path"); const { glob } = require("glob"); // 교체할 패턴들 const replacements = [ { pattern: /console\.log\(/g, replacement: "syncLogger.info(", description: "console.log → syncLogger.info", }, { pattern: /console\.error\(/g, replacement: "syncLogger.error(", description: "console.error → syncLogger.error", }, { pattern: /console\.warn\(/g, replacement: "syncLogger.warn(", description: "console.warn → syncLogger.warn", }, { pattern: /console\.info\(/g, replacement: "syncLogger.info(", description: "console.info → syncLogger.info", }, ]; // 파일별 특화된 로거 매핑 const fileLoggerMap = { auth: "authLogger", sync: "syncLogger", network: "networkLogger", storage: "storageLogger", appwrite: "appwriteLogger", }; // 파일 경로에 따른 적절한 로거 결정 function getLoggerForFile(filePath) { const lowerPath = filePath.toLowerCase(); for (const [keyword, logger] of Object.entries(fileLoggerMap)) { if (lowerPath.includes(keyword)) { return logger; } } // 기본값은 일반 logger return "logger"; } // 파일 처리 함수 async function processFile(filePath) { try { const content = fs.readFileSync(filePath, "utf8"); const originalContent = content; // 이미 logger import가 있는지 확인 const hasLoggerImport = content.includes("from '@/utils/logger'"); const appropriateLogger = getLoggerForFile(filePath); let newContent = content; let hasChanges = false; // console 사용이 있는지 확인 const hasConsoleUsage = /console\.(log|error|warn|info)\(/.test(content); if (hasConsoleUsage) { // console.log 등을 적절한 로거로 교체 replacements.forEach(({ pattern, description }) => { const loggerMethod = pattern.source.includes("error") ? "error" : pattern.source.includes("warn") ? "warn" : "info"; const replacement = `${appropriateLogger}.${loggerMethod}(`; if (pattern.test(newContent)) { newContent = newContent.replace(pattern, replacement); hasChanges = true; console.log( ` - ${description} (using ${appropriateLogger}.${loggerMethod})` ); } }); // logger import 추가 (필요한 경우) if (hasChanges && !hasLoggerImport) { // import 구문 찾기 const importMatch = newContent.match( /^(import[\s\S]*?from ['"][^'"]+['"];?\s*\n)/m ); if (importMatch) { const lastImportEnd = importMatch.index + importMatch[1].length; const beforeImports = newContent.slice(0, lastImportEnd); const afterImports = newContent.slice(lastImportEnd); let importStatement; if (appropriateLogger === "logger") { importStatement = "import { logger } from '@/utils/logger';\n"; } else { importStatement = `import { ${appropriateLogger} } from '@/utils/logger';\n`; } newContent = beforeImports + importStatement + afterImports; console.log(` - Added import: ${importStatement.trim()}`); } } } // 변경사항이 있으면 파일 저장 if (hasChanges && newContent !== originalContent) { fs.writeFileSync(filePath, newContent, "utf8"); return true; } return false; } catch (error) { console.error(`Error processing ${filePath}:`, error.message); return false; } } // 메인 실행 함수 async function main() { console.log("🔄 Console.log → Logger 교체 작업 시작\n"); // src 폴더 내의 TypeScript/JavaScript 파일들 찾기 const files = await glob("src/**/*.{ts,tsx,js,jsx}", { ignore: [ "src/utils/logger.ts", // 로거 파일 자체는 제외 "src/**/*.test.{ts,tsx,js,jsx}", // 테스트 파일 제외 "src/**/*.spec.{ts,tsx,js,jsx}", // 스펙 파일 제외 ], cwd: process.cwd(), }); console.log(`📁 총 ${files.length}개 파일 검사 중...\n`); let processedCount = 0; let changedCount = 0; for (const file of files) { const filePath = path.resolve(file); console.log(`🔍 처리 중: ${file}`); const hasChanges = await processFile(filePath); processedCount++; if (hasChanges) { changedCount++; console.log(` ✅ 변경 완료`); } else { console.log(` ⏭️ 변경 없음`); } console.log(""); } console.log("🎉 Console.log → Logger 교체 작업 완료"); console.log(`📊 결과: ${changedCount}/${processedCount} 파일 변경됨\n`); if (changedCount > 0) { console.log("🔧 다음 단계:"); console.log("1. npm run build로 빌드 에러 확인"); console.log("2. 변경된 파일들 검토"); console.log("3. 개발 서버에서 로그 출력 테스트"); } } // 스크립트 실행 if (require.main === module) { main().catch(console.error); }