package.json이란
package-lock.json이란
package.json과 package-lock.json의 차이
참고
오늘 지인 중 한 명이 package.json이랑 package-lock.json 차이가 뭔지 아시나요? 라고 물어보길래 버전 관리를 다르게 하는 것으로 알고 있습니다.
라고 답은 했지만, 확신이 없었습니다.
뭔가 면접 준비하면서 공부했던 것 같은데 기억이 나질 않아 오늘은 이 둘의 차이에 대해 공부해 보고자 합니다.
package.json이란
깨알 영어공부를 위해 해석해보자면
당신의 패키지에 package.json 파일을 추가하면 다른 사람들이 쉽게 관리하고 설치할 수 있습니다. registry(패키지 저장소)에 등록되는 패키지는 반드시 package.json 파일을 포함해야 합니다
- 프로젝트가 의존하는 패키지 목록을 작성
- 시맨틱 버전 규칙을 사용하여 당신의 프로젝트 패키지의 구체적인 버전을 명시
- build를 reproduceible(재현 가능) 하도록 다른 개발자에게 쉽게 공유
즉 package.json이란 다른 사람(협업자)들이 배포한 사람이 올린 코드를 쉽게 관리하고 설치할 수 있도록 사용되는 문서
입니다.
위 글에서 시맨틱 버전 규칙을 사용
하여 구체적인 버전을 명시하라고 했는데, 이게 무슨 의미일까요?
시멘틱 버저닝 이란 패키지의 일반적인 버전의 표현 방식을 의미합니다.
{MAJOR}.{MINOR}.{PATCH}
형식으로 표기합니다. ex) 1.3.0
MAJOR: 하위호환성이 보장되지 않는 변경사항 발생시 ⇒ 매우 큰 변화, 새로운 버전급 변화 ⇒ 큰 변화가 있으므로 내 코드도 수정해야함
MINOR: 하위호환성 보장 하면서 기능추가 ⇒ 새로운 기능 등 추가되는 경우 예를들어 react hook, class로도 사용 가능하지만 hook이 등장 ⇒ 하지만 현재 내 코드가 망가지진 않음
PATCH: 하위호환성 보장 하면서 버그수정 → 그냥 버그 수정
~1.3.0: >= 1.3.0 < 1.4.0
~1.5.2: >= 1.5.2 < 1.6.0
~2.2: >= 2.2 < 2.3
^1.0.2 : >=1.0.2 <2.0
^1.0 : >=1.0.0 <2.0
^1 : >=1.0.0 <2.0
공식문서에 아래와 같이 나타나있습니다.
너무 길어서 번역기의 도움을 좀 받아보겠습니다.
package-lock.json 파일은 npm이 node_modules 트리를 수정하거나 package.json을 변경하는 모든 작업에서 자동으로 생성됩니다.
이 파일은 생성된 정확한 의존성 트리를 기록하여, 이후 설치 시 중간 의존성 업데이트와 관계없이 동일한 트리를 재현할 수 있도록 합니다.
이 파일은 소스 코드 저장소에 커밋하는 것이 권장되며, 다음과 같은 목적을 가집니다:
팀원, 배포 환경, CI(Continuous Integration)에서 동일한 의존성을 설치하도록 보장합니다.
node_modules 디렉터리를 직접 커밋하지 않고도 이전 상태로 되돌아갈 수 있도록 합니다.
읽기 쉬운 소스 컨트롤(diff)을 통해 의존성 트리 변경 사항을 쉽게 확인할 수 있도록 합니다.
이전에 설치된 패키지에 대한 메타데이터 확인을 건너뛰어 설치 프로세스를 최적화합니다.
package-lock.json 파일의 중요한 특징 중 하나는 배포(publish)할 수 없다는 점입니다. 즉, 최상위 패키지 이외의 위치에서는 무시됩니다.
이 파일은 npm-shrinkwrap.json과 동일한 형식을 가지며, npm-shrinkwrap.json은 배포가 가능하다는 차이점이 있습니다.
그러나 npm-shrinkwrap.json은 CLI 도구 배포 또는 프로덕션 패키지 배포와 같은 특정한 경우에만 사용하는 것이 좋습니다.
만약 루트 디렉터리에 package-lock.json과 npm-shrinkwrap.json이 둘 다 존재하는 경우, package-lock.json은 완전히 무시됩니다.
package-lock.json 파일은 아래의 2가지 경우에 자동으로 생성
됩니다.
정확한 의존성 트리를 기록하여, 이후 설치 시 중간 의존성 업데이트와 관계없이 동일한 트리를 재현 -> 즉 구체적으로 정확한 버전을 가지고 있다. 예를들어 3.5~ 3.9버전이 아닌, 3.5.2 버전
package-lock.json은 협업하는 개발자들 간의 의존성 버전 충돌을 방지하기 위해 설치된 패키지의 정확한 버전 및 의존성을 기록하는 파일
입니다.이론은 이해했고, 실제 파일이 어떻게 구성돼있는지 확인해보겠습니다.
다시 정리하자면 아래와 같습니다.
package.json : 다른 사람(협업자)들이 배포한 사람이 올린 코드를 쉽게 관리하고 설치할 수 있도록 사용되는 문서
package-lock.json : 협업하는 개발자들 간의 의존성 버전 충돌을 방지하기 위해 설치된 패키지의 정확한 버전 및 의존성을 기록하는 파일
아래의 사진과 같이 package-lock.json은 구체적인 2.7.16버전으로 기록되지만,
package.json은 ^2.6.14 와 같이 범위로 기록된 걸 확인 할 수 있습니다.
이유는 -> 유연한 의존성 관리와 일관된 환경 보장이라는 두 가지 목적을 동시에 달성하기 위한 구조입니다.
1. A가 eslint를 최신 버전으로 다운 받습니다. ex) package.json - ^3.2.0, package-lock.json - 3.2.0
2. eslint에서 3.5.0으로 업그레이드 됐습니다.
3. npm i을 진행하게 되면 같은 ^3.2.0으로 관리하지만, 실제로는 3.2.0 -> 3.5.0 버전이 업그레이드 됩니다. ex) package.json - ^3.2.0, package-lock.json - 3.5.0
- 즉 npm i을 하게 되면 최신 버전을 가져올 수 있습니다.
만약 package-lock.json이 존재하지 않는다면 아래의 문제가 발생
1. A, B모두 eslint ^3.2.0 버전으로 관리
2. eslint가 업데이트가 돼서 3.4.0 버전으로 업그레이드 됨
3. A가 코딩 중 npm i을 진행하게 됐고, 3.4.0 버전으로 사용
4. eslint가 업데이트가 돼서 3.5.0 버전으로 업그레이드 됨
5. B가 코딩 중 npm i을 진행하게 됐고, 3.5.0 버전으로 사용
A는 3.4.0버전
B는 3.5.0버전으로 서로 다른 버전으로 사용하게 된다 -> 일관적이지 않은 환경 발생
따라서 반드시 package-lock.json이 수정되면 코드저장소에 commit을 해줘야합니다.