본문 바로가기
Vite

4. Vite의 주요 특징 - 2

by leo2114 2024. 10. 19.
반응형

모듈 기반 핫 모듈 교체 (HMR)

Vite의 또 다른 강력한 기능 중 하나는 **모듈 기반 핫 모듈 교체(Hot Module Replacement, HMR)**입니다. HMR은 개발 중 코드 변경 사항을 실시간으로 반영하여, 페이지를 다시 로드하지 않고도 즉각적으로 UI가 업데이트되는 기술입니다. 기존 번들러에서도 HMR을 지원하지만, Vite는 **ES 모듈 시스템(ESM)**을 기반으로 하여 기존 방식보다 훨씬 빠르고 효율적으로 동작합니다.

1. 전통적인 HMR과 Vite의 차이

기존 번들러(Webpack 등)에서 HMR은 번들 단위로 동작했습니다. 파일을 수정하면 해당 파일과 관련된 모든 모듈이 다시 컴파일되고, 그에 따라 전체 애플리케이션의 상태를 유지하면서 변경된 부분만 업데이트하려는 복잡한 로직이 필요했습니다. 이 과정은 느리고, 때로는 페이지 전체를 새로고침해야 하는 경우도 있었습니다.

반면, Vite는 모듈 단위로 HMR을 처리합니다. 파일을 수정하면 해당 파일만 다시 로드되고, 다른 모듈에 영향을 주지 않기 때문에, 전체 애플리케이션을 다시 컴파일할 필요가 없습니다. Vite는 네이티브 ES 모듈을 기반으로 하여 브라우저가 직접 모듈을 처리하기 때문에, 매우 빠르고 가벼운 HMR 경험을 제공합니다.

2. Vite의 모듈 기반 HMR 동작 방식

Vite에서 HMR이 작동하는 방식은 브라우저와 개발 서버 간의 양방향 통신에 의해 이루어집니다. 개발 중에 파일을 수정하면 Vite 개발 서버는 WebSocket을 통해 브라우저에 알림을 보냅니다. 브라우저는 해당 파일만 다시 요청하고, 변경된 모듈을 교체합니다. 이 과정은 매우 빠르고, 불필요한 전체 애플리케이션 재로딩 없이 특정 모듈만 교체됩니다.

Vite에서 HMR 동작 예시

<!-- src/components/Counter.vue -->
<template>
  <div>
    <h1>{{ count }}</h1>
    <button @click="increment">Increment</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';

const count = ref(0);

const increment = () => {
  count.value++;
};
</script>

위의 간단한 Vue 컴포넌트 Counter.vue에서, increment 함수를 수정하는 경우를 가정해 보겠습니다. 기존 번들러에서 HMR은 이 파일과 관련된 모든 모듈을 다시 컴파일한 뒤, 해당 부분만 교체하려고 했기 때문에 시간이 걸리거나, 상태가 제대로 유지되지 않는 경우가 많았습니다.

하지만 Vite에서는 HMR이 모듈 단위로 동작합니다. increment 함수가 수정되면, Vite 개발 서버는 해당 파일만 새로 로드하고 나머지 부분은 그대로 둡니다. count 상태도 그대로 유지되며, 즉시 반영되는 UI 변경을 확인할 수 있습니다.

3. 모듈 그래프(Module Graph)

Vite는 HMR을 처리할 때 **모듈 그래프(Module Graph)**를 활용합니다. 모듈 그래프는 각 모듈 간의 의존성 관계를 나타내는 구조로, 모듈이 다른 모듈을 참조하는 관계를 그래프 형태로 관리합니다. Vite는 이 그래프를 기반으로 변경된 모듈과 그 모듈이 의존하는 다른 모듈만 갱신합니다.

모듈 그래프 예시

src/
├── main.js   # Entry point
├── App.vue   # Root component
└── components/
    └── Counter.vue # Child component

위 구조에서 Counter.vue 파일이 수정되면, Vite는 모듈 그래프에서 이 파일의 의존 관계를 추적하여, 오직 이 모듈만 교체합니다. 만약 Counter.vue에서 main.js에 의존하지 않는다면 main.js는 갱신되지 않으며, 애플리케이션의 다른 부분도 영향을 받지 않습니다.

이러한 방식 덕분에 Vite의 HMR은 매우 빠르게 작동하며, 불필요한 리소스 재로드를 피할 수 있습니다.

