npm
으로 Node.js 패키지들을 관리하는 프로젝트의 경우, 프로젝트 루트 폴더에는 Node.js 패키지들이 설치된 node_modules
폴더와 함께 package.json
, package-lock.json
파일이 위치하고 있다. 이번 포스팅에서는 Node.js 패키지를 활용하여 프로젝트를 진행하는 개발자들이 node_modules
폴더, package.json
파일, 그리고 package-lock.json
파일에 대해 최소한으로 알고 있어야 하는 것들에 대해 정리해보기로 하였다. 틀린 내용이 있다면 댓글로 지적 바란다.Node.js 및npm
에 대한 기본적인 내용은 여기를 참고하기 바란다.
본 포스팅은npm
6까지 사용하던lockfileVersion
1을 기준으로 작성되어, 최신lockfileVersion
과는 다르다.
1. node_modules 폴더 (의존성 트리)
npm
을 이용하여 설치하는 Node.js 패키지들이 위치하는 곳이다. 이 폴더의 구조는 곧 해당 프로젝트에서 사용하는 Node.js 패키지들의 의존성 트리를 나타낸다. node_modules
폴더 안에는 설치된 Node.js 패키지들에 해당하는 폴더들이 존재하고, 각 패키지 폴더 안에도 필요한 경우(뒤에서 설명) 또 다른 Node.js 패키지들에 해당하는 폴더들이 존재할 수 있기 때문이다. 참고로, 일반적인 경우 이 폴더는 버전 관리 시 커밋 대상에서 제외가 된다. 곧 이어서 설명할 package.json
파일과 package-lock.json
파일만 있으면, npm install
명령어를 통해 node_modules
폴더의 의존성 트리와 동일한 형태로 Node.js 패키지들을 설치할 수 있기 때문이다.2. package.json 파일과 npm install
프로젝트에서 필요로 하는 Node.js 패키지들에 대한 정보를 JSON 형태로 표현하는 파일이다. 필수적으로 해당 프로젝트에 관한
name
및 version
속성이 명시되어야 하며, 설치되어야 할 Node.js 패키지들의 목록은 dependencies
또는 devDependencies
속성에 명시가 된다. package.json
파일은 npm install
명령어로 Node.js 패키지를 설치할 때마다 생성되거나 업데이트된다. dependencies
속성에는 --save
옵션으로 npm install {패키지명}
명령어를 실행할 때 설치되는 Node.js 패키지가 등록되고, devDependencies
속성에는 --save-dev
옵션으로 npm install {패키지명}
명령어를 실행할 때 설치되는 Node.js 패키지가 등록된다. 이때 devDependencies
속성에 명시되는 패키지들은 배포 시에는 사용되지 않고 개발 시에만 사용된다는 특징이 있다. 참고로, npm install {패키지명}
명령어를 실행할 시 특별히 옵션을 지정해주지 않으면 기본적으로 --save
옵션이 지정된다. 즉, 설치되는 패키지는 기본적으로 dependencies
속성에 등록이 된다.여기서 '배포 시에는 사용되지 않고 개발 시에만 사용'이 의미하는 것은 무엇일까?
간단하다. 테스트, 컴파일, 코드 스타일 검사 등의 목적으로 사용되는 Node.js 패키지들은 배포하려는 실서버 환경에서는 설치될 필요가 없다. 따라서 실서버 환경에서는
npm install
명령어 대신 npm install --production
명령어를 실행하는데, 이는 package.json
파일에서 오로지 dependencies
속성에 등록된 Node.js 패키지들만 설치하게 된다. 즉, 개발 시에만 사용되는 Node.js 패키지들은 설치하지 않는 것이다.일반적으로
node_modules
폴더는 커밋하지 않는 반면, package.json
파일은 반드시 커밋하게 된다. 해당 프로젝트를 pull
하여 받아온 뒤 npm install
명령어를 수행하면, node_modules
폴더를 생성하고 package.json
파일을 참조함으로써 필요한 Node.js 패키지들을 일괄 설치할 수 있기 때문이다. 그런데 여기서 문제가 존재한다. package.json
파일에 명시되는 각 Node.js 패키지의 버전 정보는 정확한 값이 아닌 범위 값(EX. ^4.16.3
)이라는 것이다. 그 결과, 동일한 package.json
파일로 npm install
명령어를 실행하더라도 npm
버전이 다르거나 특정 패키지가 추후 업데이트되거나 하는 등의 이유로 인해 의도와는 약간 다른 의존성 트리를 나타내는 node_modules
폴더를 만들어낼 수 있다. 이처럼 배포 당시 개발자가 의도한 버전이 아닌 다른 버전의 패키지가 설치된다면 프로젝트의 동작에 오류가 발생할 수도 있다. 이러한 문제를 해결하기 위해 등장한 것이 바로 이어서 설명할 package-lock.json
파일이다.3. package-lock.json 파일
package-lock.json
파일은 npm
을 통해 node_modules
폴더의 내용이나 package.json
파일의 내용을 생성하거나 업데이트할 때 자동으로 생성되거나 업데이트되는 파일로, Node.js 패키지들의 업데이트 여부와 상관없이 언제나 동일한 의존성 트리의 형태로 패키지들을 설치할 수 있도록 보장해준다. 즉, node_modules
폴더의 의존성 트리 구조를 기록하는 이 파일이 존재하면 npm install
명령어 실행 시 배포 당시 개발자가 의도한 버전대로 Node.js 패키지들을 설치할 수 있게 된다. 따라서 이 파일 또한 버전 관리 시 반드시 커밋 대상에 포함시키는 것이 좋다. 그렇지 않으면 package.json
파일의 한계로 인해 버전의 문제가 발생할 수도 있다.package-lock.json
파일의 dependencies
속성에는 설치될 각 Node.js 패키지에 대한 정보가 다음과 같은 형태로 표현된다. (EX. react-router
패키지)react-router
: Node.js 패키지 이름으로,node_modules
폴더 내에 존재한다.
version
: 설치된react-router
패키지의 정확한 버전을 의미한다.
requires
:react-router
패키지가 의존하는 다른 패키지들의 목록으로,react-router
패키지 폴더에 존재하는package.json
파일의dependencies
속성에 명시된 패키지들의 목록과 같다. 여기에 명시된 패키지는 반드시 설치되어 기본적으로는node_modules
폴더에 존재해야 한다. 만약 두 개의 패키지가 같은 패키지에 의존하는데 다른 버전을 요구한다면 하나의 버전은node_modules
폴더가 아닌 해당 패키지 폴더 내에 존재한다.
dependencies
:react-router
패키지가 의존하는 패키지들 중, 기본적으로node_modules
폴더에 설치된 버전과 다른 버전을 요구하는 패키지들의 목록이 이곳에 명시된다. 즉, 여기에 명시되는 패키지는 다른 패키지에서도 의존하고 있는 패키지라는 것을 추론할 수 있고, 그 패키지가 의존하고 있는 버전이랑react-router
패키지가 의존하고 있는 버전(1.8.0
)이 다르기 때문에 여기에 명시되어 있는 것이다. 그리고 앞서 말했듯package-lock.json
파일의 내용은node_modules
폴더의 의존성 트리 구조를 나타내기 때문에, 이곳에 명시되는 패키지들은 실제로react-router
패키지 폴더 내부에 존재하고 있다.
결국, 여기에 명시되는
dependencies
속성들의 계층이 곧 node_modules
폴더의 계층과 완전히 동일하다. 그리고 dependencies
속성에 나열되어 있는 각 패키지는 정확한 버전이 명시되어 있다. 따라서 원래의 node_modules
폴더와 똑같은 node_modules
폴더를 복원할 수 있게 된다.본 글은 아래 링크의 내용을 참고하여 학습한 내용을 나름대로 정리한 글임을 밝힙니다.