Posts [프론트엔드 개발환경의 이해와 실습] 웹팩 핫로딩
Post
Cancel

[프론트엔드 개발환경의 이해와 실습] 웹팩 핫로딩

핫 모듈 리플레이스먼트

배경

웹팩 개발서버는 코드의 변화를 감지해서 전체 화면을 갱신하기 때문에 개발 속도를 높일 수 있다.

하지만 어떤 상황에서는 전체 화면을 갱신하는 것이 좀 불편한 경우도 있다.

싱글페이지어플리케이션(SPA)은 브라우져에서 데이터를 들고 있기 때문에 리프레시 후에 모든 데이터가 초기화 되어 버리기 때문이다. 다른 부분을 수정했는데 입력한 폼 데이터가 날아가 버리는 경우도 있고 말이다.

예를 들면,

  • app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
import form from "./form";
import result from "./result";

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

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

  • form.js
1
2
3
4
5
6
7
8
9
10
11
12
13
const form = {
    render() {
        return `
            <form>
                <input />
                <button type="submit">검색</button>
                <button type="reset">취소</button>
            </form>
        `;
    }
};

export default form;
  • result.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;

app 모듈은 form모듈과 result 모듈을 import로 가져와서 body부분에 렌더링해주는 역할을 담당하고 있다.

웹팩 서버를 기동하면 아래 이미지와 같은 화면이 나올 것이다.

스크린샷 2022-03-27 오후 1 44 07

만약 검색창에 아래 이미지와 같이 입력하고 result 모듈을 의 내용을 수정하면 form모듈까지 다시 렌더링되면 검색창의 데이터가 사라지는 것을 볼 수 있다.

스크린샷 2022-03-27 오후 1 44 34

전체 화면 갱신 하지 않고 변경한 모듈만 바꿔치기 한다면 어떨까? 핫 모듈 리플레이스먼트는 이러한 목적으로 제공되는 웹팩 개발서버의 한 기능이다.

핫로딩 설정

설정은 간단하다. devServer.hot 속성을 켠다.

  • webpack.config.js
1
2
3
4
5
module.exports = {
  devServer = {
    hot: true,
  },
}

그 다음 app.js에 아래 코드를 추가한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
...
if (module.hot) {
  console.log("핫 모듈 커짐");

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

  module.hot.accept("./form", () => {
    formEl.innerHTML = form.render();
  });
}

그리고 나서 웹팩 서버를 기동한 하고 검색창에 데이터를 입력 후 result 모듈을 변경해보자. 그럼 form 모듈은 그대로 유지한체 result모듈만 렌더링 되는 것을 확인할 수 있다.

스크린샷 2022-03-27 오후 1 57 31

devServer.hot 옵션을 켜면 웹팩 개발 서버 위에서 module.hot 객체가 생성된다. 이 객체의 accept() 메소드는 감시할 모듈과 콜백 함수를 인자로 받는다. 위에서는 form 모듈과 result 모듈을 감시하고 변경이 있으면 전달한 콜백 함수가 동작하여 새로 렌더링 하도록 설정해주었다.

이렇게 핫 모듈 리플레이스먼트를 사용하면 변경된 부분만 새로 렌더링되게끔하여 좀 더 개발 생산성을 향상 시킬 수 있다.

핫로딩을 지원하는 로더

웹팩 설정의 hot설정을 true로 지정하는 것 뿐만 아니라, HMR 인터페이스를 구현한 로더만이 핫 로딩을 지원한다

위 실습에서 다음과 같이 HMR 인터페이스를 맞춰주었다.

  • app.js
1
2
3
4
5
6
7
8
9
10
11
12
if (module.hot) {
  console.log("핫 모듈 커짐");

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

  module.hot.accept("./form", () => {
    formEl.innerHTML = form.render();
  });
}

웹팩 기본편에서 보았던 style-loader 또한 HMR인터페이스를 구현하여 핫로딩을 지원한다.

style-loader의 코드를 보면 hot.accept() 함수를 사용한 것을 알 수 있다.

style-loader 출처: https://jeonghwan-kim.github.io/series/2020/01/02/frontend-dev-env-webpack-intermediate.html

이 외에도 리액트를 지원하는 react-hot-loader, 파일을 지원하는 file-loader는 핫 모듈 리플레이스먼트를 지원하는데 여기를 참고하자.

Note: 만약 리액트나 뷰를 사용한다면 각 프레임워크에 맞게 핫로딩을 설정해주면 된다. 기본적인 style-loader, filer-loader 등은 왠만하면 다 이미 설정되어 있다.

출처

This post is licensed under CC BY 4.0 by the author.

[프론트엔드 개발환경의 이해와 실습] 웹팩 최적화

npm과 yarn의 차이