dev/개발일지

package.json [ tilde, caret ],[ major, minor, patch ]

Box 2022. 3. 27. 17:56
728x90

계기

어제 package-lock.json 블로깅을 하다가 틸드, 캐럿 range 라는 키워드를 알게되었다

해당 키워드를 구글링 했을대 major, minor , patch 라는 키워드도 같이 알게 되어 흥미가 생겨 블로깅을 하게 되었다.

 

우선 틸드캐럿을 알기전에 먼저 major, minor, patch 에 대해 알아보겠다.

 

SemVer

Semantic Versioning의 줄임말로, 버전 형식에 의미를 부여하여 좀 더 체계적인 버전 관리를 위한 제안입니다.

배포 정책이나 시기에 따라서 버전이 매겨지거나,

의미 없이 버전이 올라가는 것을 지양하며 버저닝에 대한 명확한 의미를 부여합니다.


버전의 형식은 [Major].[Minor].[Patch] 형식으로 한다.

 

package.json 파일에서

 

"devDependencies": {
  "react-test-renderer": "^16.13.0",
}

 

16.13.0 버전을 나타내는 점과 숫자들을 봤을 것이다. 이것 하나하나가 명세에 맞추어 업데이트가 되는데 어떻게 되는지 확인해보자.

[MAJOR , MINOR, PATCH] 로 구성되어 있다.

소프트웨어 릴리즈 버전 넘버에 대한 네이밍 시스템이다.

그라바타(Gravatars)의 창시자이자 깃헙(GitHub)의 공동창업자인 톰 프레스턴-베르너(Tom Preston-Werner)가 작성했으며, 오픈소스 프로젝트에 일반적으로 사용된다.버전은 사용자가 이 package (api)가 어떤식으로 변경되었는가를 이해할 수 있게 해준다.

Versions

  • MAJOR Version: 기존 api가 변경 / 삭제 되었기 때문에 update 하면 동작하지 않을 수 있다는 경고의 의미
  • MINOR Version: 이전 버전과 호환되는 방식으로 API가 추가되었으니 살펴보라는 의미
  • PATCH Version: 이전 버전과 호환되는 버그 수정을 했을 경우

 

Rule

API가 이전 버전과 호환되지 않게 변경된 경우에는 반드시 Major 버전을 올린다.

이 때 Minor 버전과 Patch 버전은 0으로 초기화한다.

 

Patch 버전 뒤에 하이픈(-)을 붙이고 마침표(.)로 구별된 식별자를 붙여 배포 전의 버전을 명명할 수 있다.

1.0.0-alpha, 1.0.0-alpha.1 과 같은 형식으로. 이 때, 정식배포 버전과 비교하면 정식배포 버전의 우선순위가 더 높다.
1.0.0-alpha < 1.0.0

최초 개발 배포 버전을 0.1.0으로 한다.

자릿수를 맞추기 위해 0으로 시작하는 숫자를 쓰지 않도록 한다.

예를 들어 2.07.1은 좋지 않다. 2.7.1을 쓰도록 하자.

부모 버전이 오르면 자식 버전은 0으로 초기화한다.

Major 버전이 오르면 Minor와 Patch 버전은 0으로 초기화한다.
Minor 버전이 오르면 Patch 버전은 0으로 초기화한다.

배포하면 그 버전의 내용은 절대 변경해서는 안된다. 😱

 

이제 version Range 에 대해 알아보겠다.

 

Vesrsion Range

range들에 대해 알기전에 먼저 기초 개념들 부터 알아보겠다.

범위

내가 어느버전까지 올릴지 범위를 정할 수 있다.

  • < 명시된 버전보다 낮은버전
  • <= 명시된 버전과 같거나 낮은버전
  • > 명시된 버전보다 높은버전
  • >= 명시된 버전보다 같거나 높은버전

whitespace를 사용할 수 있는데 and와 같다고 볼 수 있다. 또한 ||(or)도 같이 쓰일 수 있다.

예시로 확인하자

  • >=1.2.7 <1.3.0
    [major, minor, patch]로 본다면 이 예시는 patch 업데이트만 허용한다.
  • 1.2.7 || >=1.2.9 <2.0.0
    1.2.7 이거나 1.2.9포함 minor과 patch 업데이트 허용

Prerelease Tags

알아야 하는 개념이 또 있다. 정식이 아닌 버전을 pre-release version을 나타내는 Prerelease tag이다.

정식 배포를 앞둔 pre-release version은 PATCH Version 바로 뒤에 붙임표(-)와 마침표(.)로 구분된 식별자를 더해서 표시할 수 있다.
예) 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92.
https://semver.org/lang/ko/

이제 예시를 보자
> 1.2.3-alpha.3

 

[major, minor, patch] 전부 일치할 경우 1.2.3일 경우 prerelease tag도 함께 포함된다.

1.2.3-alpha.4는 포함, 1.2.4도 포함 되지만 1.2.4-alpha.3은 포함되지 않는다.

 

이렇게 되어있는 건 2가지 이유가 있다.

  1. prerelease version은 매우 빠르게 업데이트 되기 때문에,
    public consumption에는 적합하지 않고 많은 변경사항이 포함되어 있기 때문에 range matching에는 제외된다.
  2. user가 prerelease version을 사용하기로 했다면 위험을 인식하고 있다고 볼 수 있기 때문에 [major, minor, patch]가 일치 하는 경우에는 포함하지만,
    다음 prelease version까지는 감수하기로 했다고 할 수 없기 때문에 포함하지 않는다.

고급 범위 지정

  • ~ 사용하는 Hyphen Ranges X.Y.Z - A.B.C
  • x 를 사용하는 X-Ranges 1.2.x 1.X 1.2.*
  • ~를 사용하는 Tilde Ranges ~1.2.3 ~1.2 ~1
  • ^를 사용하는 Caret Ranges ^1.2.3 ^0.2.5 ^0.0.4

 

Hyphen Ranges [ X.Y.Z - A.B.C ]

  • 1.2.3 - 2.3.4
    >=1.2.3 <=2.3.4
    1.2.3과 같거나 커야하며 2.3.4보다 같거나 작어야 한다.
  • 1.2 - 2.3.4
    첫번째 버전에 생략이 있다면 0을 포함시킨다.
    >=1.2.0 <=2.3.4
  • 1.2.3 - 2.3
    두번째 버전에 생략이 있다면 [major, minor] 가 일치하는 경우만 포함
    >=1.2.3 <2.4
  • 1.2.3 - 2
    두번째 버전에 생략이 있다면 2로 시작하는 [major] 가 일치하는 경우만 포함
    >=1.2.3 <3

 

X-Ranges

  • *
    >0.0.0 모든 버전에 충족
  • 1.x
    marjor와 minor level의 업데이트 허용 >=1.0.0 <2.0.0
  • 1.2.x
    patch level의 업데이트 허용 >=1.2.0 <1.3.0

 

Tilde Ranges(~)

minor version이 지정되어 있다면 patch level 변경을 허용한다.
그렇지 않은 경우 minor-level 변경을 허용한다.

  • ~1.2.3
    minor version이 지정되어 있으니 patch level 변경 허용
    >=1.2.3 <1.(2+1).0
    >=1.2.3 <1.3.0
  • ~1.2
    minor version이 지정되어 있으니 patch level 변경 허용 (1.2.x와 같다)
    >=1.2.0 <1.(2+1).0
    >=1.2.0 <1.3.0
  • ~1
    minor version이 지정되어 있지 않기 때문에 minor-level 변경을 허용
    >=1.0.0 <(1+1).0.0
    >=1.0.0 <2.0.0
  • ~3.10.0-alpha.1
    minor version이 지정되어 있으니 patch level 변경 허용
    3.10.0 이 일치하는 prerelease tag도 함께 포함된다.
    >=3.10.0-alpah.1<3.(10+1).0
    >=3.10.0-alpha.1 <3.11.0
    3.10.0-alpha.2는 포함이 되지만, 3.11.0-alpha.2는 포함되지 않는다.

 

Caret Ranges(^)

[major, minor, patch]에서 가장 왼쪽에 있는 0이 아닌 요소는 제외하고 변경 허용
1.0.0 버전이라면 minor와 patch 버전을 업데이트를 허용
0.X 버전이라면 patch 업데이트 허용
0.X.X 버전이라면 업데이트를 허용하지 않는다.

많은 저자들이 0.x 버전에서 x가 “호환성이 손상되는 변경”의 지표로 생각한다.
Caret ranges는 예를 들어 저자가 0.2.4 버전과 0.3.0 버전 사이에 호환성이 손상되는 변경(breaking-change) 업데이트 했을 시의 상황에 사용하는 것이 가장 이상적이다. 실로 이러한 경우는 일상다반사로 일어난다.
그러나 이는 0.2.4 버전과 0.2.5 버전 사이에 호환성이 손상되는 변경이 없을 것이라고 간주한다.
주로 관찰되는 관행에 따르면, 이는 추가적인 (그러나 호환성이 손상되는 변경) 변화로 간주되는 변화를 허용한다는 것이다.

Breaking change 는 호환성이 깨지는 변경이 있다는 의미한다.
보통 Breaking change를 포함한 업데이트를 major로 올리는데,
경우에 따라서는 Breaking change 없이 major를 올리기도 하고,
그냥 프로젝트 관리하는 사람 성향에 따라 Breaking change 없으면 무조건 minor만 올리는 사람도 있고,
Breaking change가 없어도 major를 올리는 사람도 있다.
Open Source 프로젝트들 들어가서 CHANGELOG.md 파일들을 보면 이해가 될 것이다. 

예시로 확인해 보자

  • ^1.2.3
    왼쪽에서 맨 처음 0이 아닌 요소는 major 이기 때문에 minor, patch 업데이트를 허용
    >=1.2.3 < 2.0.0
  • ^0.2.3
    왼쪽에서 맨 처음 0이 아닌 요소가 minor 이기 때문에 patch 업데이트를 허용
    >=0.2.3 <0.3.0
  • ^0.0.3
    왼쪽에서 맨 처음 0이 아닌 요소가 patch이기 때문에 업데이트를 허용하지 않음
  • ^1.2.3-beta.2
    왼쪽에서 맨 처음 0이 아닌 요소가 major 이기 때문에 minor, patch 업데이트를 허용하고
    1.2.3 version 일치하는 경우 prerelease tag도 함께 포함된다.
    >=1.2.3-beta.2 <2.0.0
  • ^0.0.3-beta
    0.0.3의 prerelease만 허용된다. 0.0.3-pr.2는 허용이 된다.

patch 값이 누락되어 있는 경우

0으로 표기하지만, major와 minor version 둘 다 0인 경우 해당 값 내에서 유연성이 허용된다.

  • ^1.2.x
    0이 아닌 맨 처음 요소가 major이고 0으로 채워진다.
    >=1.2.0 <2.0.0
  • ^0.0.x
    major와 minor 둘 다 0 이기 때문에 해당값 내에서 유연성 허용
    >=0.0.0 <0.1.0
  • ^0.0
    major와 minor 둘 다 0 이기 때문에 해당값 내에서 유연성 허용
    >=0.0.0 <0.1.0

 

설명과 예시를 봐도 헷갈린다면 

https://semver.npmjs.com/

 

npm semantic version calculator

use the caret (aka hat) symbol, ^ examples: ^2.2.1 ^0.1.0 ^0.0.3 caret behavior is different for 0.x versions, for which it will only match patch versions.

semver.npmjs.com

 

해당 사이트에 들어가서 직접 버전을 검색해보면서 이해하면 될것같다.

 

참조

https://velog.io/@slaslaya/npm-semver-%ED%8B%B8%ED%8A%B8-%EB%B2%94%EC%9C%84%EC%99%80-%EC%BA%90%EB%9F%BF-%EB%B2%94%EC%9C%84

 

npm semver - 틸트 범위(~)와 캐럿 범위(^)

드디어 package.json에서 많이 보았던 캐럿 ^ 까지 왔다.minor version이 지정되어 있다면 patch level 변경을 허용한다.그렇지 않은 경우 minor-level 변경을 허용한다.~1.2.3minor version이 지정되어 있으니 patch l

velog.io