4. 브라우저와 Vite 서버 간의 HMR 통신

HMR의 핵심은 브라우저와 개발 서버 간의 양방향 통신입니다. Vite는 WebSocket 연결을 통해 브라우저와 통신하며, 코드가 변경되면 브라우저에 변경 사항을 알리고, 브라우저는 해당 모듈만 새로 요청하여 교체합니다.

// Vite의 WebSocket 연결 방식 예시
import { createWebSocketServer } from 'vite';

const ws = createWebSocketServer({
  server, // HTTP 서버 연결
  port: 3000,
});

ws.on('message', (msg) => {
  if (msg.type === 'hot-reload') {
    console.log('Module updated: ', msg.file);
    // 해당 모듈을 교체
    replaceModule(msg.file);
  }
});

Vite는 위와 같은 방식으로 WebSocket을 사용하여 HMR 업데이트를 처리합니다. 코드가 변경될 때마다 브라우저는 서버로부터 알림을 받고, 변경된 파일을 다시 가져옵니다. 이 과정에서 전체 페이지가 다시 로드되지 않고, 오직 수정된 모듈만 빠르게 교체됩니다.

5. Vue와 React에서의 HMR

Vite는 Vue와 React와 같은 모던 프레임워크에서 HMR을 원활하게 지원합니다. Vue 컴포넌트의 경우, 템플릿, 스타일, 스크립트가 각각의 모듈로 분리되어 관리되므로, 특정 부분이 변경되면 해당 부분만 HMR로 교체됩니다.

Vue에서의 HMR

<!-- src/components/HelloWorld.vue -->
<template>
  <div>
    <p>{{ message }}</p>
    <button @click="changeMessage">Change Message</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';

const message = ref('Hello World!');

const changeMessage = () => {
  message.value = 'Message Changed!';
};
</script>

이 Vue 컴포넌트에서 message 값을 변경하는 함수만 수정할 경우, Vite는 템플릿과 스타일에는 아무런 영향을 주지 않고 오직 스크립트 부분만 교체합니다. 또한, 컴포넌트의 상태(message 값)는 유지되므로, 사용자 경험이 끊기지 않고 이어집니다.

React에서의 HMR

React에서도 마찬가지로 Vite는 HMR을 매우 빠르게 처리합니다. React의 함수형 컴포넌트는 그 자체가 모듈로 동작하므로, 특정 컴포넌트만 교체하면 전체 상태나 트리 구조에는 영향이 없습니다.

// src/components/MyComponent.jsx
import { useState } from 'react';

function MyComponent() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>{count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

export default MyComponent;

이 예시에서 MyComponent의 상태는 유지되며, 오직 코드의 변경된 부분만 React의 컴포넌트 구조에 맞춰 HMR로 교체됩니다. React와 Vue는 모두 Vite의 HMR과 뛰어난 호환성을 자랑하며, 개발자에게 빠르고 직관적인 피드백을 제공합니다.

결론

Vite의 모듈 기반 HMR은 기존 번들러와 비교해 매우 빠르고 가볍게 동작합니다. ES 모듈을 기반으로 모듈 단위로 교체를 수행하며, 브라우저와의 WebSocket 통신을 통해 실시간으로 변경 사항을 반영합니다. Vite의 HMR은 특히 Vue, React 같은 모던 프레임워크에서 매우 원활하게 작동하며, 개발 중 페이지를 새로고침하지 않고도 즉각적인 피드백을 받을 수 있는 장점이 있습니다. 이러한 효율성 덕분에 개발자 경험은 크게 향상되고, 생산성 역시 높아집니다.

반응형

'Vite' 카테고리의 다른 글

10. Vite의 플러그인 시스템 - 1  (1) 2024.10.19
9. Vite의 Dev Server 동작 방식 - 2  (1) 2024.10.19
8. Vite의 Dev Server 동작 방식 -1  (0) 2024.10.19
6. Vite 프로젝트 구조 - 1  (0) 2024.10.19
5. Vite의 주요 특징 - 3  (2) 2024.10.19
3. Vite의 주요 특징 - 1  (0) 2024.10.19
2. Vite란 무엇인가? - 2  (0) 2024.10.19
1. Vite란 무엇인가? - 1  (0) 2024.10.19