버저닝(Versioning)과 캐럿(Caret), 그리고 의존성 버저닝의 함정

2025. 9. 28. 15:04·Frontend
반응형

가끔씩 같은 로직인데 프로젝트에서는 되고 내꺼에서는 안되는 일이 있습니다. 

심지어 코드를 그대로 복붙해와서 모든게 똑같다고 해도 말이죠

 

이런 상황이 왜 발생할까요? 답은 버저닝(Versioning)과 캐럿(^), 그리고 우리가 잘 보지 못하는 의존성 버저닝에 있습니다.

 


버저닝의 기본: 시맨틱 버저닝(SemVer)

대부분의 오픈소스 패키지는 시맨틱 버저닝(SemVer) 이라는 규칙을 따릅니다.


형식은 다음과 같습니다.

MAJOR.MINOR.PATCH
  • MAJOR (주버전): 기존과 호환되지 않는 큰 변경
    • 예: API 구조가 바뀌어 기존 코드가 깨짐
  • MINOR (부버전): 기존과 호환되는 기능 추가
    • 예: 새로운 옵션이나 컴포넌트가 추가
  • PATCH (수정버전): 버그 수정이나 작은 개선
    • 예: 스타일 깨짐 수정, 크래시 버그 패치

 

 

예를 들어, 2.3.1은

  • 2 → 큰 틀(major 버전)
  • 3 → 새로운 기능 추가(minor 버전)
  • 1 → 버그 수정(patch 버전)

 

이라는 의미를 갖습니다.

이 규칙 덕분에 우리는 버전 번호만 보고도 “이 업데이트가 위험할지, 단순 수정일지”를 가늠할 수 있습니다.

 

 

 

요런 농담도 있는데요

매우 인정합니다. 

 

 

 

 


캐럿(^)이란 무엇인가?

 

package.json을 열어보면 이런 식으로 버전 앞에 기호가 붙어 있는 걸 자주 봅니다.

"my-library": "^1.2.3"

 

여기서 ^(캐럿)은 “호환되는 최신 버전을 자동으로 허용”하겠다는 의미입니다.

 

캐럿의 동작 규칙

  • ^1.2.3 → >=1.2.3 <2.0.0
    (메이저 버전이 바뀌지 않는 범위 내에서 최신 버전 허용)
  • ^0.2.1 → >=0.2.1 <0.3.0
    (메이저가 0일 때는 보수적으로, 마이너까지만 허용)
  • ^0.0.3 → =0.0.3
    (패치 버전 고정)

 

즉, 메이저 버전이 1 이상인 안정적인 라이브러리라면 캐럿을 사용해도 대부분 안전합니다.
하지만 0.x 버전대 라이브러리는 아직 불안정하기 때문에, 캐럿을 쓰면 위험할 수 있습니다.

 

 


하지만 이 버전 믿어도 될까? : “툴팁 Provider 사건”

그런데 어느 날 이런 문제가 발생했습니다. 대략 예시를 들어보겠습니다. 


나는 ui-tooltips라는 라이브러리를 사용 중이었고, ^0.2.1로 설치해 두었습니다. (이런 라이브러리는 없습니다. 제가 가상으로 만든 겁니다. )

 

 

그런데 어느 날 갑자기 앱이 이렇게 크래시했습니다.

 

Error: InvalidContextUsage: Tooltip은 Provider 하위에서 사용해야 합니다

 

원인을 추적해보니…

  • 0.2.1에서는 그냥 <Tooltip />을 쓰면 잘 동작했는데,
  • 0.2.11에서 Provider를 반드시 감싸야 하는 규칙이 추가됐던 겁니다.

 

즉, 이렇게 바뀐 거죠.

// 예전(0.2.1)에는 그냥 됨
<Tooltip text="Hello" />

// 새 버전(0.2.11)부터는 이렇게 안 하면 에러
<TooltipProvider>
  <Tooltip text="Hello" />
</TooltipProvider>

 

문제는 이 변화가 Patch 버전(0.2.11) 에 들어갔다는 것입니다.


