refactor(debug): 자체 완결형 DevCoordDebug로 전환 — 프로덕션 번들 완전 제거 보장
- lazy + 동적 import로 DEV에서만 청크 로드 - mapRef 기반 이벤트 등록으로 KoreaMap 코드에 디버그 흔적 없음 - 이전 CoordDebugTool/useCoordDebug 삭제
This commit is contained in:
부모
8f342f70b7
커밋
364a34ce10
@ -201,9 +201,11 @@ const FILTER_I18N_KEY: Record<string, string> = {
|
||||
cnFishing: 'filters.cnFishingMonitor',
|
||||
};
|
||||
|
||||
// [DEBUG] 좌표 디버그 도구 — 프로덕션 빌드에서 tree-shaking 제거
|
||||
import { useCoordDebug } from './debug/useCoordDebug';
|
||||
import { CoordDebugOverlay } from './debug/CoordDebugTool';
|
||||
// [DEBUG] 좌표 디버그 — DEV에서만 동적 로드, 프로덕션 번들에서 완전 제거
|
||||
import { lazy, Suspense } from 'react';
|
||||
const DevCoordDebug = import.meta.env.DEV
|
||||
? lazy(() => import('./debug/DevCoordDebug'))
|
||||
: null;
|
||||
|
||||
export function KoreaMap({ ships, allShips, aircraft, satellites, layers, osintFeed, currentTime, koreaFilters, transshipSuspects, cableWatchSuspects, dokdoWatchSuspects, dokdoAlerts, vesselAnalysis, groupPolygons, hiddenShipCategories, hiddenNationalities, externalFlyTo, onExternalFlyToDone, opsRoute }: Props) {
|
||||
const { t } = useTranslation();
|
||||
@ -216,8 +218,6 @@ export function KoreaMap({ ships, allShips, aircraft, satellites, layers, osintF
|
||||
const [selectedFleetData, setSelectedFleetData] = useState<SelectedFleetData | null>(null);
|
||||
const { fontScale } = useFontScale();
|
||||
const [zoomLevel, setZoomLevel] = useState(KOREA_MAP_ZOOM);
|
||||
// [DEBUG] 좌표 디버그 — DEV에서만 활성화, 프로덕션 빌드에서 tree-shaking 제거
|
||||
const coordDebug = useCoordDebug(!import.meta.env.DEV);
|
||||
const zoomRef = useRef(KOREA_MAP_ZOOM);
|
||||
const handleZoom = useCallback((e: { viewState: { zoom: number } }) => {
|
||||
const z = Math.floor(e.viewState.zoom);
|
||||
@ -612,12 +612,11 @@ export function KoreaMap({ ships, allShips, aircraft, satellites, layers, osintF
|
||||
style={{ width: '100%', height: '100%' }}
|
||||
mapStyle={MAP_STYLE}
|
||||
onZoom={handleZoom}
|
||||
onClick={coordDebug ? coordDebug.handleMapClick : undefined}
|
||||
>
|
||||
<NavigationControl position="top-right" />
|
||||
|
||||
{/* [DEBUG] Ctrl+Click 좌표 표시 — 프로덕션에서 제거 */}
|
||||
{coordDebug && <CoordDebugOverlay points={coordDebug.points} onRemove={coordDebug.removePoint} />}
|
||||
{/* [DEBUG] Ctrl+Click 좌표 표시 — 프로덕션 번들에서 완전 제거 */}
|
||||
{DevCoordDebug && <Suspense><DevCoordDebug mapRef={mapRef} /></Suspense>}
|
||||
|
||||
<Source id="country-labels" type="geojson" data={countryLabelsGeoJSON()}>
|
||||
<Layer
|
||||
|
||||
@ -1,9 +1,17 @@
|
||||
/**
|
||||
* [DEBUG TOOL] Ctrl+Click 좌표 표시 오버레이 컴포넌트
|
||||
* - 프로덕션 빌드에서 자동 제거됨 (import.meta.env.DEV 가드)
|
||||
* [DEBUG] 좌표 디버그 — 자체 완결형 래퍼
|
||||
* KoreaMap에서 이 컴포넌트만 동적 import하면 프로덕션 번들에서 완전 제거됨.
|
||||
* import, 훅, 컴포넌트 모두 이 파일 안에서 독립적으로 존재.
|
||||
*/
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Marker, Popup } from 'react-map-gl/maplibre';
|
||||
import type { CoordPoint } from './useCoordDebug';
|
||||
import type { MapRef } from 'react-map-gl/maplibre';
|
||||
|
||||
interface CoordPoint {
|
||||
lat: number;
|
||||
lng: number;
|
||||
id: number;
|
||||
}
|
||||
|
||||
function toDMS(dd: number, axis: 'lat' | 'lng'): string {
|
||||
const dir = axis === 'lat' ? (dd >= 0 ? 'N' : 'S') : (dd >= 0 ? 'E' : 'W');
|
||||
@ -15,7 +23,33 @@ function toDMS(dd: number, axis: 'lat' | 'lng'): string {
|
||||
return `${d}°${String(m).padStart(2, '0')}′${String(s).padStart(5, '0')}″${dir}`;
|
||||
}
|
||||
|
||||
export function CoordDebugOverlay({ points, onRemove }: { points: CoordPoint[]; onRemove: (id: number) => void }) {
|
||||
interface Props {
|
||||
mapRef: React.RefObject<MapRef | null>;
|
||||
}
|
||||
|
||||
/**
|
||||
* 자체 완결형 디버그 오버레이.
|
||||
* mapRef를 받아서 직접 click 이벤트를 등록/해제.
|
||||
* KoreaMap의 기존 코드에 어떤 것도 섞이지 않음.
|
||||
*/
|
||||
export default function DevCoordDebug({ mapRef }: Props) {
|
||||
const [points, setPoints] = useState<CoordPoint[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
const map = mapRef.current?.getMap();
|
||||
if (!map) return;
|
||||
|
||||
const handler = (e: maplibregl.MapMouseEvent) => {
|
||||
if (e.originalEvent.ctrlKey || e.originalEvent.metaKey) {
|
||||
e.originalEvent.preventDefault();
|
||||
setPoints(prev => [...prev, { lat: e.lngLat.lat, lng: e.lngLat.lng, id: Date.now() }]);
|
||||
}
|
||||
};
|
||||
|
||||
map.on('click', handler);
|
||||
return () => { map.off('click', handler); };
|
||||
}, [mapRef]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{points.map(cp => (
|
||||
@ -30,7 +64,7 @@ export function CoordDebugOverlay({ points, onRemove }: { points: CoordPoint[];
|
||||
<Popup
|
||||
longitude={cp.lng}
|
||||
latitude={cp.lat}
|
||||
onClose={() => onRemove(cp.id)}
|
||||
onClose={() => setPoints(prev => prev.filter(p => p.id !== cp.id))}
|
||||
closeButton={true}
|
||||
closeOnClick={false}
|
||||
anchor="bottom"
|
||||
@ -1,30 +0,0 @@
|
||||
/**
|
||||
* [DEBUG] Ctrl+Click 좌표 디버그 훅
|
||||
* - disabled=true 시 noop (프로덕션 빌드에서 dead code 제거)
|
||||
*/
|
||||
import { useState, useCallback } from 'react';
|
||||
import type { MapLayerMouseEvent } from 'react-map-gl/maplibre';
|
||||
|
||||
export interface CoordPoint {
|
||||
lat: number;
|
||||
lng: number;
|
||||
id: number;
|
||||
}
|
||||
|
||||
export function useCoordDebug(disabled = false) {
|
||||
const [points, setPoints] = useState<CoordPoint[]>([]);
|
||||
|
||||
const handleMapClick = useCallback((e: MapLayerMouseEvent) => {
|
||||
if (disabled) return;
|
||||
if (e.originalEvent.ctrlKey || e.originalEvent.metaKey) {
|
||||
e.originalEvent.preventDefault();
|
||||
setPoints(prev => [...prev, { lat: e.lngLat.lat, lng: e.lngLat.lng, id: Date.now() }]);
|
||||
}
|
||||
}, [disabled]);
|
||||
|
||||
const removePoint = useCallback((id: number) => {
|
||||
setPoints(prev => prev.filter(p => p.id !== id));
|
||||
}, []);
|
||||
|
||||
return { points, handleMapClick, removePoint, disabled };
|
||||
}
|
||||
불러오는 중...
Reference in New Issue
Block a user