유령 의존성이란?
개발 하다 보면, 어떤 패키지는 package.json
에 명시적으로 추가한 적이 없는데도 프로젝트에 사용할 수 있는 경우가 있습니다. 또는 npm install
을 했을 때 예상보다 더 많은 패키지가 설치되는 경우가 있습니다. 이런 현상을 유령 의존성이라고 부릅니다.
📌 유령 의존성이 발생하는 주요 원인
직접 설치하지 않은 패키지가, 하위 패키지를 통해 설치되면서 마치 직접 의존하는 것처럼 보이는 경우
- 패키지 매니저에 따라 의존성 트리가 다르게 구성되는 경우
=> npm은 90개의 하위 폴더, pnpm은 9개의 하위 폴더가 생김
📌 예제 재현
mkdir npm-test && cd npm-test
npm init -y
npm install react react-dom typescript eslint
mkdir pnpm-test && cd pnpm-test
npm init -y
pnpm install react react-dom typescript eslint
pnpm은 node_modules/.pnpm을 활용해 하드링크 최적화하지만, npm은 여러 위치에 중복 설치함.
테스트 결과를 보기 위해, 아래 버전으로 테스트하였습니다.
"eslint": "^8.12.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"typescript": "^4.6.3"
npm은 중복 설치가 발생할 수 있기 때문에, 프로젝트의 크기가 커지고 디스크 공간을 많이 차지할 수 있습니다.
pnpm은 하드링크를 사용하여 디스크 공간을 절약하고, 중복 설치를 방지할 수 있습니다.
유령 의존성이 왜 문제인가?
유령 의존성이 하위 패키지를 설치하면서 생긴 의존성이라고 제대로 관리하지 않으면 다음과 같은 에러가 발생할 수도 있습니다.
- 빌드 실패 및 런타임 오류 발생
개발 환경에서는 유령 의존성이 있어서 잘 실행되지만, 배포 후에는 해당 패키지가 없어서 빌드가 실패할 수 있습니다. - 의존성 관리 어려움
특정 패키지가 어디서 온 건지 추적하기 어려워지고, 예상하지 못한 버전 충돌이 발생할 수도 있습니다. - 보안 문제
패키지 관리가 제대로 되지 않으면, 의도하지 않은 패키지가 포함될 수도 있습니다.직접 설치하지 않은 패키지가 하위 의존성을 통해 포함된 사례
어떻게 발견할 수 있을까?
유령 의존성을 확인하는 방법에는 여러 가지가 있습니다.
npm ls
명령어 활용
이 명령어를 실행하면 특정 패키지가 어디서 의존하고 있는지 트리 형태로 보여줍니다.npm ls package-name
npm dedupe
명령어 활용
이 명령어를 실행하면 중복된 의존성을 정리해 깔끔한 상태로 정리할 수 있습니다.npm dedupe
의존성을 해결하는 방법
명시적으로 package.json
에 추가하기, lock file
삭제후 재설치, npm audit
으로 보안 이슈가 있는 의존성을 포함한 패키지를 확인하기 등의 방법이 있을 것 같습니다
유령 의존성 예방하기
- PR 리뷰 시
lock file
이 변경되었을 경우 원인을 체크하고 변경점이 진짜 필요한 내용만 변경되었는지 확인하기 npm dedupe
또는npm prune
을 사용해 불필요한 패키지를 제거하는 습관을 들이기
결론
유령 의존성은 우리가 직접 설치하지 않았지만 하위 패키지를 통해 설치되면서 마치 직접적인 의존성처럼 보이는 패키지들을 의미합니다. 이를 방치하면 빌드 실패, 디버깅 난이도 증가, 보안 취약점 유발 등의 문제가 발생할 수 있습니다.
유령 의존성 문제를 사전에 예방하고 관리하면 프로젝트의 안정성과 유지보수성을 크게 높일 수 있습니다. 🚀
'Frontend > Dev Notes' 카테고리의 다른 글
주석을 언제 작성해야 할까? (3) | 2024.10.27 |
---|---|
빈 태그 사용을 피해야 하는 이유 (0) | 2024.03.16 |
React Query에서 Non-null Assertion Operator 사용하기 좋은 방법일까? (0) | 2024.02.18 |
똑똑한 컴포넌트, 어디까지가 좋을까? (0) | 2024.01.26 |
React Custom Hook 디자인 패턴: Query/Mutation 훅 분리 (0) | 2023.12.31 |