첫 TIL(Today I Learned) 작성입니다.
프론트엔드 과정 첫 수업을 대략 금일 오전 1시쯤에 수강하였습니다. 이번 과정에서 평소에 React를 개발하면서 당연하게 여겼던 기능에 대해 다시 한 번 생각하고 배울 수 있게 되었습니다. 처음 프론트엔드를 공부할 때, HTML, CSS, JavaScript로 웹을 만들어보신 경험이 다들 있으실텐데요.
처음에 코드 변경에 따라 새로고침(F5) 이벤트가 발생해 변경 사항이 반영되었습니다. 이는 VSCode의 ’liveserver’라는 extension을 사용해서 개발 편의성을 늘리는 방식으로 많이 사용되고 있고, 저도 자주 사용한 extension이었어요.
하지만 React에서는 liveserver 없이도 개발 도중 변경 사항이 리다이렉트되지 않고, 즉시 변경 사항이 반영이 됐는데, 이는 ’Vite’라는 번들러의 HMR(Hot Module Replacement)라는 기능 때문입니다.
오늘은 앞서 말씀드렸다시피 당연하게 쓰고있던 기능인 HMR에 대해 말씀드리고자 합니다.
HMR이란? : 변경된 코드 조각만 런타임에서 동적으로 교체하는 기능을 HMR이라고 합니다.HMR이 적용되어 있다면 페이지를 새로고침하지 않고도 코드 수정 사항이 즉시 반영이 되기 때문에 개발 환경을 매우 편리하게 가져갈 수 있는 기능입니다.
’가장 큰 장점은 상태를 유지하면서도 코드 변경을 감지하고 반영한다.’인데요, liveserver를 사용했을 때의 전체 페이지를 새로고침하면 폼 입력값이나 UI 상태가 초기화되어 불편했던 경험 즉, 새로고침 했던 경험 없이 변경 확인이 가능하다는 장점이 있습니다.
이번 프론트엔드 과정에서는 ‘Vite’ 번들러를 활용해서 npm create vite@latest라는 명령어로 React의 프로젝트를 생성하고 있는데요,
HMR은 번들러에 따라 구현 방식이 다양합니다.
하나씩 소개해드리자면,
-
*Vite: 네이티브 ESM을 활용한 HMR 방식입니다. -
모던 번들러 중 하나인 Vite는 브라우저의 네이티브 ESM을 최대한 활용해, 불필요한 런타임 로직 없이 HMR을 구현합니다.
-
변경된 모듈의 URL에 타임 스탬프를 추가해 브라우저 캐시를 무효화합니다.
-
필요한 모듈만 다시 불러오기 때문에 빠르고 간단하게 HMR이 동작합니다.
-
예를 들어 foo.ts 파일을 변경하면 import 경로 뒤에 타임 스탬프가 붙어 새로운 모듈로 로드됩니다.
tsimport { foo } from "./foo.ts?t=1708957319787"; -
Metro: React Native 기본 번들러입니다.- 모듈을 전역에 등록한 뒤, 변경된 모듈만 교체하는 방식
- 코드가 변경되면, 해당 모듈의 고유 ID를 찾아 업데이트
- 변경된 부분만 새로운 코드로 교체
__d라는 함수를 사용해서 각 모듈에 고유한 ID를 부여하고, 이 ID를 이용해 런타임에서 모듈을 참조할 수 있도록 합니다. 즉, 모듈이 런타임에서 교체 가능한 상태로 등록됩니다.
-
Webpack: 전통적인 HMR 방식입니다.- 런타임에 모듈을 등록한 뒤 관리하는 구조
(__webpack_modules__)를 활용하여 변경된 모듈만 교체- 변경된 모듈을 감지하면, 서버가 새로운 코드 조각을 생성합니다.
- 클라이언트에서 기존 모듈을 대체하는 방식으로 업데이트합니다.
- 의존성 그래프를 추적하여 변경된 모듈을 참조하는 모든 상위 모듈도 갱신됩니다.
예외로 ESBuild: 초고속 번들링을 목표로 개발된 번들러입니다. HMR은 없습니다.
이렇게 다양한 번들러에 따라 HMR을 구현하는 방식이 다릅니다. 이번 글로 React를 Vite 번들러로 개발하시는 분들에게 좋은 정보가 되었으면 좋겠습니다.
추가로 ESBuild 는 기본적으로 HMR이 구현되어있지 않습니다. 하지만 ’토스’에서는 초고속 번들링이 가능한 ESBuild를 선택한 대신 HMR을 Rust언어와 직접 구현한 블로그 글이 있는데요, 저도 HMR을 따로 보면서 많은 도움이 됐는데, 다른 분들도 인사이트 얻어가셨으면 좋을 것 같아서 올려봅니다.
프론트엔드 개발 경험을 향상시키는 HMR(Hot Module Replacement)의 원리와 다양한 번들러가 HMR을 어떻게 지원하는지 살펴보고, ESBuild 기반 번들러를 직접 개발한 과정을 소개드려요.
- #배움일기