[Node.js] package-lock.json에 대해, 이 파일을 커밋해야하는 이유
0. 서론
(서론을 읽는건 생략해도 된다.)
NodeJS로 개발한 소스를 GitHub에 push한 후 다른 컴퓨터에서 pull받고 의존성 패키지를 설치 한 뒤 빌드하는데, 빌드가 실패하는 상황이 나왔었다.
설치한 외부 모듈 소스 내에서 아래와 같이 dependency를 찾을수 없다는 에러가 발생했다.
하지만 해당 dependency가 node_modules 폴더 내에 있어서 의아했었으나, 원인을 찾아보니, package-lock.json파일이 버전관리대상이 아니었고, 기존 개발 환경과 해당 파일의 내용이 달라서 구성되어야 할 의존성 트리가 정상적으로 구성되지 않았던 것이었다.
순서대로 위는 빌드가 되던 원래 소스의 package-lock.json파일 내의 "bootstrap-vue-3" 모듈의 의존성 정보이고,
아래는 다른 곳에서 내려받은 소스의 package-lock.json 파일 내의 "bootstrap-vue-3" 모듈의 의존성 정보이다.
둘의 내용이 다름을 알 수 있다.
그래서 기존 환경에서 가지고 있던 package-lock.json파일을 .gitignore에서 제거해 준 뒤 해당 파일을 push한 후,
새로운 환경에서 node_modules폴더와 package-lock.json파일을 제거한 뒤에 pull을 받고 npm install을 통해 의존성 모듈들을 설치해 준 후 빌드를 하니, 아래와 같이 빌드가 성공하게 되었다.
그렇다면 package-lock.json파일은 무엇이고 왜 관리해야 할까? 오늘 포스팅을 통해 이에대해 살펴보자.
1. package-lock.json이란?
package-lock.json을 알기 위해선 package.json 파일에 대해 알아야 한다.
package-lock.json파일은 패키지 매니저(npm, yarn)를 통해 node_modules 트리나 package.json 파일을 수정하게 되면 자동으로 생성되는 파일이다. 이 파일은 파일이 생성되는 시점의 의존성 트리에 대한 정확한 정보를 가지고 있다.
(더 알아보려면 이전포스팅 참조)
2. package-lock.json파일을 커밋해야 하는 이유?
package-lock.json파일을 커밋해야 하는 이유를 간단히 나열하자면 다음과 같다.
- npm의 버전이 다른 경우, npm의 알고리즘이 조금씩 다르기 때문에 서로 다른 node_modules 트리가 생성될 수 있다.
- 특정 버전명을 정확히 명시하지 않고 version range를 사용할 경우, 모듈의 새로운 버전이 릴리즈 된 이후 설치를 진행할 경우 이전 개발 환경과 다른 버전의 모듈이 설치될 수 있다. (이에따른 side-effect가 발생 할 가능성 존재)
package.json파일의 의존성 선언에는 version range가 사용된다. version range란 특정 버전뿐 아니라 버전의 범위까지 포함이 된다는 것을 의미한다. 가장 흔한 예로 npm install express를 실행하게 되면 package.json 파일에는 "^4.16.3"(Caret Ranges)로 버전 범위가 추가가 된다.
이 package.json 파일로 npm install을 실행하면 현재는 4.16.3버전이 설치되지만 express의 새로운 minor, patch가 publish되면 동일한 package.json 파일로 npm install을 실행해도 4.17.3 이나 4.16.4 같은 업데이트된 버전이 설치가 된다.
물론 대부분의 경우에는 문제가 없지만 간혹 업데이트된 버전이 오류를 발생시키는 경우가 있다.
package-lock.json 파일은 의존성 트리에 대한 정보를 가지고 있으며 package-lock.json 파일이 작성된 시점의 의존성 트리가 다시 생성될 수 있도록 보장해준다.
이해하기 쉽게 아래와 같이 사례를 들어보자.
package-lock.json 파일을 소스 저장소에 커밋하지 않은 경우:
1. A사원이 npm으로 프로젝트를 만들어서 git에 소스코드를 push한다. 이 때 node_modules폴더를 제외하고 package.json파일만 커밋한다.
2. B사원이 소스 코드를 pull 하고 npm install을 실행한다.
3. B사원의 일부 의존성 모듈의 버전이 A사원과 다르게 설치된다.
4. 소스 빌드시 오류가 발생한다.
5. B사원은 저녁밥을 회사에서 배달시켜 먹게 된다.
package-lock.json파일을 소스 저장소에 커밋한 경우:
1. A사원이 npm으로 프로젝트를 만들어서 git에 소스코드를 push한다. 이 때 node_modules폴더를 제외하고 package.json파일과 package-lock.json파일을 같이 커밋한다.
2. B사원은 소스 코드를 pull하고 npm install을 실행한다.
3. 모든 의존성 모듈이 A사원이 세팅한 환경과 동일하게 설치된다.
4. 소스가 정상적으로 빌드된다.
5. B사원은 저녁밥을 집에서 가족들과 오붓하게 먹게 된다.
3. 결론
package-lock.json이 존재할때에는 npm install의 동작 알고리즘이 조금 변한다.
package.json을 사용하여 node_modules를 생성하지 않고 package-lock.json을 사용하여 node_modules를 생성한다.
따라서 정리를 해보자면 package-lock.json은 개발자들이 동일한 node_module 트리를 생성해서 같은 의존성을 설치할 수 있도록 보장해주기 때문에 같이 커밋하는 것이 좋다.
#References
https://hyunjun19.github.io/2018/03/23/package-lock-why-need/