Hot Reload — este tehnologia prin care modificările din codul sursă sunt aplicate aplicației în funcțiune fără reîncărcarea completă a paginii și fără pierderea stării curente. Spre deosebire de Live Reload, care pur și simplu reîncarcă întreaga pagină, reîncărcarea la cald înlocuiește doar modulele modificate din mers. Conform Webpack, 2024, Hot Module Replacement (HMR) reduce timpul ciclului de dezvoltare cu până la 80% datorită păstrării stării componentelor.
Principale
Hot Reload — este un mecanism de dezvoltare în care modificările din fișierele sursă se reflectă imediat în aplicația în funcțiune fără repornirea acesteia. Dezvoltatorul modifică codul în editor, salvează fișierul, iar rezultatul este imediat vizibil în browser sau emulator.
Proprietatea cheie a tehnologiei este păstrarea stării aplicației. Variabilele în memorie, datele din formulare, navigarea curentă — totul rămâne la locul său. Dezvoltatorul nu trebuie să repete secvența de acțiuni pentru a reveni la ecranul necesar.
În dezvoltarea web, Hot Reload este implementat prin mecanismul Hot Module Replacement (HMR). Bundlerul urmărește modificările fișierelor, determină ce module sunt afectate și trimite codul actualizat în browser prin WebSocket. Browserul înlocuiește doar acele module fără reîncărcarea paginii.
Popularitatea Hot Reload a explodat odată cu răspândirea aplicațiilor cu o singură pagină (SPA), unde reîncărcarea completă a paginii distruge întreaga stare a aplicației client. React, Vue, Angular și alte framework-uri recomandă HMR ca mod principal de dezvoltare.
Mecanismul HMR constă din patru etape. Bundlerul de partea serverului compilează modulul modificat, creează un pachet JSON cu noua versiune a codului și îl trimite în browser prin conexiunea WebSocket. Partea de browser HMR runtime primește pachetul, înlocuiește modulul vechi cu cel nou și notifică abonații modulului.
Webpack Dev Server utilizează WebSocket pentru comunicarea cu clientul. La modificarea fișierului, bundlerul creează hot-update.js și hot-update.json cu manifestul modificărilor. Clientul încarcă automat aceste fișiere prin JSONP.
// webpack.config.js - configurarea HMR
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
devServer: {
hot: true,
liveReload: false
},
plugins: [new HtmlWebpackPlugin()]
};
HMR runtime în browser verifică dacă modulul înlocuit suportă accept. Dacă modulul a declarat module.hot.accept(), runtime îl înlocuiește in-place și rulează callback-ul de actualizare. Dacă accept nu este declarat, HMR coboară la nivelul superior, la modulul părinte.
În React Fast Refresh această logică este integrată la nivel de framework — nu este nevoie să scrieți manual module.hot.accept în fiecare fișier. Babel-plugin react-refresh/babel adaugă cod care înlocuiește în siguranță componentele fără pierderea stării.
Aceste trei terminii sunt adesea confundate, dar diferă radical prin comportament. Live Reload reîncarcă întreaga pagină la orice modificare — toată starea se pierde. Full Reload are loc la repornirea completă a serverului de dezvoltare cu pierderea nu doar a stării clientului, ci și a stării serverului.
| Tip | Reîncărcarea paginii | Păstrarea stării | Viteză |
|---|---|---|---|
| Hot Reload (HMR) | Nu | Da | Instantaneu |
| Live Reload | Da | Nu | 1-3 sec |
| Full Reload | Da | Nu | 3-10 sec |
Alegerea între Hot și Live influențează direct viteza de dezvoltare. La HMR, ciclul „am modificat codul → am văzut rezultatul” durează 50-200 ms. La Live Reload — 1-3 secunde plus timpul de restaurare a contextului. Pe parcursul zilei de lucru, diferența reprezintă zeci de minute de timp economisit.
React Fast Refresh — implementarea oficială a Hot Reload optimizată pentru componentele React. A înlocuit vechiul mecanism React Hot Loader, care era instabil și necesita configurare manuală. Fast Refresh este integrat în Create React App, Next.js, Vite și Webpack prin react-refresh/babel.
Fast Refresh păstrează corect starea componentelor funcționale la modificarea codului lor. Dacă modificați doar marcajul JSX — useState și alte hook-uri își păstrează valorile. Dacă se modifică logica hook-ului — are loc remontarea componentului.
// Exemplu - starea păstrată când JSX se schimbă
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 nu păstrează starea dacă noul cod conține eroare de compilare. Dacă componentul nu este exportat implicit (named export), starea poate fi, de asemenea, pierdută. Se recomandă utilizarea default export pentru componente și împachetarea exporturilor în memo dacă trebuie garantată păstrarea stării.
Bundlerele moderne oferă HMR. Webpack — pionierul HMR cu configurare flexibilă prin devServer.hot. Vite utilizează ESM nativ și esbuild pentru HMR instantaneu fără bundling. Parcel — HMR cu configurare zero. Turbopack — noul bundler de la Vercel cu HMR pe Rust.
| Instrument | Tip HMR | Configurare | Ecosistem |
|---|---|---|---|
| Webpack 5 | HMR prin WebSocket | devServer.hot: true | React, Vue, Angular |
| Vite | Native ESM HMR | Din cutie | React, Vue, Svelte |
| Parcel 2 | Zero-config HMR | Nu este necesar | React, Vue, TS |
| Turbopack | Incremental HMR | Din cutie | Next.js |
Vite se remarcă prin viteză — HMR în Vite funcționează prin modulele ES native ale browserului. La modificarea fișierului, Vite trimite doar acel modul prin import(), fără recompilarea întregului proiect. Webpack compilează fiecare modul în întregime, ceea ce încetinește HMR în proiectele mari.
Să analizăm configurarea HMR pentru diferite bundlere. În Webpack trebuie să setați hot: true în devServer și să adăugați react-refresh/babel. În Vite HMR funcționează din cutie cu orice preset. În Next.js Fast Refresh este activat implicit prin turbocompilator.
// 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 nu funcționează corect în toate scenariile. Modulele CSS cu clase dinamice pot să nu se aplice. Variabilele globale și singleton-urile (Redux store, router) se pot reseta la reîncărcare. Bibliotecile grele la HMR generează uneori scurgeri de memorie din cauza înlocuirii modulelor fără GC.
Solutia problemelor HMR — izolarea codului la cald în componente pure fără efecte secundare. Efectele secundare (abonamente WebSocket, temporizatoare) trebuie curățate în useEffect. Pentru Redux se recomandă un persister care salvează starea în sessionStorage. Soluțiile CSS precum CSS Modules sau styled-components funcționează corect cu HMR fără configurări suplimentare.
O altă limitare — debugarea în producție: HMR este intenționat dezactivat în compilarea de producție. Codul sursă este minificat, iar înlocuirea la cald în producție este imposibilă. Pentru depanarea erorilor în producție se utilizează source maps și logare, dar nu HMR.
Întrebări frecvente
Hot Reload înlocuiește doar modulul modificat fără reîncărcarea paginii și păstrează starea. Live Reload reîncarcă întreaga pagină — starea se pierde, aplicația pornește din nou de la ecranul inițial.
În proiectele pe Create React App și Vite, HMR este activat implicit. În Webpack trebuie să adăugați devServer: { hot: true } și @pmmmwh/react-refresh-webpack-plugin. În Next.js Fast Refresh funcționează fără configurare.
Cauza — eroare de compilare în codul nou, named export în loc de default, modificarea semnăturii hook-ului sau mutarea directă a stării. React Fast Refresh resetează în siguranță componentul doar atunci când este necesar pentru funcționarea corectă.
Da, toate bundlerele moderne suportă HMR cu TypeScript. Vite utilizează esbuild pentru transpilarea TS. Webpack — ts-loader sau babel cu @babel/preset-typescript. Fast Refresh funcționează corect cu componente tipizate.
Verificați consola browserului pentru erori de conexiune WebSocket. Asigurați-vă că devServer.hot: true este activat. Pentru Vite verificați portul HMR. Dacă problema persistă — efectuați o reîncărcare completă a paginii (F5) și verificați consola bundlerului.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și