JavsScript를 사용하여 개발을 한다면 npm을 이용해 외부 라이브러리 혹은 프레임 워크를 사용해 본 경험이 있을 것입니다. npm을 실행한다면 프로젝트의 루트 디렉토리에 package.json이라는 파일이 생성됩니다. 보통 의존성을 관리하기 위한 문서로 생각하고 있지만 그 외에도 몇 가지 역할을 더 하고 있습니다.

package.json

npm docs에서 가져온 내용

다른 사람이 개발한 패키지를 쉽게 관리하고 설치할 수 있도록 도와주는 파일이라고 정리하고 있습니다. 그리고 더 구체적으로는 다음의 3가지 기능을 언급하고 있습니다.

  • 프로젝트가 의존하는 패키지 목록
  • 시맨틱 버전 관리 규칙을 사용하여 패키지의 버전을 지정
  • 빌드를 재현 가능하게 만들어서 다른 개발자들과 쉽게 공유할 수 있게 함

name과 version

package.json은 반드시 name과 version 필드(키)를 가지고 있어야 합니다. "name" 필드는 패키지의 이름을 포함하며, 소문자로 작성되어야 하며 하이픈(-)과 밑줄(_)을 포함할 수 있습니다. 또한 이름 가이드라인을 준수해야됩니다. "version" 필드는 x.x.x 형식으로 작성되어야 하며, 시맨틱 버전 규칙을 따라야 합니다. version의 형식 규칙은 다음표에 잘 나와 있습니다.

version 관리 규칙

npm docs에서 권장하는 버전 형식 규칙

새로운 패키지를 만들었다면 1.0.0으로 시작하는 것을 권장합니다. 새로운 버전은 기본적으로 이전 버전과 호환되도록 작성해야 합니다. 만약 버그를 수정한 Patch release와 같은 버전 업데이트는 세 번째 숫자를 증가시킵니다. 그리고 기능 추가가 이루어지는 버전은 Minor release라고 부르며 두번째 숫자를 증가시킵니다(세 번째 숫자는 0으로 만듭니다). 마지막으로 이전 버전과 호환되지 않는 버전 업데이트 혹은 큰 변화가 있는 버전은 Major release이며 첫번째 숫자를 증가시킵니다(두번째와 세 번째 숫자는 0으로 초기화합니다.).

 

쉽게 요약하자면 다음과 같습니다.

버전을 <Major>.<Minor>.<Patch>와 같은 형식으로 만들고,
1. 기존 버전과 호환되지 않게 API가 바뀌면 Major
2. 기존 버전과 호환되면서 새로운 기능을 추가하면 Minor
3. 기존 버전과 호환되면서 버그를 수정하면 Patch
를 각각 올리고 더 오른쪽에 있는 숫자는 0으로 초기화한다.

 

버전 앞에는 특정 기호를 추가하여 업데이트 범위를 지정할 수 있습니다. 해당 기호에 따라 자동으로 업데이트되는 범위가 지정됩니다. 유의적 버전(Semantic Version) 관련 한글 문서는 여기서 확인할 수 있습니다.

표기 방식 내용
version 명시된 version과 일치
>version 명시된 version보다 높은 버전
>=version 명시된 version과 같거나 높은 버전
<version 명시된 version보다 낮은 버전
<=version 명시된 version과 같거나 낮은 버전
~version 명시된 version과 같은 Minor release인 버전
^version 명시된 version과 같은 Major release인 버전

dependencies(의존성) 필드

언급한 "빌드를 재현 가능하게 만들어서 다른 개발자들과 쉽게 공유할 수 있게 함"이라는 목표를 달성하기 위해 어쩌면 가장 중요한 필드입니다. 사용자가 npm install 명령을 실행하면 package.json에 명시된 각 패키지의 시맨틱 버전 요구 사항을 충족하는 패키지들이 다운로드됩니다. 이를 통해 공유된 프로젝트와 같은 빌드 환경을 재현할 수 있습니다.

 

dependencies 필드는 애플리케이션의 프로덕션 환경에서 필요한 패키지들이 포함된 dependencies와 로컬 개발 및 테스트에만 필요한 패키지들이 포함된 devDependencies로 나누어집니다. devDependencies는 애플리케이션의 크기를 줄이기 위해 배포 환경에서는 빌드에서 제외됩니다.

 

프로젝트가 의존하는 패키지를 명시하기 위해서는 package.json 파일의 "dependencies" 또는 "devDependencies"에 해당 패키지들의 목록을 작성해주어야 합니다. 일반적으로 npm install 명령어를 사용한다면 자동으로 추가되며, --save-dev 또는 -D 플래그를 사용하여 devDependencies로 추가할 수 있습니다.

Peer Dependencies

일반적으로 Peer Dependencies는 애플리케이션이 아닌 플러그인 혹은 라이브러리 제작시에 사용하는 의존성 관리 형식입니다. 플러그인과 관련된 문제를 해결하기 위해 만들어진 새로운 형태의 의존성 관리 방법입니다.

 

plugin package는 항상 'host' 패키지를 직접 사용하지는 않지만 다른 'host' 패키지와 함께 사용하도록 만듭니다. 여기서 중요한 것은 특정 버전의 호스트 패키지와 함께 사용하도록 설계됩니다. 만약 plugin이 1.2.1 버전의 host를 사용하도록 되어 있고 현재 프로젝트엣는 2.1.2 버전의 host를 dependencies로 가지고 있다면 오류가 발생할 가능성이 있습니다.

 

이때 Peer dependencies를 사용하여 이 문제를 해결합니다. dependency는 내가 만든 모듈에서 사용하는 패키지들을 지정하는 반면, peer dependency는 반대로 해당 모듈이 다른 모듈과 함께 동작한다는 호환성을 표시합니다. 즉 plugin이 1.2.1 버전의 host를 peer dependency로 가진다면 plugin은 1.2.1 버전의 host를 사용할 때만 동작한다는 뜻입니다. 따라서 peer dependency로 설정된 host 프로젝트가 현재 설치된 host 프로젝트와 다른 버전이라면 에러가 발생하고 오류 메시지가 나타납니다.

 

대표적으로 react-dom이 같은 버전의 react를 Peer Dependency로 가지고 있습니다.

기타 필드

기본 값은 npm init --yes 명령어 사용을 하였을 때의 기준입니다.
scripts
npm과 관련되어 사용할 수 있는 다양한 명령어에 별칭(alias)를 지정하는 키-값 쌍을 저장합니다. 개발 중 사용하는 여러 명령어를 저장해두어 사용합니다. 일반적으로 npm run <별칭> 명령어를 사용합니다. 아래의 필드들 보다는 더 많이 사용하고 익숙할 필드입니다.


author
Name <email@example.com> (http://example.com)와 같은 형식을 사용합니다.


description
패키지에 대한 설명으로 npm에서 검색되었을 때 리스트에 표시됩니다. 기본값은 README에서 가져나 README가 없다면 빈 문자열이 됩니다.


keywords
description과 마찬가지로 npm에서 검색되었을 때 리스트에 표시됩니다.


license
패키지에 대해 패키지 사용자가 패키지를 사용하는데 가진 권한과 제약사항을 알려줍니다. 기본값으로 ISC가 사용됩니다.

참고 자료

NPM Docs
모던 자바스크립트 Deep Dive, 모듈화와 npm(node package manager)
유의적 버전
Node.js blog, Peer Dependencies, 원글: Domenic's blog about coding and stuff, Peer Dependencies

+ Recent posts