Substituição de módulo quente no Redux

Publicados: 2022-03-11

Este é um exemplo mínimo de substituição de módulo quente (ou HMR) em um aplicativo Redux. O código de demonstração funcional está hospedado no GitHub. Incluímos apenas as configurações essenciais para oferecer suporte ao HMR, facilitando a aplicação do HMR em seu próprio aplicativo Redux.

Se você não pode esperar para aplicar o HMR, vá para esta seção para configurar o HMR para seu projeto em cinco minutos!

Demonstração de substituição de módulo quente

Execute o exemplo

Suje as mãos primeiro! Antes de executar os comandos para iniciar este aplicativo de exemplo, certifique-se de que Git, Node.js e Yarn estejam instalados corretamente em sua máquina.

 $ git clone https://github.com/Front-end-io/articles.git $ cd articles && git checkout redux-hmr $ yarn install $ yarn start

Então visite http://localhost:3000/ para ver se funciona.

Ao escrever seu código, a substituição do módulo a quente é capaz de atualizar a página sem uma atualização completa. Mais importante, o estado Redux é mantido enquanto outros recursos foram atualizados no local.

Substituição do módulo quente

A substituição de módulos a quente é um dos recursos mais úteis oferecidos pelo Webpack. Ele permite que todos os tipos de módulos, incluindo arquivos JSON, CSS e JS, sejam atualizados em tempo de execução sem a necessidade de uma atualização completa.

Veja como funciona internamente:

  1. O aplicativo solicita que o tempo de execução do HMR verifique se há atualizações.
  2. O runtime baixa as atualizações de forma assíncrona e notifica o aplicativo.
  3. O aplicativo então pede ao tempo de execução para aplicar as atualizações.
  4. O runtime aplica as atualizações de forma síncrona.

Diagrama de substituição do módulo quente

O HMR aumenta a produtividade ao desenvolver um aplicativo Redux. Redux é um contêiner de estado previsível para aplicativos JavaScript. É um framework de última geração muito popular baseado em React. Redux, por definição do primeiro princípio do Redux, é um armazenamento de dados compartilhado singular, descrito por sua documentação como uma “fonte única de verdade”. O armazenamento de dados (um objeto JavaScript simples atualizado por reducers ) será atualizado à medida que o usuário operar no aplicativo. Cada operação do usuário, como clicar em um botão, carregar dados de back-end, etc., provavelmente atualizará a loja várias vezes. Não é fácil corrigir um bug quando o bug ocorre apenas com um instantâneo específico do estado.

O HMR nos permite atualizar a página sem reinicializar o armazenamento global. Durante o desenvolvimento do Redux, podemos querer inspecionar a loja após uma série de operações. Um cenário muito comum é que um bug ocorre somente depois que adicionamos um item específico (talvez complexo) à loja. Sem HMR, temos que fazer os seguintes passos:

  1. Modifique o código que potencialmente causa o bug.
  2. Atualize a página, adicione o item específico à loja.
  3. Se os bugs persistirem, repita a Etapa 1.

A iteração acima será repetida várias vezes se o bug for difícil de encontrar. No mundo real, o bug só pode aparecer depois de mais operações. O HMR nos ajuda a compilar e aplicar o código modificado, mantendo o valor de armazenamento atual inalterado. Não precisamos repetir o Passo 2. Ele aumenta a eficiência do desenvolvimento.

Corrigir um bug não significa que você precisa reiniciar o aplicativo, com HMR.

Nota: Em alguns casos, a modificação do código pode afetar o valor de armazenamento atual. Nesse caso, o HMR o avisará para recarregar a página inteira.

Recurso neste exemplo

Queremos manter o recurso mínimo, apenas para demonstrar o recurso HMR. Portanto, neste aplicativo, não incorporamos recursos comuns em um aplicativo React, incluindo redux-logger, react-router-redux, redux-thunk, redux-devtools, etc. Enquanto isso, mantemos apenas um redutor, duas ações e 1 página.

Nosso aplicativo mantém apenas um valor de contador na loja. Temos apenas uma página chamada home , que exibe o valor do contador e dois botões para aumentar/diminuir o valor do contador.

Para confirmar que o HMR funciona, basta aumentar/diminuir o contador várias vezes e depois modificar algum código. Por exemplo, modifique o título Counter to Counter na loja . Então encontraremos que:

  • A página não é atualizada.
  • O valor do contador exibido NÃO É ALTERADO.
  • O título foi alterado para Contador na loja .

‍ Configure o HMR em cinco minutos

Para configurar o HMR, siga estas etapas.

Bibliotecas essenciais

Estas bibliotecas devem ser instaladas para suportar HMR:

  • react-hot-loader@^4.2.0: Compile e atualize o aplicativo React em tempo real.
  • webpack-dev-server@^3.1.4: Exibe um aplicativo Webpack. Atualiza o navegador sobre as alterações.

ES6

Se você estiver usando ECMAScript6 (quem não está, hoje em dia?), você precisa de mais algumas ferramentas para compilar o ES6 em tempo real. Primeiro, este é o arquivo de configuração ES6 mínimo .babelrc:

 { "env": { "development": { "presets": [ "react-hmre" ] } } }

Para suportar a compilação em tempo real, esta biblioteca é necessária:

  • babel-preset-react-hmre@^1.1.1

Webpack.config.js

Precisamos configurar o HMR no arquivo de configuração do Webpack webpack.config.js.

Primeiramente, habilite o plugin HMR na seção de plugins:

 "plugins": [ … new webpack.NamedModulesPlugin(), new webpack.HotModuleReplacementPlugin(), ]

O plugin HMR gera um Manifest, um arquivo JSON listando os módulos atualizados, e um Update, um arquivo JSON contendo os dados a serem aplicados. O que deve ser observado é que o HMR é uma opção fornecida pelo Webpack. Carregadores como o style-loader, que implementam a interface HMR, recebem uma atualização por meio do HMR e depois substituem o código antigo pelo novo.

Se estivermos usando webpack-dev-server, precisamos ativar o hot flag na seção devServer:

 "devServer": [ ... hot: true, ]

Recarregue a quente os redutores Redux

A partir do Redux versão 2.0.0, os redutores não são recarregados a quente implicitamente porque o recarregamento a quente implícito causa alguns problemas. Se o seu estado Redux for redefinido para os valores iniciais quando atualizado a quente, tente habilitar a atualização a quente para os redutores:

 import { createStore } from 'redux'; import rootReducer from '../reducers/index'; export default function configureStore(initialState) { const store = createStore(rootReducer, initialState); if (module.hot) { // Enable Webpack hot module replacement for reducers module.hot.accept('../reducers', () => { const nextRootReducer = require('../reducers/index'); store.replaceReducer(nextRootReducer); }); } return store; }

Configurações avançadas

Para configurações mais avançadas do HMR, consulte a API do HMR.

Corre

Por fim, execute o aplicativo com:

 $ ./node_modules/.bin/webpack-dashboard -- webpack-dev-server

Solução de problemas

HMR simplesmente não aplica as alterações

O HMR pode falhar silenciosamente sem nenhum aviso. Quando você atualiza o código e salva, a página simplesmente não atualiza. Isso provavelmente ocorre porque seu sistema não permite que você observe tantas alterações de arquivos.

No Ubuntu, você pode executar sysctl -a | grep inotify sysctl -a | grep inotify para visualizar o valor user.max_inotify_watches atual. Tente aumentar esse número executando: sudo sysctl fs.inotify.max_user_watches=524288 . Como alternativa, anexe uma nova linha fs.inotify.max_user_watches=524288 ao arquivo sudo vim /etc/sysctl.conf e execute sudo sysctl -p /etc/sysctl.conf para aplicar a alteração.