DEVLOG|개발 블로그

package.json의 dependencies와 devDependencies의 차이점에 대한 정리

June 17, 2021 9:02 PM:nodejs

Dependencies

말 그대로 의존성이라는 뜻이다. 많은 기술 블로그들을 검색해보면 package.json에 정의된 dependenciesdevDependencies의 차이를 정확히 설명한 블로그들이 있다. 의견들을 종합해보면 해당 프로젝트를 개발할 때에만 필요한 의존성을 devDependencies에 정의하고 그렇지 않은 의존성은 dependencies에 리스트 해놓는다고 적혀있다. 맞는 말이고 실제로도 그렇게 사용한다. 그렇지만 너무 추상적이지 않은가. 실제로 이 둘의 차이를 체감하기가 어렵다.

어떻게 추가되는가

dependencies 항목은 의존성이 추가될 때 패키지 매니저를 통해 아무 옵션을 주지 않으면 리스트에 추가 된다. 예를 들어 npm i dayjs 명령어는 해당 의존성을 dependencies에 추가한다. 아무런 옵션을 주지않으면 기본값으로 dependencies에 리스트된다는 소리다. --save 옵션을 주어 dependencies 항목에 넣는다라는 명시적인 지시를 내릴 수 있다. 기본값으로 dependencies 항목에 추가된다면 왜 --save 옵션을 주어 명시를 하는걸까?

해답은 버전의 차이에 있다. 오래된 npm 버전에서는 --save 옵션을 명시해야만 dependencies 항목에 추가된다. 마찬가지로 devDependencies 항목에 추가하려면 --save-dev 라는 옵션을 주어야 항목에 추가되었다. 버전이 올라가면서 --save 옵션이 없으면 기본값으로 dependencies 항목에 추가되었기 때문에 아직도 많은 사람이 --save를 명시해서 사용한다.

위에서 언급했듯이 devDependencies 항목에는 --save-dev 옵션을 명시해야 추가된다. -D 옵션으로 줄여쓸 수 있다.

그럼 그 둘의 차이점은

앞서 말했듯이 이 둘의 차이점을 설명한 훌륭한 글들이 매우 많지만 여기서 한번 더 정리하자면 개발에 필요한 의존성과 실제로 어플리케이션 운용에 필요한 의존성을 나누는 차이가 있다.

왜 나눌까

제일 먼저 생각난 이 둘을 나눈 이유는 가시성의 차이가 아닐까 싶다. 단순히 보기좋으려고 이 둘을 나눴다고 하면 코웃음을 치겠지만 의존성 리스트가 늘어나면 늘어날수록 보기 불편한 것은 사실이다. 물론 제일 중요한 이유는 아니라고 생각한다.

배포 환경에서 해당 프로젝트를 가져와 의존성을 설치해서 프로젝트를 빌드하는 경우 개발에만 필요한 의존성을 설치할 필요가 없기 때문에 npm i --production 명령어로 정말 운용에 필요한 의존성만을 받아와서 더 빠르게 프로젝트를 빌드할 수 있다. 물론 devDependencies 항목에 빌드할 때 필요한 의존성이 포함될 수도 있다.

프로젝트를 패키지로 배포할 때도 나눈 점이 크게 작용한다. 실제로 내 프로젝트를 npm에 배포하고 다른 사람이 패키지 형태로 나의 프로젝트를 설치한다면 실제 운용에 필요한 의존성만을 설치해서 사용자의 로컬에 필요없는 의존성이 설치되는 경우를 방지할 수 있다. 예를 들어 프로젝트를 빌드하기 위해 바벨과 그에 관련된 플러그인을 설치해서 프로젝트를 빌드하고 빌드한 파일을 npm에 배포한다면 바벨은 최종 사용자의 입장에서 필요없는 패키지이기 때문에 devDependencies로 분류된다. 그러면 최종 사용자는 해당 의존성을 설치하지 않는다.

dependencies 항목의 어떤 패키지(A)가 B를 필요로 하고 B를 실행시키기 위해 C가 필요하다면 A, B, C가 모두 설치되어야 하고 모두 설치되지 않는다면 작동하지 않는다. 하지만 devDependencies 항목에서 A를 테스트 하기 위해 B를 테스트할 필요가 없기 때문에 A를 테스트 하는 행위에서는 B가 설치되지 않는다.

번외

devDependenciesdependencies 항목 외 peerDependencies 라는 항목이 있다. 이 항목은 해당 프로젝트를 운용하기 위해 항목에 포함된 의존성이 필요한 항목을 리스트하기 위해 있는 항목이다. 예를 들어 peerDependencies 항목에 A 라는 패키지가 지정되어 있고 A의 버전이 3.0.0으로 지정되어 있다면 해당 프로젝트를 사용하기 위해 A@3.0.0이 필요하다는 소리이다. 호환되지 않는 버전을 사용한다면 작동하지 않는다는 소리다.

해당 패키지가 설치되지 않는 상태에서 어플리케이션이 실행된다면 우리의 프로젝트는 실행되지 않고 오류를 뱉는다. npm 버전 7부터는 의존성 충돌이 일어나면 peerDependencies 항목에 있는 의존성을 자동으로 설치한다.