Hot Reload è una tecnologia grazie alla quale le modifiche al codice sorgente vengono applicate a un'applicazione in esecuzione senza ricaricare completamente la pagina e senza perdere lo stato corrente. A differenza di Live Reload, che semplicemente aggiorna l'intera pagina, la ricarica a caldo sostituisce solo i moduli modificati al volo. Secondo Webpack, 2024, Hot Module Replacement (HMR) riduce il tempo del ciclo di sviluppo fino all'80% preservando lo stato dei componenti.
Punti chiave
Hot Reload è un meccanismo di sviluppo grazie al quale le modifiche ai file sorgente vengono immediatamente riflesse in un'applicazione in esecuzione senza riavviarla. Lo sviluppatore modifica il codice nell'editor, salva il file e il risultato è immediatamente visibile nel browser o nell'emulatore.
La caratteristica principale di questa tecnologia è la preservazione dello stato dell'applicazione. Le variabili in memoria, i dati nei moduli, la navigazione corrente — tutto rimane al suo posto. Lo sviluppatore non deve ripetere una sequenza di azioni per tornare alla schermata richiesta.
Nello sviluppo web, Hot Reload viene implementato attraverso il meccanismo Hot Module Replacement (HMR). Il bundler monitora le modifiche ai file, determina quali moduli sono interessati e invia il codice aggiornato al browser tramite WebSocket. Il browser sostituisce solo quei moduli senza ricaricare la pagina.
La popolarità di Hot Reload è decollata con la diffusione delle applicazioni a pagina singola (SPA), dove un ricaricamento completo della pagina distrugge tutto lo stato dell'applicazione client. React, Vue, Angular e altri framework raccomandano HMR come modalità di sviluppo principale.
Il meccanismo HMR si compone di quattro fasi. Il bundler sul lato server compila il modulo modificato, genera una patch JSON con la nuova versione del codice e la invia al browser tramite una connessione WebSocket. Il runtime HMR lato browser riceve la patch, sostituisce il vecchio modulo con quello nuovo e notifica gli iscritti al modulo.
Webpack Dev Server utilizza WebSocket per comunicare con il client. Quando un file cambia, il bundler genera hot-update.js e hot-update.json con un manifesto delle modifiche. Il client carica automaticamente questi file tramite JSONP.
// webpack.config.js - configurazione HMR
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
devServer: {
hot: true,
liveReload: false
},
plugins: [new HtmlWebpackPlugin()]
};
Il runtime HMR nel browser verifica se il modulo sostituito supporta accept. Se il modulo ha dichiarato module.hot.accept(), il runtime lo sostituisce sul posto ed esegue il callback di aggiornamento. Se accept non è dichiarato, HMR risale al livello del modulo padre.
In React Fast Refresh, questa logica è integrata a livello di framework — non è necessario scrivere manualmente module.hot.accept in ogni file. Il plugin Babel react-refresh/babel aggiunge codice che sostituisce i componenti in modo sicuro senza perdere lo stato.
Questi tre termini vengono spesso confusi, ma differiscono radicalmente nel comportamento. Live Reload ricarica l'intera pagina ad ogni modifica — tutto lo stato viene perso. Full Reload si verifica quando il server di sviluppo viene riavviato completamente, perdendo non solo lo stato del client ma anche quello del server.
| Tipo | Ricarica pagina | Preservazione stato | Velocità |
|---|---|---|---|
| Hot Reload (HMR) | No | Sì | Istantaneo |
| Live Reload | Sì | No | 1-3 sec |
| Full Reload | Sì | No | 3-10 sec |
La scelta tra Hot e Live influisce direttamente sulla velocità di sviluppo. Con HMR, il ciclo “modifica codice → vedi risultato” richiede 50-200 ms. Con Live Reload — 1-3 secondi più il tempo di ripristino del contesto. Nell'arco di una giornata lavorativa, la differenza ammonta a decine di minuti di tempo risparmiato.
React Fast Refresh è l'implementazione ufficiale di Hot Reload ottimizzata per i componenti React. Ha sostituito il vecchio meccanismo React Hot Loader, che era instabile e richiedeva configurazione manuale. Fast Refresh è integrato in Create React App, Next.js, Vite e Webpack tramite react-refresh/babel.
Fast Refresh preserva correttamente lo stato dei componenti funzionali quando il loro codice cambia. Se si modifica solo il markup JSX, useState e gli altri hook mantengono i loro valori. Se la logica dell'hook cambia, il componente viene rimontato.
// Esempio - stato preservato quando JSX cambia
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
);
}
Fast Refresh non preserva lo stato se il nuovo codice contiene un errore di compilazione. Se il componente non viene esportato di default (named export), lo stato potrebbe anche non essere preservato. Si consiglia di utilizzare export default per i componenti e avvolgere le esportazioni in memo se è necessario garantire la preservazione dello stato.
I bundler moderni forniscono HMR. Webpack è il pioniere di HMR con configurazione flessibile tramite devServer.hot. Vite utilizza ESM nativo ed esbuild per HMR istantaneo senza bundling. Parcel offre HMR zero-config. Turbopack è un nuovo bundler di Vercel con HMR basato su Rust.
| Strumento | Tipo di HMR | Configurazione | Ecosistema |
|---|---|---|---|
| Webpack 5 | HMR tramite WebSocket | devServer.hot: true | React, Vue, Angular |
| Vite | HMR con ESM nativo | Integrato | React, Vue, Svelte |
| Parcel 2 | HMR zero-config | Non richiesto | React, Vue, TS |
| Turbopack | HMR incrementale | Integrato | Next.js |
Vite si distingue per velocità — HMR in Vite funziona tramite i moduli ES nativi del browser. Quando un file cambia, Vite invia solo quel modulo tramite import(), senza ricompilare l'intero progetto. Webpack compila ogni modulo interamente, rallentando HMR nei progetti di grandi dimensioni.
Vediamo la configurazione di HMR per diversi bundler. In Webpack, è necessario impostare hot: true in devServer e aggiungere react-refresh/babel. In Vite, HMR funziona integrato con qualsiasi preset. In Next.js, Fast Refresh è abilitato per impostazione predefinita tramite il turbocompilatore.
// vite.config.js
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
server: {
hmr: {
port: 3001
}
}
});
// webpack.config.js
const ReactRefreshWebpackPlugin =
require('@pmmmwh/react-refresh-webpack-plugin');
module.exports = {
mode: 'development',
devServer: { hot: true },
plugins: [new ReactRefreshWebpackPlugin()],
module: {
rules: [
{
test: /\.jsx?$/u,
use: 'babel-loader'
}
]
}
};
HMR non funziona correttamente in tutti gli scenari. I moduli CSS con classi dinamiche potrebbero non essere applicati. Le variabili globali e i singleton (store Redux, router) possono resettarsi al ricaricamento. Le librerie pesanti con HMR a volte possono generare perdite di memoria a causa della sostituzione dei moduli senza GC.
La soluzione ai problemi di HMR è isolare il codice caldo in componenti puri senza effetti collaterali. Gli effetti collaterali (abbonamenti WebSocket, timer) devono essere puliti in useEffect. Per Redux, si consiglia un persister che salvi lo stato in sessionStorage. Le soluzioni CSS come CSS Modules o styled-components funzionano correttamente con HMR senza configurazione aggiuntiva.
Un'altra limitazione è il debug in produzione: HMR è intenzionalmente disabilitato nelle build di produzione. Il codice sorgente è minimizzato e la sostituzione a caldo in produzione è impossibile. Per eseguire il debug degli errori in produzione, utilizzare source map e registrazione, ma non HMR.
Domande frequenti
Hot Reload sostituisce solo il modulo modificato senza ricaricare la pagina e preserva lo stato. Live Reload ricarica l'intera pagina — lo stato viene perso, l'applicazione riparte dalla schermata iniziale.
Nei progetti che utilizzano Create React App e Vite, HMR è abilitato per impostazione predefinita. In Webpack, è necessario aggiungere devServer: { hot: true } e @pmmmwh/react-refresh-webpack-plugin. In Next.js, Fast Refresh funziona senza configurazione.
La causa è un errore di compilazione nel nuovo codice, un named export invece di default, un cambiamento nella firma dell'hook o una mutazione diretta dello stato. React Fast Refresh resetta il componente in modo sicuro solo quando necessario per il corretto funzionamento.
Sì, tutti i bundler moderni supportano HMR con TypeScript. Vite utilizza esbuild per la transpilazione di TS. Webpack utilizza ts-loader o babel con @babel/preset-typescript. Fast Refresh funziona correttamente con componenti tipizzati.
Controllare la console del browser per errori di connessione WebSocket. Assicurarsi che devServer.hot: true sia abilitato. Per Vite, controllare la porta HMR. Se il problema persiste, eseguire un ricaricamento completo della pagina (F5) e controllare la console del bundler.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche