如果已透過 HotModuleReplacementPlugin
啟用 熱模組替換,其介面會在 module.hot
屬性以及 import.meta.webpackHot
屬性下公開。請注意,只有 嚴格 ESM 中可以使用 import.meta.webpackHot
。
通常,使用者會檢查介面是否可存取,然後開始使用它。以下是一個範例,說明您如何 accept
更新的模組
if (module.hot) {
module.hot.accept('./library.js', function () {
// Do something with the updated library module...
});
}
// or
if (import.meta.webpackHot) {
import.meta.webpackHot.accept('./library.js', function () {
// Do something with the updated library module…
});
}
支援下列方法...
接受給定 dependencies
的更新,並觸發 callback
來回應這些更新,此外,您可以附加一個選用的錯誤處理常式
module.hot.accept(
dependencies, // Either a string or an array of strings
callback, // Function to fire when the dependencies are updated
errorHandler // (err, {moduleId, dependencyId}) => {}
);
// or
import.meta.webpackHot.accept(
dependencies, // Either a string or an array of strings
callback, // Function to fire when the dependencies are updated
errorHandler // (err, {moduleId, dependencyId}) => {}
);
使用 ESM import
時,所有從 dependencies
匯入的符號都會自動更新。注意:相依性字串必須與 import
中的 from
字串完全相符。在某些情況下,甚至可以省略 callback
。在此處的 callback
中使用 require()
沒有意義。
使用 CommonJS 時,您需要使用 callback
中的 require()
手動更新相依性。在此處省略 callback
沒有意義。
(err, {moduleId, dependencyId}) => {}
err
:使用 ESM 相依性時,由第二個參數中的 callback 或相依性執行期間引發的錯誤。moduleId
:目前的模組 ID。dependencyId
:已變更相依性(第一個)的模組 ID。接受更新本身。
module.hot.accept(
errorHandler // Function to handle errors when evaluating the new version
);
// or
import.meta.webpackHot.accept(
errorHandler // Function to handle errors when evaluating the new version
);
當此模組或相依性更新時,此模組可以處置並重新評估,而無需通知父項。如果此模組沒有匯出(或匯出以其他方式更新),這很有意義。
當此模組(或相依性)的評估引發例外狀況時,會觸發 errorHandler
。
(err, {moduleId, module}) => {}
err
:評估新版本時的錯誤。moduleId
:目前的模組 ID。module
:目前的模組實例。module.hot
:允許使用錯誤模組實例的 HMR API。常見的場景是再次自我接受。加入處置處理常程式以傳遞資料也很有意義。請注意,錯誤模組可能已經部分執行,因此請務必不要進入不一致的狀態。您可以使用 module.hot.data
來儲存部分狀態。module.exports
:可以覆寫,但請小心,因為屬性名稱在生產模式中可能會被破壞。拒絕給定的 dependencies
更新,強制更新失敗,並顯示 'decline'
程式碼。
module.hot.decline(
dependencies // Either a string or an array of strings
);
// or
import.meta.webpackHot.decline(
dependencies // Either a string or an array of strings
);
標記一個無法更新的依賴項。當這個依賴項的匯出無法處理,或尚未實作處理時,這很有意義。根據您的 HMR 管理程式碼,對這些依賴項(或其無法接受的依賴項)的更新通常會導致頁面重新載入。
拒絕更新本身。
module.hot.decline();
// or
import.meta.webpackHot.decline();
標記這個模組無法更新。當這個模組有不可逆的副作用,或尚未實作這個模組的 HMR 處理時,這很有意義。根據您的 HMR 管理程式碼,對這個模組(或無法接受的依賴項)的更新通常會導致頁面重新載入。
新增一個處理常式,當目前的模組程式碼被取代時執行。這應該用於移除您已宣告或建立的任何持續性資源。如果您想將狀態轉移到更新的模組,請將它新增到給定的 data
參數。更新後,這個物件會在 module.hot.data
中可用。
module.hot.dispose((data) => {
// Clean up and pass data to the updated module...
});
// or
import.meta.webpackHot.dispose((data) => {
// Clean up and pass data to the updated module...
});
呼叫這個方法會使目前的模組失效,當 HMR 更新套用時,會處置並重新建立它。這會像這個模組的正常更新一樣冒泡。invalidate
無法由這個模組自行接受。
當在 idle
狀態期間呼叫時,會建立一個新的 HMR 更新,包含這個模組。HMR 會進入 ready
狀態。
在 ready
或 prepare
狀態期間呼叫時,此模組會新增至目前的 HMR 更新。
在 check
狀態期間呼叫時,當有更新可用時,此模組會新增至更新。如果沒有可用更新,它會建立新的更新。HMR 會進入 ready
狀態。
在 dispose
或 apply
狀態期間呼叫時,HMR 會在離開這些狀態後選取它。
條件接受
模組可以接受依賴項,但當依賴項的變更無法處理時,可以呼叫 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) {
// This can't be handled, bubble to parent
module.hot.invalidate();
return;
}
// This can be handled
processX(x);
});
條件自我接受
模組可以自我接受,但當變更無法處理時,可以使自己失效
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();
}
觸發自訂 HMR 更新
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
新增的處理常式。
module.hot.removeDisposeHandler(callback);
// or
import.meta.webpackHot.removeDisposeHandler(callback);
擷取熱模組替換程序的目前狀態。
module.hot.status(); // Will return one of the following strings...
// or
import.meta.webpackHot.status();
狀態 | 說明 |
---|---|
idle | 程序正在等待呼叫 check |
檢查 | 程序正在檢查更新 |
prepare | 程序正在準備更新(例如下載更新的模組) |
ready | 更新已準備好且可用 |
dispose | 程序正在呼叫將被替換的模組上的 dispose 處理常式 |
套用 | 程序正在呼叫 accept 處理常式並重新執行自接受的模組 |
abort | 更新已中止,但系統仍處於前一個狀態 |
fail | 更新已擲回例外,系統狀態已受損 |
測試所有已載入的模組是否有更新,如果有更新,則 apply
它們。
module.hot
.check(autoApply)
.then((outdatedModules) => {
// outdated modules...
})
.catch((error) => {
// catch errors
});
// or
import.meta.webpackHot
.check(autoApply)
.then((outdatedModules) => {
// outdated modules...
})
.catch((error) => {
// catch errors
});
autoApply
參數可以是布林值或在呼叫時傳遞給 apply
方法的 options
。
繼續更新程序(只要 module.hot.status() === 'ready'
)。
module.hot
.apply(options)
.then((outdatedModules) => {
// outdated modules...
})
.catch((error) => {
// catch errors
});
// or
import.meta.webpackHot
.apply(options)
.then((outdatedModules) => {
// outdated modules...
})
.catch((error) => {
// catch errors
});
選用的 options
物件可以包含下列屬性
ignoreUnaccepted
(布林值):忽略對未接受的模組所做的變更。ignoreDeclined
(布林值):忽略對已拒絕的模組所做的變更。ignoreErrored
(布林值):忽略在接受處理常式、錯誤處理常式和重新評估模組時擲回的錯誤。onDeclined
(函式(info)):已拒絕模組的通知器onUnaccepted
(函式(info)):未接受模組的通知器onAccepted
(函式(info)):已接受模組的通知器onDisposed
(函式(info)):已處置模組的通知器onErrored
(函式(info)):錯誤的通知器info
參數將會是包含下列值中某些值的物件
{
type: 'self-declined' | 'declined' |
'unaccepted' | 'accepted' |
'disposed' | 'accept-errored' |
'self-accept-errored' | 'self-accept-error-handler-errored',
moduleId: 4, // The module in question.
dependencyId: 3, // For errors: the module id owning the accept handler.
chain: [1, 2, 3, 4], // For declined/accepted/unaccepted: the chain from where the update was propagated.
parentId: 5, // For declined: the module id of the declining parent
outdatedModules: [1, 2, 3, 4], // For accepted: the modules that are outdated and will be disposed
outdatedDependencies: { // For accepted: The location of accept handlers that will handle the update
5: [4]
},
error: new Error(...), // For errors: the thrown error
originalError: new Error(...) // For self-accept-error-handler-errored:
// the error thrown by the module before the error handler tried to handle it.
}
註冊一個函式來偵聽 status
的變更。
module.hot.addStatusHandler((status) => {
// React to the current status...
});
// or
import.meta.webpackHot.addStatusHandler((status) => {
// React to the current status...
});
請注意,當狀態處理常式傳回 Promise
時,HMR 系統將會等到 Promise
解析完畢才會繼續執行。
移除已註冊的狀態處理常式。
module.hot.removeStatusHandler(callback);
// or
import.meta.webpackHot.removeStatusHandler(callback);