CC 4.0 授權
本節內容衍生自以下連結的內容,並受 CC BY 4.0 授權約束。
如果未特別聲明,以下內容可視為在原始內容基礎上進行修改和刪除的結果。
熱模組替換
通常,使用者會檢查介面是否可存取,然後開始使用它。 例如,以下是如何 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…
});
}
支援以下方法...
模組 API
accept
接受給定 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
沒有意義。
accept 的 errorHandler
(err, {moduleId, dependencyId}) => {}
err
:在第二個引數中的 callback 或在使用 ESM 相依性時相依性執行期間拋出的錯誤。
moduleId
:目前的模組 id。
dependencyId
:(第一個) 變更的相依性的模組 id。
accept (self)
接受本身的更新。
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
。
用於 self accept 的 errorHandler
(err, {moduleId, module}) => {}
err
:評估新版本時發生的錯誤。
moduleId
:目前的模組 id。
module
:目前的模組實例。
module.hot
:允許使用發生錯誤的模組實例的 HMR API。 一種常見的情況是再次 self accept 它。 此外,新增 dispose 處理程式以傳遞資料也很有意義。 請注意,發生錯誤的模組可能已部分執行,因此請確保不會進入不一致的狀態。 您可以使用 module.hot.data
來儲存部分狀態。
module.exports
:可以覆寫,但請小心,因為屬性名稱可能會在生產模式中被混淆。
decline
拒絕給定 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 管理程式碼,通常更新這些相依性 (或未接受的相依性) 會導致頁面重新載入。
decline (self)
拒絕本身的更新。
module.hot.decline();
// or
import.meta.webpackHot.decline();
將此模組標記為不可更新。 當此模組具有不可逆的副作用,或尚未針對此模組實作 HMR 處理時,此方法才有意義。 根據您的 HMR 管理程式碼,通常更新此模組 (或未接受的相依性) 會導致頁面重新載入。
dispose (或 addDisposeHandler)
新增一個處理程式,當目前的模組程式碼被取代時,將會執行此處理程式。 這應該用於移除您聲明或建立的任何持續性資源。 如果您想要將狀態傳輸到更新後的模組,請將其新增至給定的 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...
});
invalidate
呼叫此方法將會使目前的模組失效,這會在套用 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();
}
T> 當呼叫 invalidate
時,最終會呼叫dispose
處理程式並填入 module.hot.data
。 如果未註冊dispose
處理程式,則將會為 module.hot.data
提供一個空物件。
W> 請勿陷入 invalidate
迴圈,再次呼叫 invalidate
。 這會導致堆疊溢位,且 HMR 會進入 fail
狀態。
removeDisposeHandler
移除透過 dispose
或 addDisposeHandler
新增的處理程式。
module.hot.removeDisposeHandler(callback);
// or
import.meta.webpackHot.removeDisposeHandler(callback);
管理 API
狀態
檢索熱模組替換程序的目前狀態。
module.hot.status(); // Will return one of the following strings...
// or
import.meta.webpackHot.status();
狀態 |
描述 |
閒置 (idle) |
程序正在等待呼叫 check |
檢查 (check) |
程序正在檢查更新 |
準備 (prepare) |
程序正在為更新做準備 (例如,下載更新後的模組) |
就緒 (ready) |
更新已準備就緒並可用 |
處置 (dispose) |
程序正在對將被替換的模組呼叫 dispose 處理程序 |
套用 (apply) |
程序正在呼叫 accept 處理程序並重新執行自我接受的模組 |
中止 (abort) |
更新已中止,但系統仍處於先前的狀態 |
失敗 (fail) |
更新拋出例外,系統狀態已受損 |
檢查 (check)
測試所有已載入的模組是否有更新,如果存在更新,則 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
。
套用 (apply)
繼續更新程序 (只要 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.
}
addStatusHandler
註冊一個函數來監聽 status
的變更。
module.hot.addStatusHandler(status => {
// React to the current status...
});
// or
import.meta.webpackHot.addStatusHandler(status => {
// React to the current status...
});
請注意,當狀態處理程序返回 Promise
時,HMR 系統將等待 Promise
解析後才繼續。
removeStatusHandler
移除已註冊的狀態處理程序。
module.hot.removeStatusHandler(callback);
// or
import.meta.webpackHot.removeStatusHandler(callback);