웹팩 개발 서버는 코드의 변화를 감지해서 전체 화면이 갱신되기 때문에 화면에 있는 데이터들이 초기화가 된다.
웹팩 개발 서버에서는 전체 화면을 갱신하지 않고 변경한 모듈만 바꿔치기 해줄 수 있는 Hot Module Replacement
를 제공한다.
webpack.config.js에서 웹팩 개발 서버 설정인 devServer
의 hot
속성을 true
로 해주면 된다.
module.exports = {
devServer = {
hot: true
}
}
우선 HMR 테스트용 코드를 추가해보자
const form = {
render() {
return `
<form>
<input />
<button type="submit">검색</button>
<button type="reset">취소</button>
</form>
`;
},
};
export default form;
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;
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 하단에 아래 코드를 추가해보자.
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();
});
}
devServer
의 hot
옵션을 켜면 웹팩 개발 서버 위에서 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
도 핫 모듈 리플레이스먼트를 지원한다.