ما وراء الـ Monolith: احتراف الـ Universal Micro-Frontends باستخدام Module Federation و Expo
اكتشف كيف استطعت سد الفجوة بين بنية الويب وتطبيقات الجوال باستخدام Webpack Module Federation و Expo. يستعرض هذا الدليل نهجاً موحداً للـ micro-frontends يتيح التوسع عبر مختلف المنصات دون تعقيدات تعدد قواعد الكود (codebases).

لقد قضيت جزءاً كبيراً من مسيرتي المهنية في صراع مع الـ frontend monoliths. لقد مررنا جميعاً بهذا الموقف: مستودع كود (repository) ضخم جداً لدرجة أن تحديث مكتبة برمجية واحدة يبدو وكأنك تلعب لعبة Jenga، وخطوط أنابيب CI/CD تستغرق وقتاً طويلاً يكفي لاستراحة قهوة—بل واستراحة غداء أيضاً.
لفترة طويلة، كان الوعد الذي تقدمه الـ Micro-Frontends (MFEs) محصوراً بشكل كبير في الويب. كان لدينا Webpack Module Federation لتطبيقات React الخاصة بنا، لكن تطبيقات React Native للجوال ظلت متماسكة ككتلة واحدة (monolithic) بشكل عنيد. تغير هذا بالنسبة لي عندما بدأت في دفع حدود Expo و Re.Pack.
اليوم، أريد أن أشارككم كيف قمت بهندسة 'Universal' Micro-Frontends تتيح للفرق إطلاق الكود بشكل مستقل عبر منصات الويب والجوال على حد سواء.
المشكلة الأساسية: تبديل السياق (Context Switch)
في العديد من المؤسسات، يعمل فريق الويب وفريق الجوال في جزر معزولة. حتى لو كان كلاهما يستخدم React، فإن وتيرة النشر تختلف. يمكن لفريق الويب النشر عشرين مرة في اليوم؛ بينما يظل فريق الجوال تحت رحمة عملية مراجعة متجر التطبيقات (App Store).
حل Module Federation هذه المعضلة من خلال السماح لتطبيق 'Host' بتحميل حزم (bundles) من نوع 'Remote' ديناميكياً في وقت التشغيل (runtime). وتحدث الطفرة الحقيقية عندما تدرك أنه يمكنك تطبيق نفس هذا النموذج الفكري على تطبيقات الجوال المبنية باستخدام Expo.
الهيكلية: Host و Remotes
في مشاريعي الأخيرة، اتجهت نحو نموذج "المحور والأطراف" (hub-and-spoke model).
- الصدفة أو الـ Shell (Host): وهي نقطة الدخول الرئيسية لـ Expo. تتولى عمليات المصادقة (authentication)، وتوجيه التنقل (navigation routing)، والسمة العامة (global theme).
- الأجزاء أو الـ Fragments (Remotes): وهي حزم مستقلة—مثل تدفق عملية الدفع (Checkout) أو الملف الشخصي للمستخدم—يتم بناؤها واستضافتها بشكل مستقل.
بالنسبة لجانب الويب، هذا هو Module Federation التقليدي. أما بالنسبة للجوال، فنحن نستخدم Re.Pack، وهو مجمع حزم (bundler) يعتمد على Webpack لـ React Native ويعتبر بديلاً لـ Metro عندما تحتاج إلى ميزات متقدمة مثل code-splitting و federation.
التنفيذ: إضافة Module Federation Plugin
إليك لمحة عن كيفية إعداد حاوية remote. في ملف webpack.config.js الخاص بك (أو إعدادات Re.Pack)، يمكنك تحديد ما ستقوم بمشاركته:
من جانب الـ Host، تقوم باستهلاكه ديناميكياً:
لماذا يُعد Expo هو المكون السري؟
يعتقد الكثير من المطورين أن Expo مخصص للمبتدئين فقط. في الواقع، تجعله Config Plugins و Expo Router الأساس المثالي لـ MFEs.
باستخدام Expo Router، يمكنني تحديد نظام توجيه يعتمد على الملفات (file-based routing) يظل ثابتاً عبر المنصات. عندما يقوم تطبيق Host بتحميل جزء remote، يمكن لهذا الجزء الارتباط بسجل التنقل الموجود كما لو كان جزءاً من قاعدة الكود المحلية. هذه القدرة الشاملة (Universal) هي ما يسمح لنا بمشاركة المنطق البرمجي (Hooks, API clients, State Management) دون كابوس الـ npm install المستمر وتعارض الإصدارات.
النقلة النوعية: تحديثات وقت التشغيل مقابل مراجعات المتجر
أحد أكبر الانتصارات التي حققتها مع هذه التقنيات هو القدرة على تحديث ميزات معينة على الجوال دون الحاجة إلى تقديم ملف binary كامل للمتجر. من خلال استضافة الـ remote chunks على CDN (مثل AWS S3 أو Cloudflare)، يقوم تطبيق Host بجلب أحدث إصدار من checkout.bundle في كل مرة يفتح فيها المستخدم التطبيق (أو بناءً على استراتيجية التخزين المؤقت لديك).
هذا يحاكي تجربة تطوير الويب تماماً. نحن لم نعد نبني تطبيقات فحسب؛ بل نبني نظاماً موزعاً من مكونات واجهة المستخدم (UI components).
الدروس المستفادة (بالطريقة الصعبة)
- إصدارات التبعيات المشتركة (Shared Dependencies): يجب أن تكون صارماً مع التبعيات المشتركة (React, React Native). إذا استخدم الـ Host والـ Remote إصدارات أساسية مختلفة من مكتبة singleton، فسيتحطم التطبيق في الإنتاج.
- أمان الأنواع (Type Safety): استخدم
@module-federation/typescriptأو monorepo مشترك (Nx/Turborepo) لضمان أن العقود بين الـ Host والـ Remotes آمنة برمجياً. كونها ديناميكية لا يعني أنها يجب أن تكون خطيرة. - الاختبار (Testing): يتطلب اختبار تطبيق federated تحولاً في العقلية. أنت بحاجة إلى اختبارات تكامل (integration tests) تتحقق من أن الـ 'Shell' يمكنه جلب ورسم الـ 'Remote' بنجاح تحت ظروف شبكة مختلفة.
أفكار ختامية
إن الانتقال إلى بنية Micro-Frontend مع Expo و Module Federation ليس حلاً سحرياً—فهو يضيف تعقيداً إلى خط بناء التطبيق (build pipeline). ولكن بالنسبة للفرق التي تتوسع لتتجاوز 20 مهندساً أو تدير تجارب عبر منصات متعددة، فإن العائد يستحق العناء.
لقد انتقلنا من شعار "اكتب مرة واحدة، وشغل في أي مكان" إلى "انشر مرة واحدة، وحدّث في كل مكان". ومن واقع خبرتي، هنا تكمن المعجزة الهندسية الحقيقية.