Knip: JavaScript 및 TypeScript 프로젝트를 위한 궁극적인 죽은 코드 탐지기

발행: (2025년 12월 24일 오전 04:51 GMT+9)
10 분 소요
원문: Dev.to

Source: Dev.to

위에 제공된 텍스트 외에 번역할 내용이 없습니다. 번역이 필요한 본문을 제공해 주시면 한국어로 번역해 드리겠습니다.

Source:

문제: 죽은 코드가 여기저기 퍼져 있다

모든 성숙한 코드베이스에는 지저분한 비밀이 있다: 죽은 코드.
누군가 “혹시 몰라”라고 만든 유틸리티 함수.
폐기된 기능에서 남은 컴포넌트.
결코 진행되지 않은 스파이크용으로 설치한 npm 패키지.

ESLint는 파일 내에서 사용되지 않는 변수와 import를 잡아낼 수 있지만, 다음은 어떨까?

  • 어디에서도 import되지 않은 파일?
  • 아무도 사용하지 않는 export된 함수?
  • package.json에 남아 있지만 제거를 깜빡한 의존성?
  • 정의만 되고 전혀 참조되지 않은 타입과 인터페이스?

바로 여기서 Knip이 등장한다.

Knip이란?

Knip (네덜란드어로 “cut”)은 JavaScript/TypeScript 프로젝트에서 사용되지 않는 파일, 의존성 및 내보내기를 찾아주는 강력한 정적 분석 도구입니다. 코드베이스의 마리 콘도라고 생각하면 됩니다 — 코드가 즐거움을 주지 않거나(또는 사용되지 않으면) 반드시 제거해야 합니다.

Knip이 감지하는 항목

CategoryDescription
🗂️ 사용되지 않는 파일어디에서도 임포트되지 않은 소스 파일
📦 사용되지 않는 의존성package.json에 있지만 사용되지 않는 패키지
📤 사용되지 않는 내보내기내보내졌지만 한 번도 임포트되지 않은 함수, 클래스, 타입
🔧 사용되지 않는 개발 의존성필요하지 않은 개발 패키지
목록에 없는 의존성코드에서 사용되지만 package.json에 없는 패키지
🔗 해결되지 않은 임포트존재하지 않는 모듈을 가리키는 임포트

Knip report example

시작하기

설치

# npm
npm install -D knip

# yarn
yarn add -D knip

# pnpm
pnpm add -D knip

기본 사용법

npx knip

그게 전부입니다! Knip은 프로젝트를 분석하고 찾아낸 모든 사용되지 않은 코드를 출력합니다.

설정

대부분의 프로젝트에서는 Knip을 별도 설정 없이 바로 사용할 수 있습니다. 복잡한 설정(모노레포, 커스텀 엔트리 포인트 등)이 필요한 경우 설정 파일을 만들면 됩니다.

프로젝트 루트에 knip.json을 생성하세요:

{
  "$schema": "https://unpkg.com/knip@5/schema.json",
  "entry": ["src/index.ts", "src/App.tsx"],
  "project": ["src/**/*.{ts,tsx}"],
  "ignore": [
    "**/__tests__/**",
    "**/__mocks__/**",
    "**/node_modules/**"
  ],
  "ignoreDependencies": [
    "prettier",
    "husky"
  ],
  "ignoreExportsUsedInFile": true
}

주요 설정 옵션

옵션설명
entryKnip이 추적을 시작하는 엔트리 포인트 파일
project분석할 파일
ignore건너뛸 파일/패턴
ignoreDependencies건너뛸 의존성 (설정 전용 패키지에 유용)
ignoreExportsUsedInFile같은 파일 내에서만 사용된 내보내기를 보고하지 않음

React Native 예시

{
  "$schema": "https://unpkg.com/knip@5/schema.json",
  "entry": ["src/App.tsx", "index.js"],
  "project": ["src/**/*.{ts,tsx}"],
  "ignore": [
    "**/__tests__/**",
    "**/__mocks__/**",
    "android/**",
    "ios/**"
  ],
  "ignoreDependencies": [
    "@react-native/metro-config",
    "@react-native/typescript-config",
    "@react-native/babel-preset",
    "patch-package",
    "husky",
    "reactotron-react-native"
  ],
  "ignoreExportsUsedInFile": true
}

실제 결과

Running Knip on a production React Native app produced:

Unused files (73)
src/components/map/index.tsx
src/components/views/NotificationMenuButton.tsx
src/models/requests/auth/authRequests.ts
src/utils/helpers/contactHelper.ts
... and 69 more

Unused dependencies (1)
@react-native-firebase/perf

Unused devDependencies (4)
@babel/preset-env
@testing-library/jest-native
@types/react-native-get-random-values
eslint-plugin-react-you-might-not-need-an-effect

Unlisted dependencies (2)
credit-card-type  src/features/paymentMethods/addNewCard/index.tsx

Unused exports (74)
translations        src/config/localization/languages.ts
defaultAddressForm src/features/addressBook/addressTypes.ts
... and more

73개의 사용되지 않은 파일! 이는 수천 줄에 달하는 죽은 코드일 가능성이 있으며, 다음과 같은 문제를 일으킵니다:

  • 번들 크기 증가
  • 새로운 개발자에게 혼란을 줌
  • 유지 보수 부담 증가
  • 검색 결과에 나타나 시간을 낭비하게 함

워크플로에 통합하기

NPM 스크립트

package.json에 다음을 추가하세요:

{
  "scripts": {
    "knip:check": "knip",
    "knip:fix": "knip --fix"
  }
}

CI/CD 통합

# .github/workflows/code-quality.yml
name: Code Quality

