Frameworkها، Build Toolها و Bundlerها

در فصل بیست‌وچهارم دیدیم که Server Components بدون Framework عملاً قابل اجرا نیستند. حالا یک گام عقب‌تر می‌رویم و پرسش پایه‌تری را بررسی می‌کنیم: کدی که ما می‌نویسیم (JSX، importهای متعدد، CSS، شاید TypeScript) چگونه به چیزی تبدیل می‌شود که مرورگر بتواند اجرا کند؟ در این درس، سه واژه‌ای که اغلب به‌جای هم به کار می‌روند را از هم جدا می‌کنیم: Bundler، Build Tool و Framework.

مشکل: مرورگر کد ما را مستقیم نمی‌فهمد

فایلی که در فصل‌های قبل نوشتیم، چند چیز دارد که مرورگر به‌تنهایی از آن‌ها سر در نمی‌آورد:

  • JSX: همان‌طور که در درس ۱-۳ دیدیم، JSX جاوااسکریپت معتبر نیست و باید به فراخوانی توابع تبدیل شود.
  • importهای متعدد: یک برنامه واقعی صدها فایل دارد. بارگذاری هر فایل با یک درخواست جدا، کند است.
  • فایل‌های غیرجاوااسکریپتی: نوشتن import "./App.css" داخل یک فایل جاوااسکریپت، در مرورگر به‌تنهایی معنای استانداردی ندارد.
  • TypeScript: مرورگر آن را اجرا نمی‌کند و باید به جاوااسکریپت تبدیل شود.

Bundler: تبدیل و بسته‌بندی ماژول‌ها

Bundler ابزاری است که از یک فایل ورودی شروع می‌کند، گراف همه importها را دنبال می‌کند و خروجی‌ای می‌سازد که مرورگر بتواند اجرا کند. کارهای رایج آن:

  • تبدیل کد: JSX و TypeScript به جاوااسکریپت ساده (معمولاً با کمک ابزارهایی مثل Babel، SWC یا esbuild). در React مدرن، JSX با Transform خودکار به فراخوانی‌هایی از react/jsx-runtime تبدیل می‌شود و دیگر لازم نیست در هر فایل React را import کنیم.
  • بسته‌بندی: جمع کردن ماژول‌ها در تعداد کمی فایل بهینه.
  • Tree-shaking: حذف کدی که import شده ولی هرگز استفاده نمی‌شود.
  • Minification: کوچک کردن حجم فایل خروجی.
  • Code Splitting: همان چیزی که در فصل بیستم دیدیم؛ هر import() پویا به یک تکه جدا تبدیل می‌شود. این کار را Bundler انجام می‌دهد، نه خود React.
  • پردازش فایل‌های دیگر: CSS، تصویر، فونت. اینجاست که import "./App.css" معنا پیدا می‌کند.

نمونه‌های شناخته‌شده شامل Webpack (قدیمی و بسیار قابل‌پیکربندی)، Rollup، esbuild (بسیار سریع) و Rspack (سازگار با Webpack) هستند.

Build Tool: همه ابزار توسعه در یک بسته

Bundler به‌تنهایی فقط بسته‌بندی می‌کند. هنگام نوشتن کد، به چیزهای بیشتری نیاز داریم: یک سرور توسعه که تغییر فایل را همان لحظه در مرورگر نشان بدهد، پیکربندی آماده، سیستم افزونه‌ها و یک دستور Build برای نسخه نهایی. به ابزاری که این‌ها را کنار هم می‌گذارد، Build Tool می‌گویند. مستندات رسمی React سه نمونه را نام می‌برد: Vite، Parcel و Rsbuild.

در حالت توسعه، این ابزارها معمولاً با Hot Reload یا Fast Refresh کار می‌کنند: با ذخیره یک فایل، فقط همان بخش به‌روز می‌شود و تلاش می‌شود State کامپوننت‌ها حفظ شود. این همان مفهوم Identity و State Preservation فصل دوازدهم است، با این تفاوت که اینجا ابزار Build آن را برای راحتی توسعه به کار می‌برد.

یک نمونه عملی: شروع با Vite

html
npm create vite@latest my-app -- --template react
cd my-app
npm install
npm run dev
jsx
// src/main.jsx
import { createRoot } from "react-dom/client";
import App from "./App.jsx";
import "./index.css";

createRoot(document.getElementById("root")).render(<App />);

