npm semver 에서 caret(^) 의 의미와 활용

 

npm 패키지를 사용할 때 무심코 npm i [패키지명] 를 하게 되면 package.json 버전에는 caret(^)이 붙게 됩니다. 이 caret 의 의미를 알아봅니다. 그리고 이를 패키지를 사용하는 입장에서와 패키지를 관리하는 입장에서의 활용법도 알아봅니다.

npm 패키지 caret의 의미

node-semver 라는 이름으로 관리되는 패키지에서 karot(^) 버저닝의 의미를 정하고 있습니다. 

https://github.com/npm/node-semver

 

GitHub - npm/node-semver: The semver parser for node (the one npm uses)

The semver parser for node (the one npm uses). Contribute to npm/node-semver development by creating an account on GitHub.

github.com

Allows changes that do not modify the left-most non-zero element in the [major, minor, patch] tuple. In other words, this allows patch and minor updates for versions 1.0.0 and above, patch updates for versions 0.X >=0.1.0, and no updates for versions 0.0.X.

 

버전 왼쪽에 붙어있는 caret(^)은  '가장 왼쪽의 0이 아닌 요소가 바뀌지 않는 변경만을 허용'한다는 표시입니다. 이를 좀 더 풀어서 알아봅니다.

일러두기: semver 의 요소

semver 는 . 을 기준으로 3가지로 구분됩니다. [major, minor, patch] 튜플로 구성된다고 인용문은 설명하고 있습니다. semver 에서 각 요소는 major, minor, patch 중 하나를 의미합니다. 1.2.3 의 버전이라면 major 요소는 1, minor 요소는 2, patch 요소는 3입니다. semver 에 대해 자세히 알아보고 싶다면 다음 글을 참고해주세요.

 

가장 쉬운 🙈 유의적 버전 semver

현대의 프로그램은 많고 복잡한 의존 관계를 가지고 있습니다. 만약 의존하고 있던 프로그램의 버전이 업데이트 되면서 문제가 생기면 대응을 해야하는데, 의존하는 라이브러리가 수십개에다

coldmater.tistory.com

가장왼쪽의 0이 아닌 요소

가령 ^0.1.3 라면 가장 왼쪽의 0이 아닌 요소는 minor 에 해당하는 1입니다.

만약 ^3.5.7 라면 가장 왼쪽의 0이 아닌 요소는 major 에 해당하는 3입니다.

수정을 하지 않는 변경 허용

semver 에서 caret(^) 지시자는 가장 왼쪽의 0이 아닌 요소가 바뀌지 않는 변경만을 허용합니다.

package.json 에 "lib-a": "^0.1.3" 으로 버전이 지정된 경우

  • 가장 왼쪽의 0 이 아닌 요소가 minor 버전인 1 이므로 minor 버전이 수정되지 않는 변경만 허용됩니다.
  • 이는 곧 patch 버전이 수정되는 변경만이 허용된다는 의미가 됩니다.
  • lib-a 패키지의 0.1.4 버전이 npm 에 등록되어 있다면 업데이트합니다. (패치 버전 업데이트)
  • lib-a 패키지의 0.2.0 버전이 npm 에 등록되어 있더라도 업데이트 하지 않습니다. (마이너 버전 고정)
  • lib-a 패키지의 1.0.0 버전이 npm 에 등록되어 있더라도 업데이트 하지 않습니다. (메이저 버전 고정)

package.json 에 "lib-b": "^3.5.7" 으로 버전이 지정된 경우

  • 가장 왼쪽의 0 이 아닌 요소가 major 버전인 3 이므로 major 버전이 수정되지 않는 변경만 허용됩니다.
  • 이는 곧 major 를 제외한, minor 버전과 patch 버전을 수정하는 변경이 허용된다는 의미가 됩니다.
  • lib-a 패키지의 3.5.8 버전이 npm 에 등록되어 있다면 업데이트합니다. (패치 버전 업데이트)
  • lib-a 패키지의 3.6.0 버전이 npm 에 등록되어 있다면 업데이트합니다. (마이너 버전 업데이트)
  • lib-a 패키지의 4.0.0 버전이 npm 에 등록되어 있더라도 업데이트 하지 않습니다. (메이저 버전 고정)

정리

npm semver 의 caret(^) 은 breaking change 가 예상되는 버전 요소의 수정을 제외하고 변경(업데이트)한다.

그 세부 사항은 아래와 같다.

 

major 버전이 0(zero)인 패키지의 업데이트는 패치버전이 수정되는 변경(업데이트)만 허용한다.

