Substituição de módulo quente no Redux
Publicados: 2022-03-11Este é 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!
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:
- O aplicativo solicita que o tempo de execução do HMR verifique se há atualizações.
- O runtime baixa as atualizações de forma assíncrona e notifica o aplicativo.
- O aplicativo então pede ao tempo de execução para aplicar as atualizações.
- O runtime aplica as atualizações de forma síncrona.
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:
- Modifique o código que potencialmente causa o bug.
- Atualize a página, adicione o item específico à loja.
- 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.
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.