코드 다이어트 - Knip으로 불필요한 코드 줄이기
서비스에 기능 추가 및 리뉴얼을 거듭 할 수록 보면 사용하지 않는 코드, 파일, 패키지(= 데드코드)가 생기게 됩니다. 물론 눈에 띄지 않겠지만, 번들 크기, 가독성 그리고 온보딩에 영향을 줍니다.
이번 글은 knip을 활용하여 데드코드를 탐지하는 것에 대해서 작성해보고자 합니다.
데드코드를 왜 치워야 될까요?
트리쉐이킹 단계에서 배제될거기도 하고, 프로젝트 실행에는 직접 영향이 없어 보여 굳이 제거 안 해도 괜찮지 않나? 라고 생각할 수 있습니다. 하지만 방치하게 되면 아래 문제가 발생합니다.
- 온보딩/리뷰 비용 증가: 시스템을 이해하고 유지보수 하기 어렵게 만듭니다.
- 빌드/테스트 시간 증가: 대부분 체감은 안되겠지만 빌드/테스트 진행시 스캔해야될 양이 증가하여 완료소요 시간이 증가합니다.
- 리팩토링 안전망 축소: 불필요한 코드가 많을수록, 리팩토링 진행시 위험도가 증가합니다.
- 실수 유도: 더 이상 사용하지 않는 deprecated 된 api/컴포넌트를 사용하게 될 가능성이 있습니다.
Knip은 뭔가요?
Knip은 TypeScript/JavaScript 프로젝트를 정적 분석해 미사용 항목을 찾아줍니다.
- Unused code / Unused exports
- dependencies / devDependencies / peerDependencies 미사용 점검
사용 방법이 단순해 문서만 조금 읽어보면 바로 적용 가능합니다.
설치 및 실행
knip.json 설정
테스트/스토리 등 ‘사용 의도는 있지만 앱 번들엔 포함되지 않는’ 파일은 제외하는 것이 핵심입니다.
실제 탐지 예시
위와 같은 컴포넌트들이 있을 때 knip을 실행하면
LegacyComponent
는 export가 미사용이어서 제거 후보로 출력이 되게 됩니다. 아래 같이 말이죠.
점진적 도입
- 탐지 위주로 진행: 로컬에서만 실행하여 목록 체크 (CI 적용도 가능, 파이프라인 실패x)
- 범위 제한: 한 번에 다 정리하기 보다는 작은 범위 부터 정리 진행 - 부작용 최소화
- 강화 전환: 합의 된 시점 부터는
--exitCode
를 지정하여 요소 감지시 실패 처리 (예: unused exports 혹은 unused files 감지 시 실패)
현재 팀에서는 1·2단계로 가볍게 운영 중이고, 양이 꽤 많아 3단계 전환 시점은 팀 합의가 필요해 보입니다.
결론
서비스가 커질수록 눈에 잘 띄지 않는 데드코드는 점점 쌓이게 됩니다. 이를 방치하면 단순히 번들 크기 문제를 넘어, 온보딩 비용 증가·리뷰 난이도 상승·리팩토링 리스크 확대 등 여러 부작용이 뒤따릅니다.
Knip은 이러한 문제를 예방하기 위한 “가벼운 안전망” 역할을 합니다.
- 초기에는 탐지 위주로 운영하여 부담을 줄이고,
- 점차 범위를 좁혀가며 정리를 진행하고,
- 팀의 합의가 이뤄지는 시점에 강화 모드(CI 실패 조건) 로 전환하는 것이 가장 안정적인 도입 방법입니다.
즉, 단순한 미사용 코드 탐지 도구를 넘어, 코드베이스 건강 상태를 지속적으로 관리하는 도구 로 활용할 수 있습니다.
작은 정리 습관은 장기적으로는 개발 생산성과 유지보수성을 크게 높여줍니다. 지금 한 번 Knip을 돌려보는 건 어떨까요?
참고: