FE
[코알라] 골칫거리 moment를 간단하게 대체하는 Day.js
2023.11.13
•
10 min read
안녕하세요, 코멘토 프론트엔드 개발자 윤종석입니다. 코멘토 개발팀에서 어떤 라이브러리를 쓰는지 공유하는 '코알라(코멘토와 알아보는 라이브러리)' 시리즈입니다. 첫 번째 글은 FE팀에서 사용하는 Day.js 라이브러리를 소개해드리려고 합니다.
FE에서 시간 다루기
Javascript에는 시간과 날짜를 다루는 Date라는 내장 객체가 있습니다. 그렇지만 개발하면서 만나는 다양한 요구사항에 맞춰 사용하기 쉽지 않은 객체라서 처음에 쓰게 되면 당황할 일이 자주 생깁니다.
Javascript의 차기 표준을 정하는 TC39에서도 Date의 문제점을 해결하기 위해 Temporal이라는 새로운 내장 객체를 도입하는 논의를 진행하고 있습니다. Temporal 도입을 논의하는 문서에서 TC39는 Date 객체를 두고 'ECMAScript의 고질적인 문제점(Date
has been a long-standing pain point in ECMAScript)'이라고 표현했습니다.
Moment의 유행과 퇴장
Moment 라이브러리가 2011년에 등장합니다. Date 객체보다 훨씬 간편하게 시간/날짜를 다룰 수 있는 라이브러리였습니다. 나오자마자 인기를 얻은 이 라이브러리는 2020년 9월 기준 무려 일주일에 1,200만의 다운로드 수가 기록됩니다.
코멘토 역시 Moment를 시간 및 날짜 관리를 위해 사용하고 있었습니다. 하지만 2020년 9월, Moment 팀은 라이브러리를 더 이상 개발하지 않고 유지보수만 한다는 선언을 합니다.
We now generally consider Moment to be a legacy project in maintenance mode. It is not dead, but it is indeed done.
Moment는 중단 시점 기준 10년 가까이 된 라이브러리였고 핵심 코드 역시 그만큼 오래되었습니다. 웹 개발의 새로운 흐름에 맞춰서 구조를 바꾸기는 개발팀에게 굉장히 큰 일이었습니다. 구조가 오래되고 여러 기능이 붙다보니 라이브러리의 스크립트 용량도 커졌습니다. 이런 이유로 Moment 팀은 개발 중단을 선언합니다.
4개의 후보
Moment 팀은 개발 중단 안내와 함께 4개의 라이브러리를 대안으로 소개했습니다. date-fns, Day.js, js-joda, Luxon인데요. 당시 코멘토 프론트엔드 팀 Moment팀이 소개한 라이브러리를 일단 후보로 두고 고민을 시작했습니다. 각각 써보면서 어떤 라이브러리가 가장 쓰기 편하고 옮기기 편할지 테스트도 해봤고요.
참고로 잘 정리했다는 글의 링크는 바로 You-Don't-Need-Momentjs입니다. 대안을 고민하시는 분은 링크의 글을 참고하시면 큰 도움이 되실 겁니다.
Day.js를 선택한 이유
저희 팀은 이미 처음에 말씀드렸듯이 Day.js를 대안으로 선택했습니다. 기존에 moment를 쓰던 상황에서 Day.js를 선택한 이유는 어떤 것이었을까요?
편한 전환 과정
이미 Moment를 사용 중이라면, Moment에서 전환하기 가장 쉽다는 것이 Day.js의 큰 강점입니다. Day.js는 처음부터 Moment와 같은 API를 구현하는 것이 목적이었기 때문에 Moment를 사용하는 방법 그대로 Day.js를 사용할 수 있습니다.
라이브러리를 아예 교체해야 하는 상황에서 이 정도로 교체 작업이 끝난다는 것은 굉장히 큰 강점이었습니다. 기존 코드를 그대로 사용할 수 있는 것은 물론이고 새로운 API를 배워야 하는 부담도 훨씬 줄어들기 때문이죠. 여전히 높은 Moment의 사용률을 고려하면 다른 라이브러리에 비해 Day.js가 크게 앞서는 부분입니다.
적은 용량과 충분한 성능
Day.js의 용량은 보시다시피 굉장히 적은 편입니다. 특히 대체하는 Moment와 비교하면 1/10 미만으로 줄어든 것을 볼 수 있습니다. 다른 경쟁 라이브러리와 비교해도 적은 편이죠. 라이브러리의 크기가 작으면 서비스의 JS 크기도 줄어들고 그만큼 사용자의 경험도 개선됩니다.
라이브러리 | 실행 시간 |
---|---|
Moment | 1078.948ms |
date-fns | 398.107ms |
Day.js | 765.358ms |
Luxon | 2306.765ms |
위의 예시 코드를 실행하는데 걸린 시간을 비교한 표입니다. (출처: 링크) 성능에서 가장 좋은 모습을 보이는 date-fns만큼은 아니지만 Moment보다는 좋은 성능을 보여주는 것을 볼 수 있습니다. 시간 관련 작업은 저희 서비스에서는 아주 중요한 부분은 아니기 때문에 사용하기 충분한 성능이라고 판단했습니다.
실제 전환 과정
간단한 전환이 Day.js의 장점이지만 실제 서비스인만큼 어떤 오류가 발생할지 알 수 없기 때문에 조심스럽게 접근했습니다. 우선 Day.js를 설치하고 Moment와 같이 사용을 했고 개발 중에 새롭게 시간 작업이 필요할 때 Day.js를 사용해서 작업하고, 기존에 Moment를 사용한 코드를 만날 때마다 Day.js로 변환하는 방식으로 점점 Day.js의 비중을 늘려나갔습니다. 이런 식으로 해서 지금은 메인 프로젝트에서는 Moment를 쓰는 코드가 완전히 사라진 상황입니다. 🎉🎉
의존성도 끊임없이 발전시켜야 한다
직접 작성하는 코드뿐만 아니라 의존하는 외부 라이브러리 역시 끊임없이 변화합니다. 오늘 다룬 Moment처럼 아예 개발이 중단되기도 하고, 새로운 버전이 이전 버전과 완벽하게 호환되지 않는 경우도 있습니다. 생각지도 못한 보안 문제가 발견되는 경우도 있고요. 서비스 중인 제품의 의존성을 쉽게 바꿀 수는 없겠지만 방치해두면 언젠가는 제품의 발목을 잡게 되는 일이 생길 수 있습니다. 이번 글이 라이브러리를 바꾸거나 버전을 올리려고 하는 분들에게 참고가 될 수 있으면 좋겠습니다.
위의 그래프에서 보다시피 아직도 Moment의 사용률은 높습니다. 기존 프로젝트를 설치하는 경우도 있을 것이고 오랜 세월 다양한 곳에서 쓰이다 보니 블로그나 강의에서 사용해서 그걸 따라 설치하는 경우도 많다고 생각합니다. 하지만 새로운 환경에서 시작할 때는 한 번쯤 라이브러리의 개발 현황을 살펴보고 최대한 오래 지원받을 수 있는 환경에서 시작하는 것을 생각해보면 좋겠습니다.