Bundler — ابزار ساخت و سازی است که ماژولهای متعدد JavaScript را در یک یا چند فایل برای استفاده در مرورگر یا اپلیکیشن موبایل ترکیب میکند. باندلرهای مدرن (Webpack, Metro, Vite) نه تنها فایلها را میچسبانند، بلکه ترانسپایل، مینیفای و بهینهسازی منابع را نیز انجام میدهند. بر اساس Webpack Concepts (2026)، پیکربندی صحیح باندلر اندازه بیلد را 40–60٪ بدون کاهش عملکرد کاهش میدهد.
نکات اصلی
Bundler (بستهبند ماژول) — ابزاری خط فرمان است که نقطه ورودی (entry point) — فایل اصلی اپلیکیشن — را دریافت کرده و به صورت بازگشتی تمام وابستگیهای آن را پیمایش میکند و گراف ماژولها را میسازد. در خروجی، باندلر یک یا چند فایل تولید میکند که میتوانند در صفحه HTML گنجانده شوند یا در اپلیکیشن موبایل اجرا شوند.
مرورگرها برای مدت طولانی از سیستم ماژول JavaScript در سطح پلتفرم پشتیبانی نمیکردند. Bundler این مشکل را حل میکرد و صدها import و require را به یک فایل تبدیل میکرد. امروزه، حتی با پشتیبانی بومی از ماژولهای ES در مرورگرها، باندلرها وظایف اضافی انجام میدهند: ترانسپایل JSX و TypeScript، مینیفای کد، code splitting برای بارگذاری تنبل و hot module replacement (HMR) برای تسریع توسعه.
در توسعه اپلیکیشن موبایل، React Native از Metro به عنوان باندلر پیشفرض استفاده میکند و Flutter از سیستم ساخت و ساز مبتنی بر Dart خود استفاده میکند. انتخاب باندلر مستقیماً بر سرعت توسعه، اندازه اپلیکیشن و عملکرد زمان اجرا تأثیر میگذارد.
باندلینگ چندین مرحله را طی میکند: تجزیه فایلهای ورودی، ساخت گراف وابستگی، تبدیل ماژولها و تولید فایلهای خروجی. در هر مرحله، باندلر لودرهایی برای تبدیل کد منبع و پلاگینهایی برای بهینهسازی اعمال میکند.
باندلر از نقطه ورودی شروع میکند، فایل را میخواند و AST (درخت نحو انتزاعی) میسازد. از AST تمام عملگرهای import و require استخراج میشوند. برای هر import پیدا شده، باندلر فرآیند را به صورت بازگشتی تکرار میکند تا زمانی که تمام وابستگیها در یک گراف واحد جمعآوری شوند.
// پیادهسازی سادهشده باندلر
const fs = require('fs');
const path = require('path');
function buildGraph(entry) {
const content = fs.readFileSync(entry, 'utf-8');
const imports = content.match(/require\(['"](.+?)['"]\)/g);
const modulePath = path.resolve(path.dirname(entry), imports[0]);
return { entry, content, deps: [buildGraph(modulePath)] };
}
پس از ساخت گراف، باندلر لودرها را اعمال میکند — تبدیلهایی که فایلها را به JavaScript تبدیل میکنند: TypeScript → JS، SCSS → CSS، JSX → توابع JSX. سپس پلاگینها تبدیلهای اضافی را انجام میدهند: مینیفای، درونخطی کردن تصاویر، تولید service worker.
باندلرها به سه نسل تقسیم میشوند: کلاسیک، تخصصی و نسل جدید مبتنی بر ماژولهای ES. هر نوع معماری و حوزه کاربری خاص خود را دارد.
Webpack — رایجترین باندلر با اکوسیستم عظیم. مزیت اصلی آن انعطافپذیری است: هزاران لودر و پلاگین تقریباً هر سناریوی ساخت و سازی را پوشش میدهند. Parcel رویکرد zero-config را ارائه میدهد و به طور خودکار تبدیلهای لازم را بر اساس پسوند فایلها تعیین میکند. هر دو باندلر از code splitting و HMR پشتیبانی میکنند.
Metro به طور خاص برای React Native ساخته شده است و فقط با JavaScript و TypeScript کار میکند. معماری آن برای توسعه موبایل بهینه شده است: پشتیبانی از inline requires، بارگذاری ناهمگام ماژولها و یکپارچهسازی با Hermes engine. Rollup برای کتابخانهها و بستههای npm طراحی شده است و خروجی ماژول ES تمیز بدون بستهبندی اضافی تولید میکند.
انتخاب باندلر به پلتفرم و نیازهای پروژه بستگی دارد. Webpack همهکاره است اما نیاز به پیکربندی دقیق دارد. Metro برای React Native بدون جایگزین است. Vite سریعترین توسعه را به لطف ماژولهای بومی ES فراهم میکند.
| ویژگی | Webpack | Metro | Vite |
|---|---|---|---|
| پلتفرم | وب، همهکاره | React Native | وب، همهکاره |
| سرعت بیلد توسعه | متوسط | زیاد | بسیار زیاد |
| Code splitting | بله | بله | بله |
| HMR | بله | Fast Refresh | HMR آنی |
| اکوسیستم پلاگین | عظیم | محدود | در حال رشد |
| پیکربندی | پیچیده | ساده | ساده |
| پشتیبانی TypeScript | از طریق لودرها | داخلی | داخلی |
Vite از esbuild برای پیشباندل کردن وابستگیها و از Rollup برای بیلد تولیدی استفاده میکند که 5–10 برابر افزایش سرعت نسبت به Webpack در حالت توسعه میدهد. Metro از اهداف وب پشتیبانی نمیکند اما یکپارچهسازی بیدرز با React Native bridge و Turbo Modules فراهم میکند.
پیکربندی باندلر تعیین میکند که انواع مختلف فایلها چگونه پردازش شوند، بیلد کجا تولید شود و چه بهینهسازیهایی اعمال شود. فایل پیکربندی معمولی شامل نقطه ورودی، قوانین برای ماژولها، پلاگینها و تنظیمات خروجی است.
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js',
clean: true,
},
module: {
rules: [
{
test: /\.(js|jsx|ts|tsx)$/,
exclude: /node_modules/,
use: { loader: 'babel-loader', options: { presets: ['@babel/preset-react'] } },
},
{ test: /\.css$/, use: ['style-loader', 'css-loader'] },
],
},
plugins: [new HtmlWebpackPlugin({ template: './public/index.html' })],
devServer: { port: 3000, hot: true },
};
Metro از فایلهای جداگانه metro.config.js و babel.config.js برای پیکربندی استفاده میکند. برخلاف Webpack، پیکربندی Metro بسیار سادهتر است زیرا باندلر برای React Native تخصصی شده است و نیازی به پیکربندی لودر برای استایلها یا تصاویر ندارد.
حتی توسعهدهندگان با تجربه با خطاهای باندلینگ مواجه میشوند. Duplicate module — یکی از رایجترین مشکلات، وقتی یک وابستگی به دلیل ناسازگاری نسخهها در package.json چندین بار به باندل وارد میشود. Module not found زمانی رخ میدهد که مسیر import نادرست باشد یا بسته نصب نشده باشد.
Metro با محدودیت اندازه باندل برای دستگاههای موبایل مواجه است. هنگام تجاوز از حد 2–5 مگابایت، خطای Unable to resolve module به دلیل کمبود حافظه روی دستگاه رخ میدهد. راهحل — استفاده از inline requires و RAM bundles برای بارگذاری تنبل ماژولها. Metro همچنین به symlinkها حساس است، بنابراین برای مونورپوزیتوریها پیکربندی اضافی watchFolders در تنظیمات مورد نیاز است.
برای Webpack مشکل معمول — Module parse failed زمانی که فایل فرمت غیرمنتظرهای دارد یا لودر لازم وجود ندارد. بررسی پسوند فایل و افزودن قانون مربوطه در module.rules مشکل را حل میکند. استفاده از source-map-explorer به پیدا کردن ماژولهای تکراری و وابستگیهای اضافی در باندل نهایی کمک میکند.
بیلد کند — یکی از مشکلات اصلی هنگام کار با باندلرها. برای تسریع از persistent caching استفاده کنید که نتایج تبدیل ماژولها را بین اجراها ذخیره میکند. Webpack 5 از کش فایلسیستمی از طریق cache: { type: 'filesystem' } پشتیبانی میکند، Vite از esbuild برای پیشباندلینگ استفاده میکند و Metro به کش ماژول در RAM متکی است. همچنین exclude را برای node_modules در لودرها تنظیم کنید تا بستههای آماده دوباره پردازش نشوند.
Code splitting — تقسیم باندل به بخشهایی که در صورت نیاز بارگذاری میشوند. باندلرهای مختلف این استراتژی را به شیوه خود پیادهسازی میکنند. Webpack از import پویا import() پشتیبانی میکند که برای هر ماژول بخشهای جداگانه ایجاد میکند. Metro از inline requires برای بارگذاری تأخیری استفاده میکند. Vite به طور خودکار vendor-chunks و importهای پویا را بدون پیکربندی اضافی تقسیم میکند. انتخاب استراتژی به نیازهای پروژه بستگی دارد: برای اپلیکیشنهای موبایل باندلهای اولیه کوچکتر با بارگذاری تنبل ترجیح داده میشوند.
برای عملکرد صحیح code splitting در React Native پیکربندی اضافی مورد نیاز است: Metro باید برای کار با بخشهای ناهمگام از طریق inlineRequires پیکربندی شود. در Webpack و Vite code splitting با استفاده از سینتکس پویای import() که به طور خودکار نقاط تقسیم را ایجاد میکند، خارج از جعبه کار میکند. برای حداکثر کارایی، code splitting را با راهنماییهای preload از طریق <link rel="preload"> برای بخشهای حیاتی ترکیب کنید.
سوالات متداول
برای پروژههای ساده بدون JSX، TypeScript یا ماژولهای CSS میتوان با ماژولهای ES بومی در مرورگر کار کرد. اما برای بیلد تولیدی، باندلر مینیفای، tree shaking و code splitting را فراهم میکند که برای عملکرد حیاتی هستند. بدون باندلر حفظ معماری ماژولار در پروژههای بزرگ دشوار است.
برای React Native — Metro (تنها گزینه پشتیبانیشده). برای اپلیکیشنهای وب — Vite برای پروژههای جدید (به دلیل سرعت) یا Webpack برای پروژههای موجود با اکوسیستم غنی. برای کتابخانهها و بستههای npm — Rollup، زیرا خروجی ماژول ES تمیز تولید میکند.
Bundler مستقیماً اندازه باندل JS نهایی را تعیین میکند. Webpack با tree shaking میتواند اندازه را 30–50٪ کاهش دهد. Metro برای React Native از Hermes bytecode پشتیبانی میکند که اندازه را 20–30٪ در مقایسه با JavaScript معمولی کاهش میدهد. Code splitting امکان بارگذاری ماژولها در صورت نیاز را فراهم میکند و باندل اولیه را کاهش میدهد.
برای وب باندلر کدی سازگار با مرورگرهای مختلف تولید میکند و از CSS، تصاویر و فونتها پشتیبانی میکند. برای پلتفرمهای موبایل Metro کد برای موتور JavaScript (Hermes یا JSC) تولید میکند، CSS یا HTML را پردازش نمیکند و بیلد را برای منابع محدود دستگاه بهینه میکند.
بله، پروژههایی وجود دارند که از Webpack برای بخش وب و Metro برای React Native استفاده میکنند — مثلاً در مخازن یکپارچه با پایه کد مشترک. اما این کار پیکربندی CI/CD را پیچیده میکند و نیاز به همگامسازی نسخههای وابستگی دارد. توصیه میشود در صورت امکان از یک باندلر واحد برای همه اهداف استفاده کنید.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید