본문 바로가기
Javascript

제 컴퓨터에서는 되는데요??🙄

by 긍고 2023. 6. 7.
반응형

개요


최근 차세대 프로젝트를 진행하며 IE 호환을 지원하기 위해 gulp를 이용한 트랜스파일링을 적용하게 되었는데, 자바를 쓰며 자연스럽게 잊고 있었던 package.json을 마주하게 되었다🤬. 자바스크립트는 여러 모듈의 버전을 package.json 파일을 통해 관리하는데, 학부생 시절에는 어떤 방식으로 버전을 관리하는지 잘 알지못해 버전 충돌로 인해 많은 고생을 했었다. 오랜만에 마주한 김에 어떻게 package.json을 이용하여 버전을 관리하는지 정리해보려고 한다.

 

Package.json


자바스크립트라는 언어를 사용해 보았으면 누구나 한 번쯤은 보았을 파일 이름이다. 간단히 정리하면 package.json은 자바스크립트 프로젝트에 관한 정보와, 패키지 매니저(npm, yarn)을 통해 설치한 모듈들의 의존성을 관리하는 파일이다. 파일 내부에는 여러 설정값이나 프로젝트 정보가 담겨 있지만, 가장 많이 눈에 띄는건 프로젝트에 필요한 모듈들과 각 모듈의 버전이다.

 

그림 1. package.json 파일 구조 예시

위 예시를 보면 dependencies 항목에 여러 자바스크립트 모듈 이름과 버전이 명시되어 있다. 그런데 각 버전 좌측에 캐럿(^) 표시(🥕)가 있는걸 확인할 수 있는데, package.json에서는 이 표시를 통해 다운로드 받을 모듈의 버전을 설정할 수 있다.

 

버전(version)


일반적으로 버전을 표기할 때 .으로 구분된 세 개의 숫자로 표기하는것을 볼 수 있다. npm 모듈들은 모두 이 방식을 따르는데 이 방식은 Semantic Versioning (SemVer) 규칙이라고 한다. SemVer는 버전 번호를 MAJOR.MINOR.PATCH 형식으로 표현하며 각 의미는 아래와 같다.

 

  • MAJOR: 하위 호환성을 보장하지 않는 큰 변경 사항이 있을 때 증가
  • MINOR: 하위 호환성을 보장하는 새로운 기능 추가 시 증가
  • PATCH: 하위 호환성을 보장하는 버그 수정 시 증가

아래에서 소개할 틸드(~)캐럿(^)은 위의 버전 규칙을 기반으로 의존성 버전 범위를 지정하는데 사용된다.

 


틸드(~)

학부시절때만 하더라도 자바스크립트 모듈 버전 표현 시에 위에 언급한 캐럿(^) 말고도 틸드(~) 표현을 많이 볼 수 있었다. 현재는 틸드(~) 보다는 캐럿(^)이 표준으로 자리하고 있지만, 틸드는 캐럿과 어떤 차이가 있는지 정리해본다.

 

틸드는 PATCH 버전의 업데이트만을 허용한다. 예를 들어 버전을 ~1.2.3이라고 표기했다면 1.2.x 버전 즉, 1.2.3, 1.2.4, 1.2.5 등의 업데이트는 허용하지만 1.3.0과 같이 MINOR의 업데이트는 허용하지 않는다.

 


캐럿(^)

캐럿은 틸드보다 한 단계 더 위까지 업데이트를 허용한다. 즉, PATCH, MINOR의 버전 업데이트를 허용한다. 예를 들어 ^1.2.3과 같이 버전을 표기한다면 1.2.3, 1.2.4, 1.3.0 등의 업데이트는 허용하지만, 2.0.0과 같이 MAJOR 버전의 업데이트는 허용하지 않는다.

 

다만 예외 상황이 있는데, MAJOR 버전이 0 버전이라면 캐럿도 틸드처럼 PATCH의 업데이트만을 허용한다. 그 이유는, 버전이 1.0.0 미만인 경우(SemVer에서는 pre-release라고 명명함) API 변경이 수시로 일어나기 때문에 마이너 버전의 업데이트라고 하위 호환성을 보장할 수 없기 때문이다🙄.


이처럼 package.json의 버전은 특정 버전이 아닌, 범위로 관리되기 때문에 의도치 않은 특정 라이브러리의 업데이트로 인해 호환성이 깨져 버전 충돌 현상이 일어날 수 있다(제목처럼 내 컴퓨터에서는 되는데 ㅇㅅㅇ 과 같은 상황). 이에 대한 해결 방법으로 이 또한 많이 마주쳤을 package-lock.json 파일이 있다.

 

Package-lock.json


package.json이 모듈 버전의 범위를 나타낸다면 package-lock.json은 범위가 아닌 특정 모듈 버전을 명시한다. 이 파일은 npm이나 yarn을 이용해 모듈을 업데이트 할때 자동으로 생성되는데, 파일이 생성되는 시점의 의존성 트리에 대한 정확한 정보를 가지고 있다.

 

앞서 MINOR 버전은 하위 호환을 보장한다고 했지만, 간혹가다 모듈 개발자의 실수로 오류가 발생하는 경우가 있다(사실 좀 많다). 이럴 경우, package-lock.json 파일을 이용해 정확한 모듈 버전을 설치한다면 모두 동일한 환경에서 프로젝트 실행이 가능하다.

 

패키지 매니저를 이용해 install을 진행할 때, package.json 파일과 package-lock.json파일이 동시에 존재한다면 더 정확한 정보를 갖는 package-lock.json파일을 참조해 모듈을 설치하기 때문에 두 파일 모두 저장소에 공유하여 모두가 같은 환경에서 프로그램을 실행할 수 있어야 한다(학부생때 package-lock.json 이 계속 알아서 생성되길래 계속 지웠던 기억이 있다..).

 

정리


node를 사용해 개발하며 받았던 많은 스트레스중에 모듈 충돌이 한 몫 했었는데 오늘 정리를 통해 그 이유를 정확히 알게되었다. 어렵지 않은 내용이지만 모르면 내가 그랬던것처럼 파일을 지워버려 스불재를 만들 수 있으니 숙지하면 좋을것 같다. 끝.

 

참고


 

 

npm package.json에서 틸드(~) 대신 캐럿(^) 사용하기 :: Outsider's Dev Story

한 달 정도 전에 트위터에서 다음과 같은 트윗을 보고 처음 캐럿(`^`)의 존재를 알게 되었다. 아랫글의 의미는 npm에서 `package.json`에서 의존성의 버전을 명시할 때 기존의 기본값인 `~1.2.3`대신 `^1.2

blog.outsider.ne.kr

 

 

package-lock.json 이란 무엇일까?

내가 사용하는 라이브러리의 버전을 확인하려고 package.json을 찾아본 적은 있지만 package-lock.json은 뭐하는 파일인지 몰라서 검색해보고 쉽게 정리해보려고 한다. package-lock.json이란? npm을 사용해서

choisuhyeok.tistory.com

 

'Javascript' 카테고리의 다른 글

[JavaScript] 자바스크립트에서의 객체 비교 방법 (=== vs ==)  (0) 2024.09.23
이벤트 루프  (0) 2022.08.07

댓글