Hot Reload هي تقنية يتم من خلالها تطبيق التغييرات في الكود المصدري على التطبيق قيد التشغيل دون إعادة تحميل كاملة للصفحة ودون فقدان الحالة الحالية. على عكس Live Reload، الذي يقوم ببساطة بتحديث الصفحة بأكملها، فإن إعادة التحميل الساخن تستبدل فقط الوحدات المعدلة أثناء التشغيل. وفقًا لـ Webpack، 2024، يقلل Hot Module Replacement (HMR) من وقت دورة التطوير بنسبة تصل إلى 80% من خلال الحفاظ على حالة المكونات.
أهم النقاط
Hot Reload هي آلية تطوير يتم من خلالها عكس التغييرات في الملفات المصدرية فورًا في التطبيق قيد التشغيل دون إعادة تشغيله. يقوم المطور بتحرير الكود في المحرر، وحفظ الملف، وتكون النتيجة مرئية فورًا في المتصفح أو المحاكي.
الخاصية الرئيسية لهذه التقنية هي الحفاظ على حالة التطبيق. المتغيرات في الذاكرة، البيانات في النماذج، التنقل الحالي — كل شيء يبقى في مكانه. لا يحتاج المطور إلى تكرار تسلسل الإجراءات للعودة إلى الشاشة المطلوبة.
في تطوير الويب، يتم تطبيق Hot Reload من خلال آلية Hot Module Replacement (HMR). تقوم أداة التجميع بمراقبة تغييرات الملفات، وتحديد الوحدات المتأثرة، وإرسال الكود المحدث إلى المتصفح عبر WebSocket. يستبدل المتصفح تلك الوحدات فقط دون إعادة تحميل الصفحة.
ارتفعت شعبية Hot Reload مع انتشار تطبيقات الصفحة الواحدة (SPA)، حيث تؤدي إعادة تحميل الصفحة بالكامل إلى تدمير حالة تطبيق العميل بالكامل. توصي React و Vue و Angular وغيرها من الأطر باستخدام HMR كوضع التطوير الأساسي.
تتكون آلية HMR من أربع مراحل. تقوم أداة التجميع على جانب الخادم بتجميع الوحدة المعدلة، وإنشاء تصحيح JSON بالإصدار الجديد من الكود، وإرساله إلى المتصفح عبر اتصال WebSocket. يستقبل وقت تشغيل HMR في المتصفح التصحيح، ويستبدل الوحدة القديمة بالجديدة، ويُعلم المشتركين في الوحدة.
يستخدم Webpack Dev Server WebSocket للتواصل مع العميل. عندما يتغير ملف، تقوم أداة التجميع بإنشاء hot-update.js و hot-update.json مع قائمة بالتغييرات. يقوم العميل بتحميل هذه الملفات تلقائيًا عبر JSONP.
// webpack.config.js - إعداد HMR
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
devServer: {
hot: true,
liveReload: false
},
plugins: [new HtmlWebpackPlugin()]
};
يتحقق وقت تشغيل HMR في المتصفح مما إذا كانت الوحدة المستبدلة تدعم accept. إذا أعلنت الوحدة عن module.hot.accept()، يستبدلها وقت التشغيل في مكانها ويشغل رد اتصال التحديث. إذا لم يتم إعلان accept، يتراجع HMR إلى مستوى الوحدة الأصلية.
في React Fast Refresh، هذا المنطق مدمج على مستوى الإطار — لا حاجة لكتابة module.hot.accept يدويًا في كل ملف. يضيف إضافة Babel react-refresh/babel كودًا يستبدل المكونات بأمان دون فقدان الحالة.
غالبًا ما يتم الخلط بين هذه المصطلحات الثلاثة، لكنها تختلف جذريًا في السلوك. Live Reload يعيد تحميل الصفحة بأكملها عند أي تغيير — يتم فقدان كل الحالة. Full Reload يحدث عند إعادة تشغيل خادم التطوير بالكامل، مما يفقد ليس فقط حالة العميل ولكن أيضًا حالة الخادم.
| النوع | إعادة تحميل الصفحة | الحفاظ على الحالة | السرعة |
|---|---|---|---|
| Hot Reload (HMR) | لا | نعم | فوري |
| Live Reload | نعم | لا | 1-3 ثانية |
| Full Reload | نعم | لا | 3-10 ثانية |
يؤثر الاختيار بين Hot و Live مباشرة على سرعة التطوير. مع HMR، تستغرق دورة «تحرير الكود → رؤية النتيجة» من 50 إلى 200 مللي ثانية. مع Live Reload — من 1 إلى 3 ثوانٍ بالإضافة إلى وقت استعادة السياق. على مدار يوم العمل، يشكل الفرق عشرات الدقائق من الوقت الموفر.
React Fast Refresh هو التطبيق الرسمي لـ Hot Reload المُحسّن لمكونات React. لقد حل محل الآلية القديمة React Hot Loader، التي كانت غير مستقرة وتتطلب تكوينًا يدويًا. Fast Refresh مدمج في Create React App و Next.js و Vite و Webpack عبر react-refresh/babel.
يحافظ Fast Refresh بشكل صحيح على حالة المكونات الوظيفية عندما يتغير كودها. إذا قمت فقط بتغيير ترميز JSX، فإن useState والخطافات الأخرى تحتفظ بقيمها. إذا تغير منطق الخطاف، يتم إعادة تركيب المكون.
// مثال - الحالة محفوظة عندما يتغير JSX
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 على الحالة إذا كان الكود الجديد يحتوي على خطأ في التجميع. إذا لم يتم تصدير المكون بشكل افتراضي (named export)، فقد لا يتم الحفاظ على الحالة أيضًا. يوصى باستخدام export default للمكونات وتغليف الصادرات في memo إذا كنت بحاجة إلى ضمان الحفاظ على الحالة.
توفر أدوات التجميع الحديثة HMR. Webpack هو الرائد في HMR مع تكوين مرن عبر devServer.hot. Vite يستخدم ESM الأصلي و esbuild لـ HMR فوري دون تجميع. Parcel يقدم HMR بدون تكوين. Turbopack هو أداة تجميع جديدة من Vercel مع HMR قائم على Rust.
| الأداة | نوع HMR | التكوين | النظام البيئي |
|---|---|---|---|
| Webpack 5 | HMR عبر WebSocket | devServer.hot: true | React, Vue, Angular |
| Vite | HMR عبر ESM الأصلي | مدمج | React, Vue, Svelte |
| Parcel 2 | HMR بدون تكوين | غير مطلوب | React, Vue, TS |
| Turbopack | HMR تدريجي | مدمج | Next.js |
يتميز Vite بالسرعة — يعمل HMR في Vite من خلال وحدات ES الأصلية في المتصفح. عندما يتغير ملف، يرسل Vite تلك الوحدة فقط عبر import()، دون إعادة تجميع المشروع بأكمله. يقوم Webpack بتجميع كل وحدة بالكامل، مما يبطئ HMR في المشاريع الكبيرة.
دعنا نلقي نظرة على إعداد HMR لأدوات التجميع المختلفة. في Webpack، تحتاج إلى تعيين hot: true في devServer وإضافة react-refresh/babel. في Vite، يعمل HMR مدمجًا مع أي إعداد مسبق. في Next.js، Fast Refresh مفعل افتراضيًا عبر المترجم التوربيني.
// 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 بشكل صحيح في جميع السيناريوهات. وحدات CSS ذات الفئات الديناميكية قد لا تُطبق. المتغيرات العامة والمفردات (مخزن Redux، الموجه) قد تُعاد تعيينها عند إعادة التحميل. المكتبات الثقيلة مع HMR قد تولد أحيانًا تسربًا للذاكرة بسبب استبدال الوحدات دون جمع القمامة.
حل مشاكل HMR هو عزل الكود الساخن في مكونات نقية دون آثار جانبية. يجب تنظيف الآثار الجانبية (اشتراكات WebSocket، المؤقتات) في useEffect. لـ Redux، يوصى باستخدام مثبت يحفظ الحالة في sessionStorage. تعمل حلول CSS مثل CSS Modules أو styled-components بشكل صحيح مع HMR دون تكوين إضافي.
قيد آخر هو التصحيح في الإنتاج: يتم تعطيل HMR عمدًا في إصدارات الإنتاج. الكود المصدري مصغر، والاستبدال الساخن في الإنتاج مستحيل. لتصحيح الأخطاء في الإنتاج، استخدم خرائط المصدر والتسجيل، ولكن ليس HMR.
الأسئلة الشائعة
Hot Reload يستبدل فقط الوحدة المعدلة دون إعادة تحميل الصفحة ويحافظ على الحالة. يقوم Live Reload بإعادة تحميل الصفحة بأكملها — يتم فقدان الحالة، ويبدأ التطبيق من جديد من الشاشة الأولية.
في المشاريع التي تستخدم Create React App و Vite، HMR مفعل افتراضيًا. في Webpack، تحتاج إلى إضافة devServer: { hot: true } و @pmmmwh/react-refresh-webpack-plugin. في Next.js، يعمل Fast Refresh بدون تكوين.
السبب هو خطأ في التجميع في الكود الجديد، أو named export بدلاً من default، أو تغيير في توقيع الخطاف، أو تحوير مباشر للحالة. يقوم React Fast Refresh بإعادة تعيين المكون بأمان فقط عندما يكون ذلك ضروريًا للتشغيل الصحيح.
نعم، جميع أدوات التجميع الحديثة تدعم HMR مع TypeScript. Vite يستخدم esbuild لترجمة TS. يستخدم Webpack ts-loader أو babel مع @babel/preset-typescript. يعمل Fast Refresh بشكل صحيح مع المكونات المكتوبة.
تحقق من وحدة تحكم المتصفح بحثًا عن أخطاء اتصال WebSocket. تأكد من تفعيل devServer.hot: true. لـ Vite، تحقق من منفذ HMR. إذا استمرت المشكلة، قم بإجراء إعادة تحميل كاملة للصفحة (F5) وتحقق من وحدة تحكم أداة التجميع.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا