Hot Reload — egy olyan technológia, amelynél a forráskód változtatásai az oldal teljes újratöltése nélkül és az aktuális állapot elvesztése nélkül kerülnek alkalmazásra a futó alkalmazásban. Ellentétben a Live Reload-dal, amely egyszerűen frissíti a teljes oldalt, a forró újratöltés csak a módosított modulokat cseréli ki menet közben. A Webpack, 2024 szerint a Hot Module Replacement (HMR) akár 80%-kal is csökkenti a fejlesztési ciklus idejét a komponensek állapotának megőrzésével.
Főbb pontok
Hot Reload — egy olyan fejlesztési mechanizmus, amelynél a forrásfájlok változtatásai azonnal megjelennek a futó alkalmazásban annak újraindítása nélkül. A fejlesztő szerkeszti a kódot a szerkesztőben, elmenti a fájlt, és az eredmény azonnal látható a böngészőben vagy emulátorban.
A technológia kulcsfontosságú tulajdonsága az alkalmazás állapotának megőrzése. A memóriában lévő változók, az űrlapok adatai, az aktuális navigáció — minden a helyén marad. A fejlesztőnek nem kell megismételnie a műveletsort a kívánt képernyőre való visszatéréshez.
A webes fejlesztésben a Hot Reload a Hot Module Replacement (HMR) mechanizmuson keresztül valósul meg. A bundler figyeli a fájlváltozásokat, meghatározza, mely modulok érintettek, és elküldi a frissített kódot a böngészőbe WebSocketen keresztül. A böngésző csak azokat a modulokat cseréli ki az oldal újratöltése nélkül.
A Hot Reload népszerűsége az egyoldalas alkalmazások (SPA) elterjedésével nőtt meg, ahol az oldal teljes újratöltése elpusztítja a kliensalkalmazás teljes állapotát. A React, Vue, Angular és más keretrendszerek a HMR-t ajánlják elsŝleges fejlesztési módként.
A HMR mechanizmus négy szakaszból áll. A szerver oldali bundler lefordítja a módosított modult, létrehoz egy JSON-javítást a kód új verziójával, és elküldi a böngészőbe WebSocket-kapcsolaton keresztül. A böngésző részén a HMR runtime megkapja a javítást, lecseréli a régi modult az újra, és értesíti a modul feliratkozóit.
A Webpack Dev Server WebSocketet használ a klienssel való kommunikációhoz. Fájlváltoztatáskor a bundler létrehozza a hot-update.js és hot-update.json fájlokat a változások manifesztumával. A kliens automatikusan betölti ezeket a fájlokat JSONP-n keresztül.
// webpack.config.js - HMR beállítás
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
devServer: {
hot: true,
liveReload: false
},
plugins: [new HtmlWebpackPlugin()]
};
A böngészőben a HMR runtime ellenőrzi, hogy a lecserélendő modul támogatja-e az accept-ot. Ha a modul deklarálta a module.hot.accept()-et, a runtime helyben lecseréli és elindítja a frissítési visszahívást. Ha az accept nincs deklarálva, a HMR visszaesik a magasabb szintre, a szülő modulhoz.
A React Fast Refresh-ben ez a logika keretrendszer szinten van beépítve — nem kell kézzel írni a module.hot.accept-et minden fájlban. A Babel-plugin react-refresh/babel olyan kódot ad hozzá, amely biztonságosan cseréli ki a komponenseket állapotvesztés nélkül.
Ezt a három kifejezést gyakran összekeverik, de viselkedésükben gyökeresen különböznek. A Live Reload minden változtatásnál újratölti a teljes oldalt — minden állapot elveszik. A Full Reload a fejlesztőszerver teljes újraindításakor történik, nemcsak a kliens, hanem a szerver állapotának elvesztésével.
| Típus | Oldal újratöltése | Állapot megőrzése | Sebesség |
|---|---|---|---|
| Hot Reload (HMR) | Nem | Igen | Azonnali |
| Live Reload | Igen | Nem | 1-3 mp |
| Full Reload | Igen | Nem | 3-10 mp |
A Hot és Live közötti választás közvetlenül befolyásolja a fejlesztési sebességet. HMR-nél a «megváltoztattam a kódot → láttam az eredményt» ciklus 50-200 ms-ig tart. Live Reload-nál — 1-3 másodperc plusz a kontextus helyreállításának ideje. Egy munkanap során a különbség tízperces megtakarított időt jelent.
React Fast Refresh — a Hot Reload hivatalos megvalósítása, optimalizálva React komponensekre. Lecserélte a régi React Hot Loader mechanizmust, amely instabil volt és kézi konfigurációt igényelt. A Fast Refresh be van építve a Create React App, Next.js, Vite és Webpack környezetekbe a react-refresh/babel segítségével.
A Fast Refresh helyesen megőrzi a funkcionális komponensek állapotát a kód megváltoztatásakor. Ha csak a JSX jelölést változtatja meg — a useState és más hookok megtartják értékeiket. Ha a hook logikája változik — a komponens újramountolása történik.
// Példa - az állapot megmarad, amikor a JSX változik
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>
);
}
A Fast Refresh nem őrzi meg az állapotot, ha az új kód fordítási hibát tartalmaz. Ha a komponens nem alapértelmezetten (default), hanem név szerint (named export) van exportálva, az állapot szintén elveszhet. Javasolt a default export használata a komponensekhez, és az exportok memo-ba csomagolása, ha garantálni kell az állapot megőrzését.
A modern bundlerek HMR-t biztosítanak. A Webpack — a HMR útörője rugalmas konfigurációval a devServer.hot segítségével. A Vite natív ESM-et és esbuild-ot használ azonnali HMR-hez bundling nélkül. A Parcel — nulla konfigurációs HMR. A Turbopack — az új bundler a Verceltől HMR-rel Rust-ban.
| Eszköz | HMR típus | Konfiguráció | Ökoszisztéma |
|---|---|---|---|
| Webpack 5 | HMR WebSocketen keresztül | devServer.hot: true | React, Vue, Angular |
| Vite | Natív ESM HMR | Dobozból | React, Vue, Svelte |
| Parcel 2 | Nulla konfigurációs HMR | Nem szükséges | React, Vue, TS |
| Turbopack | Növekményes HMR | Dobozból | Next.js |
A Vite sebességével tűnik ki — a HMR a Vite-ban a böngésző natív ES moduljain keresztül működik. Fájlváltoztatáskor a Vite csak azt a modult küldi el import()-on keresztül, a teljes projekt újrafordítása nélkül. A Webpack minden modult teljesen lefordít, ami nagy projektekben lelassítja a HMR-t.
Nézzük meg a HMR beállítását különböző bundlerekhez. A Webpack-ben be kell állítani a hot: true értéket a devServer-ben, és hozzá kell adni a react-refresh/babel-t. A Vite-ban a HMR dobozból működik bármilyen preset-tel. A Next.js-ben a Fast Refresh alapértelmezetten engedélyezve van a turbófordítón keresztül.
// 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'
}
]
}
};
A HMR nem minden forgatókönyvben működik helyesen. A CSS-modulok dinamikus osztályokkal előfordulhat, hogy nem érvényesülnek. A globális változók és szingletonok (Redux store, router) visszaállíthatódhatnak újratöltéskor. A nehéz könyvtárak HMR-nél néha memóriaszivárgást okoznak a modulok GC nélküli cseréje miatt.
A HMR-problémák megoldása — a forró kódot mellékhatások nélküli tiszta komponensekbe kell izolálni. A mellékhatásokat (WebSocket-feliratkozások, időzítők) a useEffect-ben kell megtisztítani. A Redux-hoz javasolt egy persister, amely az állapotot sessionStorage-ban menti. Az olyan CSS-megoldások, mint a CSS Modules vagy a styled-components, további konfiguráció nélkül helyesen működnek a HMR-rel.
Egy másik korlát — hibakeresés éles környezetben: a HMR szándékosan ki van kapcsolva az éles fordításban. A forráskód minifikálásra kerül, és a forró csere éles környezetben lehetetlen. A hibakereséshez éles környezetben source mapokat és naplózást használnak, de nem HMR-t.
Gyakran ismételt kérdések
A Hot Reload csak a módosított modult cseréli ki az oldal újratöltése nélkül és megőrzi az állapotot. A Live Reload a teljes oldalt újratölti — az állapot elveszik, az alkalmazás a kezdőképernyőről indul újra.
A Create React App és Vite projektjeiben a HMR alapértelmezetten be van kapcsolva. Webpack-ben hozzá kell adni a devServer: { hot: true } és a @pmmmwh/react-refresh-webpack-plugin kódot. Next.js-ben a Fast Refresh konfiguráció nélkül működik.
Az ok — fordítási hiba az új kódban, named export default helyett, a hook aláírásának megváltoztatása vagy az állapot közvetlen mutálása. A React Fast Refresh csak akkor állítja vissza biztonságosan a komponenst, ha az a helyes működéshez szükséges.
Igen, minden modern bundler támogatja a HMR-t TypeScript-tel. A Vite esbuild-ot használ a TS transzpilálásához. Webpack — ts-loader-t vagy babel-t @babel/preset-typescript-tel. A Fast Refresh helyesen működik típusos komponensekkel.
Ellenőrizze a böngésző konzolját WebSocket-kapcsolati hibákra. Győződjön meg arról, hogy a devServer.hot: true be van kapcsolva. Vite esetén ellenőrizze a HMR-portot. Ha a probléma nem oldódik meg — végezzen teljes oldalújratöltést (F5) és ellenőrizze a bundler konzolját.
Összefoglaló
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is