Bundler هي أداة بناء تجمع وحدات JavaScript متعددة في ملف واحد أو عدة ملفات لاستخدامها في المتصفح أو التطبيق المحمول. لا تقوم أدوات التجميع الحديثة (Webpack, Metro, Vite) بدمج الملفات فحسب، بل تقوم أيضاً بالترجمة والتصغير وتحسين الموارد. وفقاً لـ Webpack Concepts (2026)، فإن الإعداد الصحيح لأداة التجميع يقلل حجم البناء بنسبة 40–60% دون فقدان الوظائف.
النقاط الرئيسية
Bundler (أداة تجميع الوحدات) — هي أداة سطر أوامر تأخذ نقطة دخول — الملف الرئيسي للتطبيق — وتجتاز recursively جميع تبعياتها، ببناء رسم بياني للوحدات. عند الإخراج، تقوم الأداة بإنشاء ملف واحد أو أكثر يمكن تضمينها في صفحة HTML أو تشغيلها في تطبيق محمول.
لم تكن المتصفحات تدعم نظام الوحدات في JavaScript على مستوى المنصة لفترة طويلة. Bundler حل هذه المشكلة بتحويل المئات من import و require إلى ملف واحد. اليوم، حتى مع الدعم الأصلي لوحدات ES في المتصفحات، تقوم أدوات التجميع بمهام إضافية: الترجمة (transpilation) لـ JSX و TypeScript، تصغير الكود، تقسيم الكود (code splitting) للتحميل البطيء و الاستبدال السريع للوحدات (HMR) لتسريع التطوير.
في تطوير التطبيقات المحمولة، يستخدم React Native Metro كأداة تجميع افتراضية، بينما يستخدم Flutter نظام البناء الخاص به المبني على Dart. يؤثر اختيار أداة التجميع مباشرة على سرعة التطوير وحجم التطبيق وأداء وقت التشغيل.
التجميع يمر بعدة مراحل: تحليل ملفات الإدخال، بناء الرسم البياني للتبعيات، تحويل الوحدات وتوليد ملفات الإخراج. في كل مرحلة، تطبق أداة التجميع اللوادر (loaders) لتحويل الكود المصدري والإضافات (plugins) للتحسين.
تبدأ أداة التجميع من نقطة الدخول، تقرأ الملف وتبني AST (شجرة التركيب المجردة). من AST، تستخرج جميع عبارات import و require. لكل import يتم العثور عليه، تكرر الأداة العملية recursively حتى يتم جمع جميع التبعيات في رسم بياني واحد.
// تنفيذ مبسط لأداة التجميع
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. ثم تقوم الإضافات (plugins) بتحويلات إضافية: التصغير، تضمين الصور، توليد service worker.
أدوات التجميع تنقسم إلى ثلاثة أجيال: كلاسيكية، متخصصة، والجيل الجديد المبني على وحدات ES. كل نوع له هيكله الخاص ومجال تطبيقه.
Webpack — أشهر أداة تجميع مع نظام بيئي ضخم. ميزته الرئيسية هي المرونة: الآلاف من اللوادر والإضافات تغطي أي سيناريو بناء تقريباً. Parcel يقدم نهج zero-config، حيث يكتشف تلقائياً التحويلات اللازمة بناءً على امتدادات الملفات. كلتا الأداتين تدعمان تقسيم الكود و HMR.
Metro تم إنشاؤه خصيصاً لـ React Native ويعمل فقط مع JavaScript و TypeScript. هيكله محسّن لتطوير التطبيقات المحمولة: دعم inline requires، التحميل غير المتزامن للوحدات والتكامل مع محرك Hermes. Rollup موجه للمكتبات وحزم npm، ويولد مخرجات وحدات ES نظيفة بدون أغلفة غير ضرورية.
يعتمد اختيار أداة التجميع على المنصة ومتطلبات المشروع. Webpack متعدد الاستخدامات لكنه يتطلب إعداداً مفصلاً. Metro هو الخيار الوحيد لـ React Native. Vite يوفر أسرع تجربة تطوير بفضل وحدات ES الأصلية.
| الخاصية | Webpack | Metro | Vite |
|---|---|---|---|
| المنصة | ويب، عالمية | React Native | ويب، عالمية |
| سرعة بناء التطوير | متوسطة | عالية | عالية جداً |
| تقسيم الكود | نعم | نعم | نعم |
| HMR | نعم | Fast Refresh | HMR فوري |
| النظام البيئي للإضافات | ضخم | محدود | متنامي |
| الإعداد | معقد | بسيط | بسيط |
| دعم TypeScript | عبر اللوادر | مدمج | مدمج |
Vite يستخدم esbuild للتجميع المسبق للتبعيات و Rollup لبناءات الإنتاج، مما يوفر تحسيناً في السرعة بمقدار 5–10 مرات مقارنة بـ Webpack في وضع التطوير. Metro لا يدعم أهداف الويب لكنه يوفر تكاملاً سلساً مع جسر React Native و 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 يحدث عندما يكون مسار الاستيراد غير صحيح أو لم يتم تثبيت الحزمة.
Metro محدود بأحجام الحزمة للأجهزة المحمولة. عند تجاوز الحد 2–5 ميجابايت، يظهر خطأ Unable to resolve module بسبب عدم كفاية الذاكرة على الجهاز. الحل — استخدام inline requires و RAM bundles للتحميل البطيء للوحدات. Metro حساس أيضاً للروابط الرمزية، لذلك تتطلب المستودعات المتعددة إعداداً إضافياً watchFolders في الإعداد.
بالنسبة لـ Webpack، المشكلة النموذجية هي Module parse failed، والتي تحدث عندما يكون للملف تنسيق غير متوقع أو يكون اللودر المطلوب مفقوداً. التحقق من امتداد الملف وإضافة القاعدة المناسبة في module.rules يحل المشكلة. استخدام source-map-explorer يساعد في العثور على الوحدات المكررة والتبعيات الزائدة في الحزمة النهائية.
البناء البطيء — من المشكلات الرئيسية عند العمل مع أدوات التجميع. للتسريع، استخدم التخزين المؤقت المستمر (persistent caching) الذي يحفظ نتائج تحويل الوحدات بين عمليات التشغيل. Webpack 5 يدعم التخزين المؤقت للملفات عبر cache: { type: 'filesystem' }، Vite يستخدم esbuild للتجميع المسبق، و Metro يعتمد على التخزين المؤقت للوحدات في الذاكرة. بالإضافة إلى ذلك، حدد exclude لـ node_modules في اللوادر لتجنب معالجة الحزم الجاهزة مرة أخرى.
تقسيم الكود (code splitting) — تقسيم الحزمة إلى أجزاء يتم تحميلها حسب الطلب. تطبق أدوات التجميع المختلفة هذه الاستراتيجية بطريقتها الخاصة. Webpack يدعم الاستيراد الديناميكي import()، مما يخلق أجزاء منفصلة لكل وحدة. Metro يستخدم inline requires للتحميل المؤجل. Vite يقسم تلقائياً vendor chunks والاستيرادات الديناميكية دون إعداد إضافي. يعتمد اختيار الاستراتيجية على متطلبات المشروع: للتطبيقات المحمولة، يفضل حزم أولية أصغر مع تحميل بطيء.
لتشغيل code splitting بشكل صحيح في React Native، يلزم إعداد إضافي: يجب تكوين Metro للعمل مع الأجزاء غير المتزامنة عبر inlineRequires. في Webpack و Vite، يعمل code splitting بشكل افتراضي عند استخدام الصيغة الديناميكية import()، والتي تنشئ تلقائياً نقاط تقسيم. لتحقيق أقصى كفاءة، ادمج code splitting مع تلميحات التحميل المسبق عبر <link rel="preload"> للأجزاء الحرجة.
الأسئلة الشائعة
للمشاريع البسيطة بدون JSX أو TypeScript أو وحدات CSS، يمكنك استخدام وحدات ES الأصلية في المتصفح. ومع ذلك، لبناءات الإنتاج، توفر أداة التجميع التصغير و tree shaking و code splitting، وهي ضرورية للأداء. بدون أداة تجميع، من الصعب الحفاظ على بنية معيارية في المشاريع الكبيرة.
لـ React Native — Metro (الخيار الوحيد المدعوم). لتطبيقات الويب — Vite للمشاريع الجديدة (بفضل السرعة) أو Webpack للمشاريع الحالية ذات النظام البيئي الغني. للمكتبات وحزم npm — Rollup، لأنه يولد مخرجات وحدات ES نظيفة.
أداة التجميع تحدد بشكل مباشر حجم حزمة JS النهائية. Webpack مع tree shaking يمكن أن يقلل الحجم بنسبة 30–50%. Metro لـ React Native يدعم bytecode Hermes، الذي يقلل الحجم بنسبة 20–30% مقارنة بـ JavaScript العادي. Code splitting يسمح بتحميل الوحدات حسب الطلب، مما يقلل الحزمة الأولية.
للويب، أداة التجميع تولد كوداً متوافقاً مع متصفحات مختلفة وتدعم CSS والصور والخطوط. لمنصات المحمول، Metro يولد كوداً لمحرك JavaScript (Hermes أو JSC)، ولا يعالج CSS أو HTML ويحسن البناء لموارد الجهاز المحدودة.
نعم، توجد مشاريع تستخدم Webpack للجزء الويب و Metro لـ React Native — على سبيل المثال، في المستودعات المتعددة مع قاعدة كود مشتركة. ومع ذلك، هذا يعقد إعداد CI/CD ويتطلب مزامنة إصدارات التبعيات. يوصى باستخدام أداة تجميع واحدة لجميع الأهداف إذا كان ذلك ممكناً.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.