이때 version에 대한 정보를 표시하는 방식이 여러 가지가 존재한다. 특히 범위를 지정할 수 있는 부분이 독특하다.
1.2.3 : 정확히 버전을 지정한다.
>1.2.3, >=1.2.3, <1.2.3, <=1.2.3: 저정한 버전보다 미만, 이하, 초과, 이상 이어야 한다.
1.2.x: 맨 뒤 자리만 변경 가능하다. 1.2.3이나 1.2.4는 괜찮지만 1.3.0은 불가
*: 상관 없음
~1.2.3: Approximately equivalent to version(버전과 거의 동일)
^1.2.3: Compatible with version(버전과 호환 가능)
이중 ~(tilde range)와 ^(caret range)에 대해 좀 더 알아보자.
~(tilde ranges)
~는 Approximately equivalent to version 즉 버전과 거의 동일하면 된다는건데 매우 애매한 표현이다. tield range는 minor 버전이 명시된 경우 patch-level의 변경이 가능하다. 그렇지 않은 경우는 minor-level의 변경이 가능하다.
간단히 여러가지 상황에서의 예를 살펴보자.
표현
범위
설명
~1.2.3
1.2.3<=version <1.3.0
minor 버전있음. 패치 버전만 3~9까지 변경 가능
~1.2
1.2.0<=version <1.3.0-0 (1.2.x와 동일)
minor 버전 있음. 패치 버전만 0~9까지 변경 가능
~1
1.0.0<=version <2.0.0-0 (1.x와 동일)
minor 버전 없음. minor 버전만 0~9까지 변경 가능
참고로 공식 문서에는 ~1.2.3 := >=1.2.3 <1.(2+1).0 := >=1.2.3 <1.3.0-0 이런 식으로 표현된다. 개인적으로 헷갈려서 수학시간에 하던것처럼 바꿔보았다. ㅎ
^(caret ranges)
^은 npm install 명령으로 라이브러리를 설치할 때 기본으로 적용되는 방식으로 호환성이 유지된다면 버전 변경이 가능하다. 따라서 주어진 버전 이상에서 minor 버전이나 patch 버전에 대해서 버전 변경이 가능하다.
역시 간단히 여러 상황의 예를 살펴보자.
표현
범위
설명
^1.2.3
1.2.3<=version <2.0
minor와 patch 변경 가능
^1.2
1.2.0<=version <2.0
minor와 patch 변경 가능
^1
1.0.0<=version <2.0
minor와 patch 변경 가능
~에 비해 훨씬 간단한데 예외 상황이 있다.
특히 개발 초창기에는 설계가 변경될 수 있기 때문에 버전에 대한 변화가 심하다. 이런 버전은 아마도 1.0.0 미만으로 아직 release 되기 이전 즉 pre-release 상태일 것이다. 따라서 0.1과 0.2는 호환되지 않을 가능성이 높다.
따라서 이런 pre-lease 상태에서는 ~와 동일하게 동작한다.
표현
범위
설명
^0.2.3
0.2.3<=version <0.3.0
pre-release 상황, minor 버전 있음, patch만 3~9까지 허용
^0.2
0.2.0<=version <0.3.0
pre-release 상황, minor 버전 있음, patch만 0~9까지 허용
^0
0.0.0<=version <1.0
pre-release 상황, minor 버전 없음, minor만 0~9까지 허용
개인적인 생각으로 ~보다 ^이 합리적이지 않을까 한다. 하위 호환성이 중요하지.
왜 버전을 범위로 지정할까?
이제까지 ~와 ^의 차이점에 대해서 설명했는데 이런 궁금증도 생길것 같다. 왜 버전을 지정하지 않을까? 애초에 version을 1.2.3이라고 콕 지정하기 않고 범위를 주는 이유가 문득 궁금하다면 SW는 생물(生物)이기 때문이다. (원래 정치는 생물인데 ㅎ)
특정 라이브러리를 사용해서 개발을 하는 과정에 그 라이브러리 개발자도 열심히 개발을 하고 있고 버그는 꾸준히 패치되고 있다. 1.2.3 버전을 쓰고 있는 상황에서 심각한 버그가 발견되서 1.2.4로 패치되었다고 생각해보자. 나에게 메일로 알려줄 리는 만무하고 이런 상황에서 범위로 지정되어있다면 특별히 신경쓰지 않더라도 패치된 라이브러리를 사용할 수 있을 것이다.