회사에서 tilde와 caret 버전 관련 이슈가 터졌었다.
정말 끔찍했었는데... 어떤 문제였는지 알아보고, 틸드와 캐럿 중에 어떤 걸 써야 하는 지도 살펴보자!
어떤 이슈였나?
금요일에 QA를 무사히 마치고 다음주 월요일에 배포했다.
그런데 갑자기 form 에서 submit을 할 때 validation check 하는 부분에서 버그가 발생하며 submit이 되지 않았다. 실제로 validation 문제는 없었는데도 말이다.
그래서 멘붕왔고 롤백했다...
원인은 무엇이었나?
form에서 submit 할 때 문제가 발생했으니, 해당 외부 라이브러리의 버전을 낮추니 해결되었다.
자세히 설명하자면
금요일 QA가 끝났을 때는 서버에 있던 버전에서는 문제가 없었는데
월요일에 배포할 때는 주말 동안 해당 라이브러리의 버전이 업데이트되었다.
package.json 에 해당 라이브러리 버전은 ^ 으로 관리되고 있었고 (ex ^1.2.3)
마이너 업데이트라 배포할 때는 반영되었다.
마이너 업데이트는 기존 코드에 영향이 없어야 했는데 해당 외부 라이브러리의 실수로 이 문제가 발생했다.
해결 방법은?
배포할 때 package.json 에 caret(^)을 tilde(~)로 바꿔서 해결했다. (ex ^1.2.3 이었다면 1.2.9 로)
버전은 major.minor.patch 순서인데 ^보다 ~를 사용하면 좀 더 보수적으로 최신 버전을 사용할 수 있다.
이번에 발생한 문제도 예방할 수 있다.
그럼 모든 버전을 tilde(~)로 사용하면 되는 것일까?
그렇지 않다.
아래 아티클의 글을 참고해 정리해 보겠다.
https://nodesource.com/blog/semver-tilde-and-caret/
처음에 tilde가 기본이었다
처음 package.json의 semver(Semantic Versioning)에서는 2년 6개월 동안 tilde (~)가 기본값이었다. npm install 을 실행하면 아래처럼 package.json에 기록된다.
"dependencies": {
"qs": "~2.2.3"
}
tilde (~) 가 있을 경우, patch는 최신 버전을 허용한다. 예를 들어 위의 예시는 2.2.9는 허용하되 2.3.0은 허용하지 않는다.
patch 업데이트의 경우는 기능적으로 이전 버전과 호환되고, 대부분의 유저들이 인지하지 못하는 버그를 해결한다.
새로운 Range Specifier 에 대한 필요성
semver에 따르면 minor 버전은 업데이트되어도 기능적으로 이전 버전과 호환이 가능하다.
예를 들어 내가 1.2.3 버전으로 개발했더라도 1.9.9 버전을 설치해서 실행해도 문제없다.
1.2.3 대비 1.9.9 버전은 훨씬 더 많은 버그들이 해결되었을 것이다.
기능적으로 문제없는데 버그가 더 적은 1.9.9 버전으로 배포하는 것이 이득이다.
semver에는 이에 대한 규칙이 없었고, 이에 대한 필요성이 생겨 minor 최신 버전까지 쓸 수 있는 caret(^) 이 생기게 되었다.
단, 여기서 주의해야 할 점은 라이브러리 개발자가 "minor 버전은 이전 버전과 완벽하게 호환한다"라는 규칙을 철저하게 지켜야 한다.
내가 겪었던 이슈는 이를 못 지켜서 발생한 것이었다.
Tilde와 Caret 의 차이
Tilde는 Patch 에 대해 유동적이다
예를 들어 ~1.2.3 인 경우 다음 마이너 버전인 1.3.0 미만인 버전을 허용한다 (ex 1.2.9)
Caret은 Minor와 Patch에 대해 유동적이다.
예를 들어 ^1.2.3 인 경우 2.0.0 미만인 버전을 허용한다 (ex 1.2.9 , 1.5.1)
그리고 major가 0인 경우는 특이하게 적용된다.
^0.0.Z -> 0.0.Z (ex ^0.0.3 인 경우는 0.0.3만 허용된다)
^0.Y.Z -> 0.Y.Z - 0.(Y+1).0 (ex ^0.1.3인 경우 0.2.0 미만 버전 모두 허용된다)
major 0 인 경우는 초기 개발하는 단계라 언제든 어떤 것이든 바뀔 수 있기 때문에 이렇게 예외적인 경우로 정했다고 한다.
그런데 이게 복잡해서 1.0.0으로 시작하는 것을 추천한다.
major 0 인 경우에 대해서 실제로 어떻게 동작하는 지 알고 싶다면
node-semver 를 사용하면 된다.
https://github.com/npm/node-semver
var semver = require('semver')
semver.toComparators('~1.2.3')
// [ [ '>=1.2.3-0', '<1.3.0-0' ] ]
semver.satisfies('0.0.4', '^0.0.3')
// false
version range 를 어떻게 작성하면 실제로 어떤 버전이 사용 가능한 지 알려주는 곳도 있다.
혹시 semver에 대해서 더 궁금하다면 아래 링크로!
결론: Caret이 새로운 표준이다.
semver 규칙에 의하면 minor 는 기존 버전과 기능적으로 호환이 되기 때문에
더 버그가 많이 해결된 caret(^) 을 쓰는게 이득이고, 현재 표준이다.
(단, 외부 라이브러리가 semver 규칙을 어긴다면, 즉 minor 업데이트 했을 때 이전 버전과의 호환 문제가 있다면 버그가 발생할 수 있다.)
npm 1.4.3 버전부터 caret 이 표준이 되었다.
npm install --save, npm install --save-dev 등을 하면 caret 으로 버전 관리를 한다.
그렇다면 내가 겪었던 이슈는 어떻게 잡아야 하는 것이냐
모든 버전을 tilde 로 바꾸는 건 아니고
결국엔 배포 전에 테스트 코드를 도입해야 해결할 수 있을 것 같다.
'dev' 카테고리의 다른 글
jest 라이브러리 import 문제 해결 방법 (SyntaxError: Unexpected token 'export') (0) | 2023.08.13 |
---|---|
Reactive Native Webview 의 장단점 (0) | 2023.07.19 |
2023년 상반기 주류 이커머스 스타트업 프론트엔드 개발 회고 (0) | 2023.06.13 |
사용자 스토리 맵 만들기 책 후기 - 스타트업에서 애자일 도입하기 (0) | 2023.06.07 |
AWS 한국 사용자 모임 - 프론트엔드 Next.js 이미지 최적화 소모임 후기 (0) | 2023.05.14 |
댓글