Замена модулей при горячей перезагрузке
Если Замена модулей при горячей перезагрузке включена через HotModuleReplacementPlugin, её интерфейс будет доступен через свойство module.hot, а также свойство import.meta.webpackHot. Обратите внимание, что только import.meta.webpackHot может использоваться в строгом ESM.
Обычно пользователи проверяют доступность интерфейса, а затем начинают с ним работать. Например, вот как можно 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 автоматически обновляются. Примечание: строка зависимости должна точно соответствовать строке from в import. В некоторых случаях callback можно опустить. Использование require() в callback здесь не имеет смысла.
При использовании CommonJS необходимо вручную обновить зависимости, используя require() в callback. Опускание callback здесь не имеет смысла.
errorHandler для accept
(err, {moduleId, dependencyId}) => {}
-
err: ошибка, брошенная обратным вызовом во втором аргументе или во время выполнения зависимостей при использовании ESM-зависимостей. -
moduleId: текущий идентификатор модуля. -
dependencyId: идентификатор модуля (первой) изменённой зависимости.
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 срабатывает, когда при оценке этого модуля (или зависимостей) возникает исключение.
errorHandler для self accept
(err, {moduleId, module}) => {}
-
err: ошибка при оценке новой версии. -
moduleId: текущий идентификатор модуля. -
module: текущий экземпляр модуля.-
module.hot: позволяет использовать API горячей перезагрузки экземпляра модуля с ошибкой. Общий сценарий — повторно принять его. Также имеет смысл добавить обработчик удаления для передачи данных. Обратите внимание, что модуль с ошибкой может быть частично выполнен, поэтому необходимо убедиться, что состояние не станет несогласованным. Для сохранения частичного состояния можно использовать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 );
Помечает зависимость как не подлежащую обновлению. Это имеет смысл, когда изменения экспортов этой зависимости не могут быть обработаны или обработка ещё не реализована. В зависимости от вашего кода управления горячей перезагрузкой, обновление этих зависимостей (или не принятых зависимостей) обычно приводит к полной перезагрузке страницы.
decline (self)
Отклоняет обновления для себя.
module.hot.decline(); // or import.meta.webpackHot.decline();
Помечает этот модуль как не подлежащий обновлению. Это имеет смысл, когда у этого модуля есть необратимые побочные эффекты или обработка горячей перезагрузки для этого модуля ещё не реализована. В зависимости от вашего кода управления горячей перезагрузкой, обновление этого модуля (или не принятых зависимостей) обычно приводит к полной перезагрузке страницы.
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
Вызов этого метода делает текущий модуль недействительным, что приводит к его удалению и повторному созданию при применении обновления горячей перезагрузки. Это распространяется, как и обычное обновление этого модуля. invalidate не может быть самопринятым этим модулем.
При вызове в состоянии idle, будет создано новое обновление горячей перезагрузки, содержащее этот модуль. Горячая перезагрузка перейдёт в состояние ready.
При вызове в состоянии ready или prepare, этот модуль будет добавлен в текущее обновление горячей перезагрузки.
При вызове в состоянии check, этот модуль будет добавлен в обновление при наличии обновления. Если обновление недоступно, будет создано новое обновление. Горячая перезагрузка перейдёт в состояние ready.
При вызове в состояниях dispose или apply, горячая перезагрузка подхватит его после выхода из этих состояний.
Примеры использования
Условное принятие
Модуль может принять зависимость, но может вызвать 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();
} Вызов пользовательских обновлений горячей перезагрузки
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();
} removeDisposeHandler
Удалить обработчик, добавленный с помощью dispose или addDisposeHandler.
module.hot.removeDisposeHandler(callback); // or import.meta.webpackHot.removeDisposeHandler(callback);
API управления
status
Получить текущее состояние процесса горячей перезагрузки модулей.
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 может быть булевым значением или options для передачи методу apply при вызове.
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(булево): Игнорировать ошибки, возникшие в обработчиках accept, обработчиках ошибок и при повторной оценке модуля. -
onDeclined(функция(информация)): Уведомление для отклоненных модулей -
onUnaccepted(функция(информация)): Уведомление для не принятых модулей -
onAccepted(функция(информация)): Уведомление для принятых модулей -
onDisposed(функция(информация)): Уведомление для удалённых модулей -
onErrored(функция(информация)): Уведомление об ошибках
Параметр 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, система горячей перезагрузки будет ждать, пока Promise разрешится, прежде чем продолжить.
removeStatusHandler
Удаляет зарегистрированный обработчик состояния.
module.hot.removeStatusHandler(callback); // or import.meta.webpackHot.removeStatusHandler(callback);
© JS Foundation and other contributors
Licensed under the Creative Commons Attribution License 4.0.
https://webpack.js.org/api/hot-module-replacement