[Webpack5] Hot module replacement

상민·2022년 10월 2일
0
post-thumbnail

웹팩 개발 서버는 코드의 변화를 감지해서 전체 화면이 갱신되기 때문에 화면에 있는 데이터들이 초기화가 된다.
웹팩 개발 서버에서는 전체 화면을 갱신하지 않고 변경한 모듈만 바꿔치기 해줄 수 있는 Hot Module Replacement를 제공한다.


설정

webpack.config.js에서 웹팩 개발 서버 설정인 devServerhot 속성을 true로 해주면 된다.

  • webpack.config.js

  module.exports = {
    devServer = {
      hot: true
  	}
  }

우선 HMR 테스트용 코드를 추가해보자

  • src/form.js

const form = {
  render() {
    return `
      <form>
        <input />
        <button type="submit">검색</button>
        <button type="reset">취소</button>
      </form>
    `;
  },
};

export default form;
  • src/result.js

import axios from "axios";

const result = {
  async render() {
    const res = await axios.get("/api/users");

    return (res.data || [])
      .map((user) => {
        return `<div>${user.id}: ${user.name}</div>`;
      })
      .join("-----");
  },
};

export default result;
  • src/app.js

import form from "./form";
import result from "./result";

let resultEl;
let formEl;

document.addEventListener("DOMContentLoaded", async () => {
  formEl = document.createElement("div");
  formEl.innerHTML = form.render();
  document.body.appendChild(formEl);

  resultEl = document.createElement("div");
  resultEl.innerHTML = await result.render();
  document.body.appendChild(resultEl);
});

npm start 로 개발 서버를 실행시키고 코드를 수정해보자

코드 수정이 반영이 되지만 브라우저 전체가 리렌더링이 일어난다
따라서 모듈에 변화가 있을 경우 전체 화면을 렌더링하지 않고 변경된 모듈만 다시 실행시켜야 한다

이 기능을 만들기 위해 app.js 하단에 아래 코드를 추가해보자.

  • src/app.js

import form from "./form";
import result from "./result";

let resultEl;
let formEl;

document.addEventListener("DOMContentLoaded", async () => {
  formEl = document.createElement("div");
  formEl.innerHTML = form.render();
  document.body.appendChild(formEl);

  resultEl = document.createElement("div");
  resultEl.innerHTML = await result.render();
  document.body.appendChild(resultEl);
});

if (module.hot) {
  console.log("핫 모듈 켜짐");

  module.hot.accept("./result", async () => {
    console.log("result 모듈 변경됨");
    resultEl.innerHTML = await result.render();
  });

  module.hot.accept("./form", async () => {
    console.log("form 모듈 변경됨");
    formEl.innerHTML = form.render();
  });
}

devServerhot옵션을 켜면 웹팩 개발 서버 위에서 module.hot 객체가 생성된다. 이 객체의 accept() 메소드는 감시할 모듈콜백 함수를 인자로 받는다.

accept 메소드를 통해 result.js와 form.js의 코드가 수정될 때 마다 console.log를 실행하고 resultEl과 formEl을 render() 메소드로 다시 렌더링하였다.

웹팩 개발 서버를 실행하고 form.js의 코드를 수정해보면 브라우저 콘솔에 "form 모듈 변경됨"이 출력이 되고 브라우저 갱신 없이 화면이 변경될 것이다.


핫로딩을 지원하는 로더

위 코드와 같이 accept 메소드를 사용하여 핫로딩을 지원하도록 하는 것을
HMR 인터페이스를 구현했다고 할 수 있다.

이러한 HMR 인터페이스를 구현한 로더만이 핫로딩을 지원하는데 style-loader가 그렇다.

webpack4에서 사용하는 file-loader도 핫 로딩을 지원하는데 webpack5에서는 사용하지 않는다.
대신 asset modules를 사용하는데 이도 핫로딩을 지원한다.

이외에도 리액트를 지원하는 react-hot-loader도 핫 모듈 리플레이스먼트를 지원한다.


참고자료: https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard

profile
FE Developer

0개의 댓글