در این فایل، سه چیز را Build Tool مدیریت می‌کند: JSX، importهای فایل‌های جاوااسکریپتی و import فایل CSS. برای ساختن نسخه نهایی (Production) معمولاً دستور npm run build اجرا می‌شود که فایل‌های بهینه‌شده را در یک پوشه خروجی می‌سازد. نکته درباره TypeScript: این ابزارها معمولاً فقط نوع‌ها را حذف می‌کنند و خود بررسی نوع، با ابزار جداگانه‌ای مثل tsc انجام می‌شود.

Framework: یک لایه بالاتر

Build Tool یک برنامه ساده Client-only (SPA) تحویل می‌دهد. اما یک برنامه واقعی به چیزهای دیگری هم نیاز دارد که Build Tool خودش آن‌ها را تعیین نمی‌کند. مستندات رسمی React درباره Create React App این کمبودها را صریحاً بیان کرده است: ابزار از پیش، راه‌حلی برای Routing، دریافت داده و Code Splitting ارائه نمی‌دهد. Framework دقیقاً همین خلأ را پر می‌کند: Routing، رندر سرور، دریافت داده، قراردادهای فایل و تصمیم‌های Build (که در درس ۲۴-۸ دیدیم). برای مثال، React Router در حالت Framework روی Vite ساخته شده، پس Framework می‌تواند خودش از یک Build Tool استفاده کند.

تصویر لایه‌ای

html
Framework   (Next.js، React Router، Expo، ...)
   ← Routing، رندر سرور، دریافت داده، قراردادهای فایل
Build Tool  (Vite، Parcel، Rsbuild، ...)
   ← سرور توسعه، پیکربندی، افزونه‌ها، دستور Build
Bundler / Compiler  (Rollup، esbuild، Rspack، SWC، ...)
   ← تبدیل و بسته‌بندی ماژول‌ها

این مرزبندی یک مدل ذهنی است، نه یک تعریف دقیق: بعضی ابزارها چند لایه را با هم ارائه می‌دهند (مثلاً Parcel هم Bundler است و هم تجربه Build Tool دارد)، و Frameworkها معمولاً ابزار Build خودشان را از پیش پیکربندی‌شده همراه می‌آورند.

وضعیت Create React App

Create React App سال‌ها راه استاندارد شروع پروژه بود. تیم React در فوریه ۲۰۲۵ آن را برای پروژه‌های جدید منسوخ (Deprecated) اعلام کرد. این ابزار در حالت نگه‌داری باقی مانده و برای React 19 هم نسخه‌ای منتشر شده، اما توصیه رسمی، برای پروژه‌های موجود، مهاجرت به یک Framework یا یک Build Tool مثل Vite، Parcel یا Rsbuild است. اگر در آموزش‌های قدیمی‌تر به npx create-react-app برخوردید، آن را روش پیشنهادی امروز ندانید.

کدام را کی انتخاب کنیم

  • Framework: اگر Routing، رندر سرور، دریافت داده و استقرار را یک‌جا و آماده می‌خواهید. مستندات رسمی هم می‌گوید بیشتر برنامه‌ها از Framework سود می‌برند.
  • Build Tool به‌تنهایی: اگر محدودیت‌های خاص دارید، می‌خواهید خودتان تصمیم بگیرید چه ابزاری برای Routing و داده استفاده کنید، یا فقط می‌خواهید بفهمید یک برنامه React از پایه چگونه کار می‌کند.
  • Bundler مستقیم: معمولاً فقط وقتی لازم است که خودتان در حال ساختن ابزار یا Framework هستید.

مقایسه عمیق‌تر Library در برابر Framework در درس ۲۵-۸، و معیار انتخاب نهایی در درس ۲۵-۹ بررسی می‌شود.

چرا این درس مثال قابل اجرا ندارد

این درس درباره ابزارهایی است که فایل‌های پروژه را روی دیسک می‌خوانند و می‌سازند؛ در ویرایشگر درون‌صفحه‌ای قابل نمایش نیستند. برای دیدن آن‌ها، دستورهای بالا را در یک پوشه واقعی روی سیستم خودتان اجرا کنید.

جمع‌بندی

مرورگر JSX، TypeScript و importهای غیراستاندارد را مستقیم نمی‌فهمد. Bundler گراف importها را دنبال می‌کند و کد را تبدیل، بسته‌بندی، کوچک و تکه‌تکه می‌کند. Build Tool مثل Vite، Parcel و Rsbuild، سرور توسعه، پیکربندی و دستور Build را کنار Bundler می‌گذارد. Framework لایه بالاتری است که Routing، رندر سرور، دریافت داده و قراردادها را اضافه می‌کند. Create React App برای پروژه‌های جدید منسوخ شده و توصیه رسمی، Framework یا یک Build Tool است. در درس بعدی، به Routing در اکوسیستم React می‌پردازیم.