如果已經(jīng)通過 HotModuleReplacementPlugin 啟用了 Hot Module Replacement, 則它的接口將被暴露在 module.hot 以及 import.meta.webpackHot 屬性下。請(qǐng)注意,只有 import.meta.webpackHot 可以在 strict ESM 中使用。
通常,用戶先要檢查這個(gè)接口是否可訪問, 再使用它。你可以這樣使用 accept 操作一個(gè)更新的模塊:
if (module.hot) {
module.hot.accept('./library.js', function() {
// 對(duì)更新過的 library 模塊做些事情...
});
}
// or
if (import.meta.webpackHot) {
import.meta.webpackHot.accept('./library.js', function () {
// Do something with the updated library module…
});
}
支持以下方法
接受(accept)給定 依賴模塊(dependencies) 的更新,并觸發(fā)一個(gè) 回調(diào)函數(shù) 來響應(yīng)更新,除此之外,你可以附加一個(gè)可選的 error 處理程序:
module.hot.accept(
dependencies, // 可以是一個(gè)字符串或字符串?dāng)?shù)組
callback // 用于在模塊更新后觸發(fā)的函數(shù)
errorHandler // (err, {moduleId, dependencyId}) => {}
);
// or
import.meta.webpackHot.accept(
dependencies, // 可以是一個(gè)字符串或字符串?dāng)?shù)組
callback, // 用于在模塊更新后觸發(fā)的函數(shù)
errorHandler // (err, {moduleId, dependencyId}) => {}
);
當(dāng)使用 ESM import 時(shí),所有從 dependencies 中導(dǎo)入的符號(hào)都會(huì)自動(dòng)更新。注意:依賴項(xiàng)字符串必須與 import 中的 from 字符串完全匹配。在某些情況下, 甚至可以省略 callback。在 callback 中使用的 require() 在這里沒有任何意義。
在使用 CommonJS 時(shí),你應(yīng)該通過 callback 中的 require() 手動(dòng)更新依賴模塊。省略 callback 在這里沒有任何意義。
(err, {moduleId, dependencyId}) => {}
接受自身更新。
module.hot.accept(
errorHandler // 在計(jì)算新版本時(shí)處理錯(cuò)誤的函數(shù)
);
// or
import.meta.webpackHot.accept(
errorHandler // Function to handle errors when evaluating the new version
);
在此模塊或依賴模塊更新時(shí),可以在不通知父依賴的情況下,對(duì)此模塊處理和重新取值。如果此模塊沒有導(dǎo)出(或以其他方式更新的導(dǎo)出),這是有意義的。
當(dāng)執(zhí)行此模塊(或依賴模塊)拋出異常時(shí),會(huì)觸發(fā) errorHandler。
(err, {moduleId, module}) => {}
拒絕給定依賴模塊的更新,使用 'decline' 方法強(qiáng)制更新失敗。
module.hot.decline(
dependencies // 可以是一個(gè)字符串或字符串?dāng)?shù)組
);
// or
import.meta.webpackHot.decline(
dependencies // Either a string or an array of strings
);
將依賴模塊標(biāo)記為不可更新(not-update-able)。在處理「依賴的導(dǎo)出正在更新」或「尚未實(shí)現(xiàn)處理」時(shí),這是有意義的。取決于你的 HMR 管理代碼, 此依賴模塊(或其未接受的依賴模塊)更新,通常會(huì)導(dǎo)致頁(yè)面被完全重新加載。
拒絕自身更新。
module.hot.decline();
// or
import.meta.webpackHot.decline();
將依賴模塊標(biāo)記為不可更新(not-update-able)。當(dāng)此模塊具有無法避免的外部作用(side-effect),或者尚未對(duì)此模塊進(jìn)行 HMR 處理時(shí),這是有意義的。取決于你的 HMR 管理代碼,此依賴模塊(或其未接受的依賴模塊)更新,通常會(huì)導(dǎo)致頁(yè)面被完全重新加載。
添加一個(gè)處理函數(shù),在當(dāng)前模塊代碼被替換時(shí)執(zhí)行。此函數(shù)應(yīng)該用于移除你聲明或創(chuàng)建的任何持久資源。如果要將狀態(tài)傳入到更新過的模塊,請(qǐng)?zhí)砑咏o定 data 參數(shù)。更新后,此對(duì)象在更新之后可通過 module.hot.data 調(diào)用。
module.hot.dispose(data => {
// 清理并將 data 傳遞到更新后的模塊...
});
// or
import.meta.webpackHot.dispose((data) => {
// Clean up and pass data to the updated module...
});
調(diào)用此方法將使當(dāng)前模塊無效,而當(dāng)前模塊將在應(yīng)用 HMR 更新時(shí)進(jìn)行部署并重新創(chuàng)建。這個(gè)模塊的更新像冒泡一樣,拒絕自身更新。
在 idle 狀態(tài)下調(diào)用時(shí),將創(chuàng)建一個(gè)包含此模塊的新 HMR 更新。HMR 將進(jìn)入 ready 狀態(tài)。
在 ready 或 prepare 狀態(tài)下調(diào)用時(shí),此模塊將添加到當(dāng)前 HMR 的更新中。
在 check 狀態(tài)期間被調(diào)用時(shí),如果有可用更新,則此模塊將添加到更新中。如果沒有可用的更新,它將創(chuàng)建一個(gè)新更新。HMR 將進(jìn)入 ready 狀態(tài)。
在 dispose 或 apply 狀態(tài)下調(diào)用時(shí),HMR 將在退出這些狀態(tài)后將其拾取。
Conditional Accepting
一個(gè)模塊可以接受一個(gè)依賴,但是當(dāng)依賴的改變無法處理時(shí),可以調(diào)用 invalidate:
import { x, y } from './dep';
import { processX, processY } from 'anotherDep';
const oldY = y;
processX(x);
export default processY(y);
module.hot.accept('./dep', () => {
if (y !== oldY) {
// 無法處理,冒泡給父級(jí)
module.hot.invalidate();
return;
}
// 可以處理
processX(x);
});
Conditional self accept
模塊可以自我接受,但是當(dāng)更改無法處理時(shí)可以使自身失效:
const VALUE = 'constant';
export default VALUE;
if (
module.hot.data &&
module.hot.data.value &&
module.hot.data.value !== VALUE
) {
module.hot.invalidate();
} else {
module.hot.dispose((data) => {
data.value = VALUE;
});
module.hot.accept();
}
Triggering custom HMR updates
const moduleId = chooseAModule();
const code = __webpack_modules__[moduleId].toString();
__webpack_modules__[moduleId] = eval(`(${makeChanges(code)})`);
if (require.cache[moduleId]) {
require.cache[moduleId].hot.invalidate();
module.hot.apply();
}
刪除由 dispose 或 addDisposeHandler 添加的回調(diào)函數(shù)。
module.hot.removeDisposeHandler(callback);
// or
import.meta.webpackHot.removeDisposeHandler(callback);
獲取當(dāng)前模塊熱替換進(jìn)程的狀態(tài)。
module.hot.status(); // 返回以下字符串之一...
// 或者
import.meta.webpackHot.status();
Status | Description |
---|---|
idle | 該進(jìn)程正在等待調(diào)用 check (見下文) |
check | 該進(jìn)程正在檢查以更新 |
prepare | 該進(jìn)程正在準(zhǔn)備更新(例如,下載已更新的模塊) |
ready | 此更新已準(zhǔn)備并可用 |
dispose | 該進(jìn)程正在調(diào)用將被替換模塊的 dispose 處理函數(shù) |
apply | 該進(jìn)程正在調(diào)用 accept 處理函數(shù),并重新執(zhí)行自我接受(self-accepted)的模塊 |
abort | 更新已中止,但系統(tǒng)仍處于之前的狀態(tài) |
fail | 更新已拋出異常,系統(tǒng)狀態(tài)已被破壞 |
測(cè)試所有加載的模塊以進(jìn)行更新,如果有更新,則 apply 它們。
module.hot
.check(autoApply)
.then((outdatedModules) => {
// 超時(shí)的模塊...
})
.catch((error) => {
// 捕獲錯(cuò)誤
});
// or
import.meta.webpackHot
.check(autoApply)
.then((outdatedModules) => {
// outdated modules...
})
.catch((error) => {
// catch errors
});
當(dāng)被調(diào)用時(shí),傳遞給 apply 方法的 autoApply 參數(shù)可以是布爾值,也可以是 options,
繼續(xù)更新進(jìn)程(當(dāng) module.hot.status() === 'ready' 時(shí))。
module.hot
.apply(options)
.then((outdatedModules) => {
// 超時(shí)的模塊...
})
.catch((error) => {
// 捕獲錯(cuò)誤
});
// or
import.meta.webpackHot
.apply(options)
.then((outdatedModules) => {
// outdated modules...
})
.catch((error) => {
// catch errors
});
可選的 options 對(duì)象可以包含以下屬性:
info 參數(shù)將是一個(gè)包含以下某些值的對(duì)象:
{
type: 'self-declined' | 'declined' |
'unaccepted' | 'accepted' |
'disposed' | 'accept-errored' |
'self-accept-errored' | 'self-accept-error-handler-errored',
moduleId: 4, // 有問題的模塊。
dependencyId: 3, // 對(duì)于錯(cuò)誤:擁有接受處理程序的模塊 ID。
chain: [1, 2, 3, 4], // 對(duì)于拒絕/接受/不接受:傳播更新的 `chain`。
parentId: 5, // 對(duì)于拒絕:下降的父模塊 ID。
outdatedModules: [1, 2, 3, 4], // 對(duì)于接受:已過時(shí)且將被處置的模塊。
outdatedDependencies: { // 對(duì)于接受:將處理更新的接受處理程序的位置。
5: [4]
},
error: new Error(...), // 對(duì)于錯(cuò)誤:拋出錯(cuò)誤
originalError: new Error(...) // 對(duì)于自我接受錯(cuò)誤處理程序錯(cuò)誤:
// 在錯(cuò)誤處理程序嘗試處理該模塊之前,該模塊引發(fā)的錯(cuò)誤。
}
注冊(cè)一個(gè)函數(shù)來監(jiān)聽 status 的變化。
module.hot.addStatusHandler((status) => {
// 響應(yīng)當(dāng)前狀態(tài)...
});
// or
import.meta.webpackHot.addStatusHandler((status) => {
// React to the current status...
});
請(qǐng)記住,當(dāng) status 處理函數(shù)返回一個(gè) Promise 時(shí),HMR 系統(tǒng)將會(huì)在繼續(xù)之前等待 Promise resolve。
移除一個(gè)注冊(cè)的狀態(tài)處理函數(shù)。
module.hot.removeStatusHandler(callback);
// or
import.meta.webpackHot.removeStatusHandler(callback);
更多建議: