먼저 HMR (핫 모듈 교체)은 여전히 실험적인 기능입니다.
HMR은 실행중인 응용 프로그램에서 모듈을 교환하고 모듈을 추가 / 제거하는 방법입니다. 기본적으로 전체 페이지를 다시로드하지 않고도 변경된 모듈을 업데이트 할 수 있습니다.
선적 서류 비치
전제 조건 :
HMR에는 그다지 중요하지 않지만 링크는 다음과 같습니다.
이 답변을 설명서에 추가하겠습니다.
어떻게 작동합니까?
앱보기에서
앱 코드는 HMR 런타임에 업데이트를 확인하도록 요청합니다. HMR 런타임은 업데이트 (비동기)를 다운로드하고 앱 코드에 업데이트가 있음을 알려줍니다. 앱 코드는 HMR 런타임에 업데이트를 적용하도록 요청합니다. HMR 런타임은 업데이트 (동기화)를 적용합니다. 이 프로세스에서 앱 코드는 사용자 상호 작용을 요구하거나 요구하지 않을 수 있습니다 (결정).
컴파일러 (웹팩)보기에서
일반 자산 외에도 컴파일러는 이전 버전에서이 버전으로 업데이트 할 수 있도록 "업데이트"를 내 보내야합니다. "업데이트"에는 두 부분이 있습니다.
- 업데이트 매니페스트 (json)
- 하나 이상의 업데이트 청크 (js)
매니페스트에는 새로운 컴파일 해시와 모든 업데이트 청크 목록이 포함되어 있습니다 (2).
업데이트 청크에는이 청크의 모든 업데이트 된 모듈에 대한 코드 (또는 모듈이 제거 된 경우 플래그)가 포함됩니다.
또한 컴파일러는 이러한 빌드간에 모듈 및 청크 ID가 일치하는지 확인합니다. "records"json 파일을 사용하여 빌드간에 파일을 저장하거나 메모리에 저장합니다.
모듈 뷰에서
HMR은 옵트 인 기능이므로 HMR 코드가 포함 된 모듈에만 영향을줍니다. 설명서는 모듈에서 사용 가능한 API를 설명합니다. 일반적으로 모듈 개발자는이 모듈의 종속성이 업데이트 될 때 호출되는 핸들러를 작성합니다. 또한이 모듈이 업데이트 될 때 호출되는 핸들러를 작성할 수 있습니다.
대부분의 경우 모든 모듈에서 HMR 코드를 작성해야하는 것은 아닙니다. 모듈에 HMR 처리기가 없으면 업데이트가 시작됩니다. 이는 단일 핸들러가 완전한 모듈 트리에 대한 업데이트를 처리 할 수 있음을 의미합니다. 이 트리의 단일 모듈이 업데이트되면 전체 모듈 트리가 다시로드됩니다 (다시로드 만하고 전송되지는 않음).
HMR 런타임보기에서 (기술적)
추가 코드 추적하기위한 모듈, 모듈 시스템 런타임 방출 parents
및 children
.
관리 측면에서, 런타임은 두 가지 방법을 지원 check
하고 apply
.
A check
는 업데이트 매니페스트에 대한 HTTP 요청을 수행합니다. 이 요청이 실패하면 사용 가능한 업데이트가 없습니다. 그렇지 않으면 업데이트 된 청크 목록이 현재로드 된 청크 목록과 비교됩니다. 로드 된 각 청크에 대해 해당 업데이트 청크가 다운로드됩니다. 모든 모듈 업데이트는 런타임에 업데이트로 저장됩니다. 런타임이 ready
상태 로 전환되어 업데이트가 다운로드되었고 적용 할 준비가되었음을 나타냅니다.
준비 상태의 각 새 청크 요청에 대해 업데이트 청크도 다운로드됩니다.
이 apply
메소드는 모든 업데이트 된 모듈을 유효하지 않은 것으로 플래그합니다. 유효하지 않은 각 모듈마다 모듈에 업데이트 핸들러가 있거나 모든 상위에 업데이트 핸들러가 있어야합니다. 그렇지 않으면 무효 한 거품이 나타나고 모든 부모도 유효하지 않은 것으로 표시됩니다. 이 프로세스는 더 이상 "버블 업"이 발생하지 않을 때까지 계속됩니다. 진입 점까지 버블 링되면 프로세스가 실패합니다.
이제 모든 유효하지 않은 모듈이 처리되고 (처리기 폐기) 언로드됩니다. 그런 다음 현재 해시가 업데이트되고 모든 "수락"핸들러가 호출됩니다. 런타임이 idle
상태로 다시 전환 되고 모든 것이 정상적으로 계속됩니다.
그것으로 무엇을 할 수 있습니까?
개발시 LiveReload 대체품으로 사용할 수 있습니다. 실제로 webpack-dev-server는 전체 페이지를 다시로드하기 전에 HMR로 업데이트를 시도하는 핫 모드를 지원합니다. webpack/hot/dev-server
시작점 만 추가 하고로 dev-server를 호출하면됩니다 --hot
.
프로덕션에서 업데이트 메커니즘으로 사용할 수도 있습니다. 여기에 HMR을 앱과 통합하는 자체 관리 코드를 작성해야합니다.
일부 로더는 이미 핫 업데이트 가능한 모듈을 생성합니다. 예 : style-loader
스타일 시트를 교환 할 수 있습니다. 특별한 것을 할 필요는 없습니다.
페이지를 다시로드하지 않고 LiveReload와 같은 플러그인을 사용하지 않고 디스크에 저장할 때 CSS (한 스타일 시트)와 JS 모듈을 업데이트하려고한다고 가정합니다. 핫 모듈 교체가 도움이 될 수 있습니까?
예
어떤 종류의 작업을해야합니까? 그리고 HMR은 이미 무엇을 제공합니까?
여기 작은 예가 있습니다 : https://webpack.js.org/guides/hot-module-replacement/
모듈은 "수락"하는 경우에만 업데이트 할 수 있습니다. 따라서 module.hot.accept
부모님이나 부모님의 부모님에게 모듈 이 필요합니다 . 예를 들어 라우터가 좋은 장소이거나 하위 견해입니다.
webpack-dev-server에서만 사용하려면 webpack/hot/dev-server
엔트리 포인트로 추가하십시오 . 다른 사람이 전화 몇몇 HMR 관리 코드 필요 check
와 apply
.
의견 : 왜 그렇게 시원하게합니까?
- LiveReload이지만 모든 종류의 모듈에 적용됩니다.
- 프로덕션에서 사용할 수 있습니다.
- 업데이트는 코드 분할을 존중하며 앱의 사용 된 부분에 대한 업데이트 만 다운로드합니다.
- 응용 프로그램의 일부로 사용할 수 있으며 다른 모듈에는 영향을 미치지 않습니다.
- HMR을 사용하지 않으면 모든 HMR 코드가 컴파일러에 의해 제거됩니다 (랩핑
if(module.hot)
).
경고
- 실험적이고 잘 테스트되지 않았습니다.
- 몇 가지 버그가 예상됩니다.
- 이론적으로는 프로덕션에서 사용할 수 있지만 심각한 작업에 사용하기에는 너무 이르다.
- 컴파일간에 모듈 ID를 추적해야하므로 모듈 ID를 저장해야합니다 (
records
).
- 옵티마이 저는 첫 번째 컴파일 후 더 이상 모듈 ID를 최적화 할 수 없습니다. 번들 크기에 약간의 영향을 미칩니다.
- HMR 런타임 코드는 번들 크기를 증가시킵니다.
- 프로덕션 용도의 경우 HMR 핸들러를 테스트하려면 추가 테스트가 필요합니다. 이것은 매우 어려울 수 있습니다.