O que exatamente é a Substituição de Módulo Quente no Webpack?

245

Eu li algumas páginas sobre Substituição de Módulo Quente no Webpack.
Existe até um aplicativo de exemplo que o usa .

Eu li tudo isso e ainda não entendi a idéia.

O que posso fazer com isso?

  1. Ele deveria ser usado apenas no desenvolvimento e não na produção?
  2. É como o LiveReload, mas você precisa gerenciar sozinho?
  3. O WebpackDevServer está integrado ao LiveReload de alguma forma?

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? Que tipo de trabalho eu preciso fazer e o que a HMR já oferece?

Dan Abramov
fonte
HMR com Webpack é quase tão bom como este: medium.com/@the1mills/...
Alexander Mills

Respostas:

407

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:

  1. o manifesto de atualização (json)
  2. 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 parentse children.

No lado do gerenciamento, o tempo de execução suporta dois métodos: checke apply.

A checkfaz 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 readyestado, 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 applymé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 idleestado e tudo continua como normal.

pedaços de atualização gerados

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-serverponto 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-loaderpode 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.acceptdo 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-servercomo ponto de entrada. Caso contrário, você precisa de algum código de gerenciamento HMR que chame checke 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.
Tobias K.
fonte
145
Uma resposta infernal.
Dan Abramov
13
Mais uma vez obrigado pela explicação, fiz um vídeo mostrando o poder do HMR para editar ao vivo um aplicativo React.
Dan Abramov
1
bem legal ... Pensei em criar um carregador de reação que adiciona carregamento HMR e assíncrono para reagir aos componentes.
Tobias K.
4
Copiei esta resposta na documentação: webpack.github.io/docs/hot-module-replacement-with-webpack.html
Tobias K.
2
É possível capturar erros nos módulos atualizados, quando você quebra o requiremanipulador de atualizações do HMR em um bloco try-catch.
Tobias K.
10

A resposta aceita expalain tudo correto de qualquer maneira a descrição a seguir ajuda a entender o que é HMR rapidamente.

A substituição do Hot Module é uma das mais recentes técnicas de desenvolvimento de javascript que atrai a atenção dos desenvolvedores. Ajuda no desenvolvimento, reduzindo o número de atualizações de página, substituindo os módulos por mudanças no tempo de execução.

Ao pesquisar sobre o HMR, encontrei um artigo que explica o conceito na internet. Você pode obtê-lo aqui e adicionar uma imagem GIF que explica o conceito sem muita explicação.

Aqui está o trabalho - observe que o timer não é redefinido para 0 como seria após o recarregamento de uma página e o css também altera a atualização automática. GIF de substituição de módulo quente

O Webpack ajuda a obter o HMR. Você pode encontrar documentos aqui

Ajuda a alcançar os seguintes

  • Reter o estado do aplicativo perdido durante uma recarga completa.

  • Economize um tempo valioso de desenvolvimento atualizando apenas o que mudou.

  • Ajuste o estilo mais rapidamente - quase comparável à mudança de estilos no depurador do navegador.

Aqui está o guia do webpack para obter o HMR

samuelj90
fonte