시맨틱 버저닝 원칙상 호환성이 깨지는 변경은 Major나 최소한 Minor 버전에 들어가야 하는데, Patch로 들어가 버린 것이죠.

결과적으로, 내가 ^0.2.1을 쓰고 있었기 때문에 자동으로 0.2.11이 설치되었고, 예기치 못한 에러를 맞이하게 된 겁니다.

 

근데 만약 이 라이브러리가 제가 고칠 수 있는 것이 아니라면?

해결 방법은 단순합니다. 캐럿을 제거하고 버전을 고정하는 것이죠. (더 좋은 해결법은 아무래도 이런 일이 발생하면 안되는..)

"ui-tooltips": "0.2.1"

 

이렇게 하면 항상 동일한 버전을 쓰게 되어 안정성을 확보할 수 있습니다.

 


의존성 버저닝의 함정

문제는 내가 직접 설치한 라이브러리만 신경 쓴다고 끝이 아니라는 데 있습니다.


대부분의 라이브러리는 또 다른 라이브러리에 의존합니다. 즉, 의존성의 의존성(transitive dependency)이 존재합니다.

 

예를 들어, 내가 설치한 건 `abc` 라는 라이브러리인데, 실제로는 내부에서 `a` 라는 다른 라이브러리를 사용하고 있다고 합시다.
이 경우 `a`의 버저닝 정책에 문제가 있으면, 내가 직접 설치하지도 않은 코드 때문에 내 앱이 깨질 수 있습니다.

 


의존성 버전 확인 방법

 

이런 문제를 예방하려면 내 프로젝트에 어떤 버전의 라이브러리가 설치되어 있는지 확인하는 습관이 필요합니다.

 

npm 

npm ls abc

 

yarn

yarn why abc

 

pnpm 

pnpm why abc

 

 

 

이 명령어들을 통해 “이 라이브러리가 어떤 버전의 패키지들을 끌고 왔는지” 확인할 수 있습니다 ! 

만약 내가 가진 라이브러리 버전과 동일한데도 에러가 터진다면 요 라이브러리가 의존하는 다른 라이브러리가 문제가 될 수도 있는거죠 !! 

 


교훈

이 사례는 제가 실제 최근 디버깅한 사례에서 따왔습니다.. 

평소 install 만하고 버전은 크게 신경쓰지 못했던 저에게 큰 러닝을 주었던 + 야근을 주었던 사례였습니다. 

 

 

  • Patch라고 무조건 안전하지 않다. (나도 실수할 수 있음. 잘 확인해야한다 !) 
  • 특히 0.x 버전대 라이브러리는 캐럿(^)을 쓰면 위험 → 버전 고정 권장
  • 내가 직접 설치한 라이브러리뿐만 아니라, 그 라이브러리가 의존하는 서브 디펜던시까지 버저닝 리스크가 있다

 

언제나 믿었던 숫자도 휴먼에러를 가진 숫자일 수도 있습니다. 사람은 늘 실수를 하기 때문이죠 

그래서 이번 기회로 버전 번호를 믿괴, 항상 확인하고 검증해보려는 러닝을 갖게 되었습니다 !! 

 

끗 ! 

반응형

'Frontend' 카테고리의 다른 글

Next.js에서 Google Form API 사용해서 데이터 수집하기  (3) 2025.08.31
'Frontend' 카테고리의 다른 글
  • Next.js에서 Google Form API 사용해서 데이터 수집하기
healim01
healim01
    반응형
  • healim01
    Hailey Daily
    healim01
  • 전체
    오늘
    어제
  • 블로그 메뉴

    • 전체
    • 나의 성장기록
    • 우테코
    • Frontend
    • SOLVED.
    • 개발자의 워크스페이스
    • Every Year Every Month
    • 글쓰기
  • 링크

    • Github
  • 인기 글

  • hELLO· Designed By정상우.v4.10.2
healim01
버저닝(Versioning)과 캐럿(Caret), 그리고 의존성 버저닝의 함정
상단으로

티스토리툴바