on: [push, pull_request]

jobs:
  knip:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm ci
      - run: npx knip

Pre‑commit 훅 (Husky 사용)

# .husky/pre-commit
npx knip --no-exit-code

--fix 로 자동 수정

npx knip --fix

⚠️ Warning: 이 작업은 파일을 수정합니다! 항상 변경 사항을 검토하고 버전 관리를 준비하세요.

--fix 로 할 수 있는 일:

  • ✅ 사용되지 않는 export 제거
  • package.json에서 사용되지 않는 의존성 제거
  • ❌ 사용되지 않는 파일 삭제는 불가능 (위험함)

팁 및 모범 사례

  1. --include 로 시작하여 집중 – 결과가 너무 많아 압도될 경우, 먼저 특정 폴더나 카테고리로 분석을 제한하세요.
  2. 정기적으로 Knip을 실행하세요(예: CI에서) 죽은 코드를 누적되지 않게 방지합니다.
  3. Knip을 코드 리뷰 체크리스트와 함께 사용하세요: “새로운 사용되지 않은 import/파일 없음.”
  4. 수정 후 변경 사항을 커밋하고 팀에 정리 작업이 완료되었음을 알리세요.

Knip을 도입하면 코드베이스를 가볍게 유지하고, 개발자 경험을 향상시키며, 더 작고 빠른 번들을 배포할 수 있습니다. 청소를 즐기세요!

Source:

Knip 사용 팁

1. 특정 체크 포함하기

# 사용되지 않은 파일만 확인
npx knip --include files

# 의존성만 확인
npx knip --include dependencies

# 여러 카테고리 확인
npx knip --include files,exports

2. 출력 리포터 선택하기

# JSON 출력 (툴링에 유용)
npx knip --reporter json

# 마크다운 (문서화용)
npx knip --reporter markdown

3. 알려진 오탐 무시하기

일부 코드는 동적으로 사용되거나 Knip이 감지할 수 없는 관례를 통해 사용됩니다:

{
  "ignore": [
    "src/generated/**",
    "**/*.stories.tsx"
  ],
  "ignoreDependencies": [
    "tsconfig-paths"
  ]
}

4. 배럴 익스포트 처리하기

배럴 파일(index.ts에서 모든 것을 재수출) 을 사용하는 경우 Knip이 오탐을 보고할 수 있습니다. 다음 옵션을 활성화하세요:

{
  "ignoreExportsUsedInFile": true
}

5. 프레임워크‑별 플러그인

Knip은 다양한 프레임워크에 대한 내장 지원을 제공합니다:

{
  "next": {
    "entry": ["pages/**/*.tsx", "app/**/*.tsx"]
  },
  "jest": {
    "config": ["jest.config.js"]
  },
  "storybook": {
    "entry": [".storybook/main.ts"]
  }
}

Knip vs. 기타 도구

ToolUnused FilesUnused ExportsUnused DepsAuto‑fix
Knip
ESLintPartial
ts‑prune
depcheck
unimported

Knip은 여러 도구를 대체하는 올인원 솔루션입니다.

일반적인 문제 및 해결책

“거짓 양성이 너무 많이 발생해요!”

  • 코드가 동적으로 import되는지 확인하세요.
  • 설정의 ignore에 패턴을 추가하세요.
  • 설정 전용 패키지에는 ignoreDependencies를 사용하세요.
  • ignoreExportsUsedInFile을 활성화하세요.

“대규모 모노레포에서 Knip이 느려요”

{
  "ignore": [
    "**/dist/**",
    "**/build/**",
    "**/coverage/**"
  ]
}

“엔트리 포인트를 찾지 못하고 있어요”

명시적으로 정의하세요:

{
  "entry": [
    "src/index.ts",
    "src/cli.ts",
    "scripts/*.ts"
  ]
}

결론

죽은 코드는 시간이 지날수록 누적되는 기술 부채입니다. 사용되지 않는 파일 하나마다 다음과 같은 비용이 발생합니다:

  • 사용자에게 전달되는 바이트
  • 개발자에게 가해지는 인지적 부담
  • 잠재적인 보안 취약점
  • 낭비되는 CI/CD 시간

Knip은 코드베이스에서 실제로 사용되는 부분을 가시화해 줍니다. 한 번 실행해 보세요—발견에 놀라실 수도 있습니다. 정기적으로 실행하여 코드베이스를 가볍고 유지보수하기 쉽게 유지하세요.

# Try it now
npx knip

Resources

Knip이 코드베이스 정리에 도움이 되었나요? 댓글에 결과를 공유해주세요! 얼마나 많은 죽은 코드를 찾았는지 듣고 싶어요. 🔪

Tags: javascript, typescript, webdev, productivity

Back to Blog

관련 글

더 보기 »

🚀 번들 사이즈를 죽이는 걸 멈춰라

자동으로 TypeScript에서 Barrel 파일 제거하기! 커버 이미지 설명: 왼쪽에 무겁고 뒤얽힌 번들이 표시되고, 오른쪽에 깔끔하고 직접적인 import가 표시된 분할 화면.

Next js에서 번들 크기를 줄이는 방법

제가 처음 Next.js를 사용하기 시작했을 때, 기본 설정만으로도 얼마나 빠른지 정말 좋았습니다. 프로젝트가 커지면서 bundle size가 계속 증가해 로드가 느려졌습니다.

자바스크립트

핵심 트렌드 - 런타임 혁신: Deno의 최신 릴리스는 NPM 및 JSR 바이너리를 실행하기 위한 새로운 도구 dx를 도입하여 호환성을 개선하고 개발자 워크플로우를 향상시킵니다.