다크 모드
라우터 가드 추적
@platform/vue-debugger는 화면 전환이 막히거나 리다이렉트될 때 어느 가드가 그렇게 만들었는지를 Router 패널에 표시합니다. 대부분의 경우 별도 설정이 필요 없지만, 한 가지 경우 — 앱 부트스트랩보다 먼저 등록되는 전역 가드 — 만은 디버거가 자동으로 잡을 수 없습니다. 이 페이지는 그 한 줄짜리 보강 레시피 traceGuards를 설명합니다.
선택 기능이므로, 라우터 가드 추적이 굳이 필요 없다면 이 페이지는 건너뛰어도 됩니다. 기본 연동은 연동을 보세요.
언제 필요한가
가드는 등록 위치에 따라 디버거가 잡을 수 있는 시점이 다릅니다. 핵심은 디버거가 attach되는 시점(보통 app 셋업 직후) 보다 가드가 먼저 등록됐는지 여부입니다.
| 가드 종류 | 등록 위치 | traceGuards 필요? | 이유 |
|---|---|---|---|
라우트별 beforeEnter | 라우트 정의 안 | ❌ 불필요 | attach 시 디버거가 라우트 레코드를 순회하며 자동 귀속 |
전역 beforeEach / beforeResolve | router.ts 모듈 로드 시(attach 이전) | ✅ 필요 | vue-router가 내부 가드 리스트를 비공개해, attach 시점엔 이미 등록된 가드를 감쌀 수 없음 |
라우트별 beforeEnter는 그냥 됩니다
/admin처럼 특정 라우트의 beforeEnter가 막는 경우는 아무 설정도 하지 마세요. 디버거가 attach 시 라우트 레코드에서 직접 찾아 '어느 가드가 막았나'를 Router 패널에 표시합니다.
전역 가드를 잡는 한 줄 — traceGuards
전역 beforeEach/beforeResolve는 보통 router.ts 모듈이 로드될 때, 즉 디버거가 붙기 한참 전에 등록됩니다. 그래서 디버거 attach만으로는 잡히지 않습니다. 이를 해결하려면 가드를 등록하기 직전에 traceGuards(router)를 한 번 호출하세요. 그 뒤로 등록되는 모든 전역 가드가 감싸져 추적 대상이 됩니다.
ts
// router.ts
import { traceGuards } from '@platform/vue-debugger' // 정적 import (프로덕션선 트리셰이킹됨)
export const router = createRouter({ /* ... */ })
if (import.meta.env.DEV || (import.meta.env.MODE === 'staging' && import.meta.env.VITE_DEBUGGER === 'on')) {
traceGuards(router) // ← 전역 가드 등록 '전에' (동기 — 이 한 줄이 전부)
}
router.beforeEach(authGuard) // 이제 authGuard가 막거나 리다이렉트하면 Router 패널에 귀속됨호출 순서가 전부입니다. traceGuards(router)는 router.beforeEach/router.beforeResolve를 감싸도록 갈아끼우므로, 반드시 가드 등록보다 먼저 와야 합니다. 그 이후에 등록되는 authGuard 같은 가드는 자동으로 귀속됩니다.
등록 후에 부르면 그 가드는 못 잡습니다
router.beforeEach(authGuard) 다음에 traceGuards를 부르면, 이미 등록된 authGuard는 추적되지 않습니다. vue-router가 내부 가드 리스트를 비공개하기 때문에, 디버거는 등록 시점에만 가드를 감쌀 수 있습니다. 순서를 꼭 지키세요.
활성 분기 import.meta.env.DEV || (import.meta.env.MODE === 'staging' && import.meta.env.VITE_DEBUGGER === 'on')는 연동의 attachDebugger 분기와 동일합니다. 정적 치환 대상이라 production 빌드에서는 이 블록이 통째로 제거됩니다. 환경별 의미는 환경별 설정에서 자세히 다룹니다.
webpack / Vue CLI
import.meta.env가 없는 webpack·Vue CLI에서는 process.env.NODE_ENV !== 'production' || (__VDBG_STAGING__ && process.env.VUE_APP_DEBUGGER === 'on')로 대체하세요 — VUE_APP_DEBUGGER를 NODE_ENV 체크에 OR로만 붙이면 안 되고, 빌드 스크립트에 묶인 상수(__VDBG_STAGING__)와 AND로 결합해야 합니다(연동의 webpack 예시 참고). DefinePlugin이 이를 정적 치환해 동일한 dead-code 제거 효과를 줍니다.
왜 동적이 아니라 정적 import인가
attachDebugger는 await import('@platform/vue-debugger')로 동적 로드하는데, traceGuards는 정적 import로 가져옵니다. 이는 일관성이 없어 보이지만 의도된 차이이며, 두 가지 이유가 맞물려 있습니다.
- 동기 호출 순서가 필요합니다.
traceGuards는router.beforeEach(...)바로 직전에 동기적으로 호출돼야 가드 등록을 가로챌 수 있습니다.await import()(비동기)로 지연 로드하면 그사이에 가드가 먼저 등록돼 순서가 어긋납니다. 동기 정적 import만이 이 타이밍을 보장합니다. - production 누출이 없습니다. 정적 import를 써도 프로덕션 분기가 정적
false라 호출이 제거되고, 패키지의sideEffects:false설정 덕분에 호출이 사라진 import는 번들러가 통째로 트리셰이킹합니다. 결과적으로 프로덕션 번들엔traceGuards는 물론 디버거 코드가 한 바이트도 남지 않습니다. top-level await도 필요 없습니다.
누출이 0인지 직접 확인하기
프로덕션 빌드 후 산출물에서 디버거 흔적을 검사합니다.
bash
grep -rl "__VUE_DEBUGGER__" dist/assets 2>/dev/null && echo "⚠ 누출!" || echo "✓ 프로덕션 깨끗"CI에 고정하는 방법과 더 넓은 검증 절차는 설치 검증을 보세요.
가드 동작은 바뀌지 않습니다
traceGuards는 가드를 감싸기만 할 뿐, 동작은 그대로 보존합니다. 따라서 추적을 켰다고 해서 네비게이션 흐름이 달라지지 않습니다.
- 반환값 보존 — 원래 가드가 돌려주던 값(
true/false/경로/undefined)을 그대로 전달합니다. 차단·리다이렉트·통과 판정이 동일합니다. - 함수
length보존 — vue-router는 가드의 매개변수 개수(next사용 여부)로 호출 방식을 결정하므로, 래퍼도 원래 가드의length를 유지합니다. - 우아한 degrade — 동결된(frozen) 라우터 등 감싸기가 불가능한 경우엔 조용히 건너뛰고, 추적만 빠진 채 앱은 정상 동작합니다.
이중 래핑 걱정 없음
traceGuards는 라우터에 추적 표시를 남겨, attach 시 디버거 컬렉터가 같은 가드를 다시 감싸지 않도록 합니다. traceGuards와 디버거 자동 추적을 함께 써도 안전합니다.
정리
- 라우트별
beforeEnter는 설정 불필요 — 자동으로 잡힙니다. - attach 이전에 등록되는 전역
beforeEach/beforeResolve만router.ts에서 가드 등록 전에traceGuards(router)한 줄을 추가하세요. - 정적 import + 정적 분기 +
sideEffects:false로 프로덕션 누출은 0입니다. - 가드의 반환값·
length가 보존되므로 동작은 그대로입니다.
다음으로, 이 분기가 환경마다 어떻게 켜지고 꺼지는지는 환경별 설정에서, 실제로 추적이 동작하는지 확인하는 절차는 설치 검증에서 이어집니다.