npm semver 에서 caret(^) 의 의미와 활용
- 개념
- 2024. 11. 22.
npm 패키지를 사용할 때 무심코 npm i [패키지명] 를 하게 되면 package.json 버전에는 caret(^)이 붙게 됩니다. 이 caret 의 의미를 알아봅니다. 그리고 이를 패키지를 사용하는 입장에서와 패키지를 관리하는 입장에서의 활용법도 알아봅니다.
npm 패키지 caret의 의미
node-semver 라는 이름으로 관리되는 패키지에서 karot(^) 버저닝의 의미를 정하고 있습니다.
https://github.com/npm/node-semver
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 에 대해 자세히 알아보고 싶다면 다음 글을 참고해주세요.
가장왼쪽의 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 버전의 패키지가 설치됩니다.
명령줄에 다음을 입력하여 설치된 버전을 확인합니다.
(node_modules 에서 typeorm 폴더의 package.json 을 통해 직접 확인할 수도 있습니다.)
npm list typeorm
패키지 업데이트하기
이제 typeorm 을 다시 설치하는 명령어를 실행해봅니다.
npm i typeorm
package.json 의 정보도 함께 업데이트가 된 것을 확인할 수 있습니다.
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 버전의 패키지가 설치됩니다.
버전 정보를 확인해봅니다. (node_modules 의 decimal.js 폴더의 package.json 파일을 통해서도 확인 가능)
npm list decimal.js
패키지 업데이트하기
이제 decimal.js 를 다시 설치하는 명령어를 실행해봅니다.
npm i decimal.js
package.json 의 정보도 함께 업데이트가 된 것을 확인할 수 있습니다.
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 |