Primeiro, quero observar que a substituição de módulo quente (HMR) ainda é um recurso experimental.
O HMR é uma maneira de trocar módulos em um aplicativo em execução (e adicionar / remover módulos). Basicamente, você pode atualizar os módulos alterados sem recarregar a página inteira.
Documentação
Pré requisitos:
Não é tanto para HMR, mas aqui estão os links:
Vou adicionar essas respostas à documentação.
Como funciona?
Na visualização do aplicativo
O código do aplicativo solicita ao tempo de execução do HMR que verifique atualizações. O tempo de execução do HMR baixa as atualizações (assíncronas) e informa ao código do aplicativo que uma atualização está disponível. O código do aplicativo solicita que o tempo de execução do HMR aplique atualizações. O tempo de execução do HMR aplica as atualizações (sincronização). O código do aplicativo pode ou não exigir a interação do usuário nesse processo (você decide).
Na visualização do compilador (webpack)
Além dos ativos normais, o compilador precisa emitir a "Atualização" para permitir a atualização de uma versão anterior para esta versão. A "Atualização" contém duas partes:
- o manifesto de atualização (json)
- um ou vários blocos de atualização (js)
O manifesto contém o novo hash de compilação e uma lista de todos os chunks de atualização (2).
Os blocos de atualização contêm código para todos os módulos atualizados nesse bloco (ou um sinalizador se um módulo foi removido).
O compilador adicionalmente garante que os IDs do módulo e do bloco sejam consistentes entre essas compilações. Ele usa um arquivo json "records" para armazená-los entre compilações (ou armazena-os na memória).
Na visualização do módulo
O HMR é um recurso de aceitação, portanto, afeta apenas os módulos que contêm o código HMR. A documentação descreve a API que está disponível em módulos. Em geral, o desenvolvedor do módulo grava manipuladores chamados quando uma dependência desse módulo é atualizada. Eles também podem escrever um manipulador chamado quando este módulo é atualizado.
Na maioria dos casos, não é obrigatório escrever o código HMR em todos os módulos. Se um módulo não tiver manipuladores HMR, a atualização será exibida. Isso significa que um único manipulador pode manipular atualizações para uma árvore de módulos completa. Se um único módulo nesta árvore for atualizado, a árvore completa do módulo será recarregada (somente recarregada, não transferida).
Na visualização de tempo de execução do HMR (técnica)
Um código adicional é emitido para o tempo de execução do sistema do módulo rastrear o módulo parents
e children
.
No lado do gerenciamento, o tempo de execução suporta dois métodos: check
e apply
.
A check
faz uma solicitação HTTP para o manifesto de atualização. Quando essa solicitação falha, não há atualização disponível. Caso contrário, a lista de trechos atualizados é comparada à lista de trechos carregados no momento. Para cada pedaço carregado, o pedaço de atualização correspondente é baixado. Todas as atualizações do módulo são armazenadas no tempo de execução como atualizações. O tempo de execução muda para o ready
estado, o que significa que uma atualização foi baixada e está pronta para ser aplicada.
Para cada nova solicitação de bloco no estado pronto, o bloco de atualização também é baixado.
O apply
método sinaliza todos os módulos atualizados como inválidos. Para cada módulo inválido, é necessário que haja um manipulador de atualização no módulo ou manipuladores de atualização em todos os pais. Caso contrário, as bolhas inválidas aparecerão e marcarão todos os pais como inválidos. Esse processo continua até que não ocorra mais "bolha". Se borbulhar até um ponto de entrada, o processo falhará.
Agora todos os módulos inválidos são descartados (manipulador de descarte) e descarregados. Em seguida, o hash atual é atualizado e todos os manipuladores de "aceitação" são chamados. O tempo de execução volta ao idle
estado e tudo continua como normal.
O que posso fazer com isso?
Você pode usá-lo no desenvolvimento como uma substituição do LiveReload. Na verdade, o webpack-dev-server suporta um modo ativo que tenta atualizar com o HMR antes de tentar recarregar a página inteira. Você só precisa adicionar o webpack/hot/dev-server
ponto de entrada e chamar o servidor dev --hot
.
Você também pode usá-lo na produção como mecanismos de atualização. Aqui você precisa escrever seu próprio código de gerenciamento que integra o HMR ao seu aplicativo.
Alguns carregadores já geram módulos atualizáveis a quente. Por exemplo, o style-loader
pode trocar a folha de estilo. Você não precisa fazer nada de especial.
Suponha que eu queira atualizar meus módulos CSS (uma folha de estilo) e JS quando os salvar em disco, sem recarregar a página e sem usar plug-ins como o LiveReload. É algo que a substituição de módulo quente pode me ajudar?
sim
Que tipo de trabalho eu preciso fazer e o que a HMR já oferece?
Aqui está um pequeno exemplo: https://webpack.js.org/guides/hot-module-replacement/
Um módulo só pode ser atualizado se você o "aceitar". Então você precisa module.hot.accept
do módulo nos pais ou nos pais dos pais ... por exemplo, um roteador é um bom local ou uma subvisão.
Se você quiser usá-lo apenas com o webpack-dev-server, basta adicionar webpack/hot/dev-server
como ponto de entrada. Caso contrário, você precisa de algum código de gerenciamento HMR que chame check
e apply
.
Opinião: O que o torna tão legal?
- É o LiveReload, mas para todos os tipos de módulos.
- Você pode usá-lo na produção.
- As atualizações respeitam a divisão de código e baixam atualizações apenas para as partes usadas do seu aplicativo.
- Você pode usá-lo para uma parte do seu aplicativo e não afeta outros módulos
- Se o HMR estiver desativado, todo o código do HMR será removido pelo compilador (envolva-o
if(module.hot)
).
Ressalvas
- É experimental e não foi testado tão bem.
- Espere alguns erros.
- Teoricamente utilizável na produção, mas pode ser muito cedo para usá-lo para algo sério.
- Os IDs do módulo precisam ser rastreados entre compilações, para que você os armazene (
records
).
- O otimizador não pode mais otimizar os IDs do módulo após a primeira compilação. Um pouco de impacto no tamanho do pacote.
- O código de tempo de execução HMR aumenta o tamanho do pacote configurável.
- Para uso em produção, testes adicionais são necessários para testar os manipuladores HMR. Isso pode ser bem difícil.