ERP-node/frontend/lib/registry/utils/hotReload.ts

197 lines
5.0 KiB
TypeScript

"use client";
import { ComponentRegistry } from "../ComponentRegistry";
/**
* Hot Reload 시스템
* 개발 모드에서 컴포넌트 파일 변경 시 자동으로 레지스트리 업데이트
*/
let isHotReloadEnabled = false;
let hotReloadListeners: Array<() => void> = [];
/**
* Hot Reload 시스템 초기화
*/
export function initializeHotReload(): void {
// 핫 리로드 시스템 임시 비활성화 (디버깅 목적)
return;
if (process.env.NODE_ENV !== "development" || typeof window === "undefined") {
return;
}
if (isHotReloadEnabled) {
return;
}
console.log("🔥 컴포넌트 Hot Reload 시스템 시작...");
// HMR (Hot Module Replacement) 지원
if ((module as any).hot) {
(module as any).hot.accept(() => {
console.log("🔄 컴포넌트 Hot Reload 감지");
reloadComponents();
});
(module as any).hot.dispose(() => {
console.log("🧹 컴포넌트 Hot Reload 정리");
cleanup();
});
}
// 파일 변경 감지 (개발 서버 이벤트)
if (typeof EventSource !== "undefined") {
setupDevServerEventListener();
}
isHotReloadEnabled = true;
console.log("✅ 컴포넌트 Hot Reload 시스템 준비 완료");
}
/**
* 개발 서버 이벤트 리스너 설정
*/
function setupDevServerEventListener(): void {
try {
// Next.js 개발 서버의 WebSocket 연결 활용
const originalLog = console.log;
let reloadPending = false;
// console.log 메시지를 감지하여 Hot Reload 트리거 (특정 메시지만)
console.log = (...args: any[]) => {
const message = args.join(" ");
// 핫 리로드를 트리거할 특정 메시지만 감지 (디버깅 로그는 제외)
if (
(message.includes("compiled") || message.includes("Fast Refresh")) &&
!message.includes("🔍") &&
!message.includes("🎯") &&
!message.includes("📤") &&
!message.includes("📥") &&
!message.includes("⚠️") &&
!message.includes("🔄") &&
!message.includes("✅") &&
!message.includes("🔧") &&
!message.includes("📋")
) {
if (!reloadPending) {
reloadPending = true;
setTimeout(() => {
reloadComponents();
reloadPending = false;
}, 100);
}
}
originalLog.apply(console, args);
};
console.log("🔍 개발 서버 이벤트 리스너 등록 완료");
} catch (error) {
console.warn("⚠️ 개발 서버 이벤트 리스너 등록 실패:", error);
}
}
/**
* 컴포넌트 재로드
*/
function reloadComponents(): void {
try {
console.log("🔄 컴포넌트 레지스트리 재로드 중...");
// 기존 컴포넌트 개수 저장
const beforeCount = ComponentRegistry.getComponentCount();
// Hot Reload 이벤트 발생
notifyHotReloadListeners();
// 재로드 후 컴포넌트 개수 확인
const afterCount = ComponentRegistry.getComponentCount();
console.log(`✅ 컴포넌트 재로드 완료: ${beforeCount}개 → ${afterCount}`);
// UI 업데이트 알림
if (typeof window !== "undefined") {
window.dispatchEvent(
new CustomEvent("componentRegistryUpdated", {
detail: {
before: beforeCount,
after: afterCount,
timestamp: new Date(),
},
}),
);
}
} catch (error) {
console.error("❌ 컴포넌트 재로드 실패:", error);
}
}
/**
* Hot Reload 리스너 등록
*/
export function addHotReloadListener(listener: () => void): void {
hotReloadListeners.push(listener);
}
/**
* Hot Reload 리스너 제거
*/
export function removeHotReloadListener(listener: () => void): void {
const index = hotReloadListeners.indexOf(listener);
if (index !== -1) {
hotReloadListeners.splice(index, 1);
}
}
/**
* Hot Reload 리스너들에게 알림
*/
function notifyHotReloadListeners(): void {
hotReloadListeners.forEach((listener) => {
try {
listener();
} catch (error) {
console.error("Hot Reload 리스너 오류:", error);
}
});
}
/**
* Hot Reload 정리
*/
function cleanup(): void {
hotReloadListeners.length = 0;
isHotReloadEnabled = false;
}
/**
* Hot Reload 상태 확인
*/
export function isHotReloadActive(): boolean {
return isHotReloadEnabled;
}
/**
* 강제 컴포넌트 재로드 (개발자 도구용)
*/
export function forceReloadComponents(): void {
if (process.env.NODE_ENV === "development") {
console.log("🔧 강제 컴포넌트 재로드 실행");
reloadComponents();
} else {
console.warn("⚠️ 강제 재로드는 개발 모드에서만 사용 가능합니다");
}
}
// 자동 초기화 (개발 모드에서만)
if (process.env.NODE_ENV === "development" && typeof window !== "undefined") {
// DOM이 로드된 후 초기화
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", initializeHotReload);
} else {
setTimeout(initializeHotReload, 0);
}
}