🔥 پیشفروش دوره جدید: جاوااسکریپت برای React و Next.js 🧑🏻💻 با ۲۰٪ تخفیف ویژه در دوران پیشتولید همراه من باش. بعد از شروع ضبط، افزایش قیمت داریمهااا 📈🤗
npm run dev چطور کار میکنه؟ بررسی کامل Dev Server و HMR
npm run dev چطور کار میکنه؟ بررسی کامل Dev Server و HMR
مقدمه: فراتر از یک دستور ساده
اکثر برنامهنویسها فکر میکنن npm run dev فقط یک میانبر برای اجرا شدن پروژه هست.
اما حقیقت اینه که این دستور، شروع یک ارکستر سمفونیک هماهنگ بین سیستمعامل، محیط Node.js، فایلسیستم و مرورگر شماست. بیا این فرآیند رو لایه به لایه بشکافیم.
۱. لایه اول: شِل (Shell) و جستجو برای npm
وقتی اینتر رو میزنی، اولین کسی که بیدار میشه Shell سیستم عاملات هست (Zsh, Bash یا PowerShell).
شل در متغیر محیطی PATH دنبال فایلی به نام npm میگرده.
وقتی پیداش کرد، یک فرآیند جدید برای اجراش میسازه.
npm خودش یک پکیج Node.js هست. پس Node.js اجرا میشه تا کدهای npm رو تفسیر کنه.
مسیر اجرای دستور npm run dev از shell تا npm CLI و dev server
۲. لایه دوم: نقشه راه در package.json
حالا npm وارد پوشه پروژه میشه و سراغ فایل قلب پروژه یعنی package.json میره.
بخش scripts رو نگاه میکنه.
وقتی فیلد dev رو پیدا کرد، مقدار جلوش رو میخونه (مثلاً vite یا next dev).
نکته جالب: npm به صورت موقت پوشهی node_modules/.bin رو به ابتدای PATH اضافه میکنه. چرا؟ تا اگر vite رو در سیستم نصب نداری ولی در پروژه هست، بدون مشکل اجرا بشه.
۳. لایه سوم: تولد Dev Server (قلب تپنده توسعه)
حالا اسکریپتی مثل Vite اجرا میشه. اینجا جایی هست که Dev Server متولد میشه. برخلاف سرورهای قدیمی (مثل Webpack که اول کل پروژه رو باندل میکرد)، ابزارهای مدرن مثل Vite از استراتژی Unbundled Dev Server استفاده میکنن.
چرا سرعت Vite بالاست؟ چون از esbuild استفاده میکنه. esbuild با زبان Go نوشته شده و سرعتش در تبدیل کدها (Transform) وحشتناک بالاست.
فایلهای تایپاسکریپت و JSX در لحظه (On-the-fly) به جاوااسکریپت تبدیل میشن.
وابستگیهای سنگین (مثل React یا Lodash) یکبار برای همیشه Pre-bundle میشن تا مرورگر رو با هزاران درخواست ریز اذیت نکنن.
۴. لایه چهارم: مرورگر و جادوی ES Modules
اینجاست که جادوی اصلی اتفاق میوفته. وقتی آدرس localhost:5173 را باز میکنی:
۱. مرورگر یک درخواست برای فایل index.html میفرسته.
۲. داخل HTML، یک تگ اسکریپت با تایپ ماژول وجود دارد:
۳. مرورگر چون type="module" رو میبینه، میفهمه که نباید منتظر یک فایل غولپیکر باشه. خودش شروع میکنه به درخواست دادن برای تکتک ایمپورتهای داخل اون فایل.
<scripttype="module"src="/src/main.tsx"></script>
نمودار module graph در Vite dev server هنگام لود شدن ES module ها در مرورگر
۵. لایه پنجم: گراف ماژولها (The Module Graph)
سرور فقط یک توزیعکننده فایل ساده نیست. اون یک نقشه (Graph) از تمام فایلها و وابستگیهاشون داره.
اگر فایلی رو درخواست کنی که هنوز پردازش نشده، سرور همون لحظه اون رو پردازش و تحویل میده.
اگر فایلی در حافظه (Cache) باشه، سریعاً همون رو برمیگردونه.
۶. لایه ششم: File Watcher و پایان انتظار برای رفرش
وقتی برنامه نویس عزیز کد رو تغییر میده و Ctrl+S رو برای ذخیره میزنه:
۱. سیستمعامل تغییر فایل رو حس میکنه (از طریق الگوریتمهایی مثل inotify یا chokidar ).
۲. سرور متوجه میشه کدوم گره (Node) در گراف ماژولها تغییر کرده.
۳. سرور فقط و فقط همون فایل رو دوباره پردازش میکنه.
۷. لایه هفتم: HMR و Fast Refresh (جراحی زنده کد)
به جای رفرش کردن کل صفحه، سرور پیامی از طریق WebSocket به مرورگر میفرسته میگه: «هی! فایل Button.tsx عوض شد، نسخهی جدیدش اینجاست!» مرورگر با استفاده از HMR (Hot Module Replacement)، نسخه قدیمی کامپوننت رو با نسخه جدید جایگزین میکنه.
React Fast Refresh اینجا نقش کلیدی داره:
فرآیند Hot Module Replacement و React Fast Refresh پس از تغییر فایل در dev server
اگر کدت فقط تغییرات ظاهری داشته باشه، حالت (State) کامپوننت (مثلاً عددی که در Counter بود) حفظ میشه.
شما تغییر رو میبینید بدون اینکه دیتای فرم یا اسکرول صفحه بپره.
جمعبندی: چرا باید اینها رو بدونیم؟
درک این فرآیند به تو کمک میکنه که وقتی پروژهات سنگین شد، بفهمی چرا کند شده. یا وقتی یک خطای عجیب در مورد “MIME type” یا “Module not found” میگیری، دقیقاً بدونی مشکل در لایه esbuild است، یا آدرسدهی مرورگر، یا تنظیمات Dev Server.
خیلی مقالات دیگه مثل این توی مقالهخونه نوشتم که ۱۰۰ درصد میتونه بهت کمک کنه تا دانشات رو چند سطح بالا ببری 💪.