semver 에서 major 버전이 0 인 패키지는 (0.0.3, 0.8.9 등) 공식 배포판이 아닌 것으로 간주합니다. 따라서 이 경우 minor 버전의 업데이트에서도 breaking change 가 있을것으로 간주하고, minor 버전의 자동 업데이트를 제한합니다.

 

major 버전이 1 이상인 패키지의 업데이트는 마이너버전과 패치 버전이 수정되는 변경(업데이트)만 허용한다.

semver 에서 major 버전이 1 이상인 패키지는 (1.0.0, 12.8.9 등) 공식 배포판으로 보고, breaking change 가 있을 것이라고 기대되는 major 버전만을 자동 업데이트하지 않습니다.

해보기

빈 nodejs 패키지를 하나 만들고 (npm init) 다음 과정을 따라 진행해봅니다.

major 버전이 0인 패키지

패키지 설치하기

명령줄에 다음과 같이 0.2.0 버전의 typeorm 을 설치해봅니다. typeorm 은 글 작성일 기준으로 최신버전이 0.3.20 인 패키지입니다.

npm i typeorm@0.2.0

 

package.json 에는 다음과 같이 ^ 이 붙어 0.2.0 버전의 패키지가 설치됩니다.

0.2.0 버전으로 고정되어 package.json 에 패키지 정보가 추가되었다.

 

명령줄에 다음을 입력하여 설치된 버전을 확인합니다.

(node_modules 에서 typeorm 폴더의 package.json 을 통해 직접 확인할 수도 있습니다.)

npm list typeorm

typeorm 의 버전은 0.2.0 버전으로 설치가 되어 있다.

 

패키지 업데이트하기

이제 typeorm 을 다시 설치하는 명령어를 실행해봅니다.

npm i typeorm

패키지가 0.2.45 버전으로 업데이트 되었다.

 

package.json 의 정보도 함께 업데이트가 된 것을 확인할 수 있습니다.

package.json 의 정보도 함께 0.2.45 로 업데이트 되었다.

 

0.3.20 버전이 있지만, ^0.2.0 으로 지정되어있었기 때문에, 패치버전의 업데이트만 진행되었습니다.

💡 package.json 만 남겨두고 pacakge-lock.json 및 node_modules 폴더를 지운 상태에서 npm i 를 할 때 package.json 의 버전 정보는 변경되지 않지만, 실제 설치되어 있는 패키지의 caret(^) 규칙을 따른 최신 버전일 수 있습니다.

major 버전이 1 이상인 패키지

npm list decimal.js

패키지 설치하기

명령줄에 다음과 같이 decimal.js@9.0.0 버전을 설치해봅시다. decimal.js 는 글 작성일 기준으로 10.4.3 이 최신버전입니다.

npm i decimal.js@7.0.0

 

package.json 에는 다음과 같이 ^ 이 붙어 7.0.0 버전의 패키지가 설치됩니다.

9.0.0 버전으로 caret(^) 이 붙어 package.json 에 패키지 정보가 추가되었다.

버전 정보를 확인해봅니다. (node_modules 의 decimal.js 폴더의 package.json 파일을 통해서도 확인 가능)

npm list decimal.js

decimal.js 의 버전은 7.0.0 버전으로 설치가 되어 있다.

패키지 업데이트하기

이제 decimal.js 를 다시 설치하는 명령어를 실행해봅니다.

npm i decimal.js

패키지가 7.5.1 버전으로 업데이트 되었다.

package.json 의 정보도 함께 업데이트가 된 것을 확인할 수 있습니다.

package.json 의 정보도 함께 7.5.1 로 업데이트 되었다.

10.4.3 버전이 있지만, ^7.0.0 으로 지정되어있었기 때문에, 마이너 및 패치버전의 업데이트만 진행하였습니다.

💡 package.json 만 남겨두고 pacakge-lock.json 및 node_modules 폴더를 지운 상태에서 npm i 를 할 때 package.json 의 버전 정보는 변경되지 않지만, 실제 설치되어 있는 패키지의 버전은 다를 수 있습니다.

 

정리

npm i [패키지명] 명령어를 사용했을 때 package.json 에는 기본적으로 caret(^) 표시가 붙습니다. 이는 breaking change 가 있을 수 있는 업데이트는 진행하지 않음을 의미합니다. 패키지를 관리하는 입장에서도 breaking change 가 있는 업데이트의 경우 semver 의 의미에 따라  버저닝을 해주어야 합니다.

반응형

'개념' 카테고리의 다른 글

가장 쉬운 🙈 유의적 버전 semver  (0) 2024.11.18
CORS가 어려운 이유 - 1. CORS 에러 마주하기  (3) 2024.11.10

Designed by JB FACTORY