لماذا تختلف CI/CD للواجهة الأمامية عن CI/CD للواجهة الخلفية
عندما يبدأ فريق في بناء خط أنابيب CI/CD، غالبًا ما يتبادر إلى الذهن الواجهة الخلفية. يوجد خادم يجب إعادة تشغيله، ترحيل قاعدة بيانات يجب تنفيذه، واجهة برمجة تطبيقات يجب التحقق من استجاباتها الصحيحة. الواجهة الخلفية تعمل على بنية تحتية يتحكم فيها الفريق. أنت تعرف نظام التشغيل، إصدار بيئة التشغيل، الذاكرة المتاحة، وآخر مرة تم فيها إعادة تشغيل الخادم. إذا حدث خطأ، تتصل عبر SSH، تفحص السجلات، وتعيد تشغيل العملية.
الواجهة الأمامية للويب لا تعمل بهذه الطريقة. بمجرد نشر التطبيق، يتم إرسال JavaScript و HTML و CSS إلى متصفح المستخدم. قد يكون هذا المتصفح Chrome أو Firefox أو Safari أو أي شيء آخر تمامًا. قد يكون المستخدم على كمبيوتر محمول يعمل بنظام Windows أو Mac أو هاتف Android. قد يكون اتصالهم بالإنترنت سريعًا أو بطيئًا بشكل مؤلم. الفريق ليس لديه أي سيطرة على أي من هذه المتغيرات. الشيء الوحيد الذي يمكنك التحكم فيه هو الكود الذي تشحنه: أن يكون صحيحًا، خفيف الوزن، ومتوافقًا مع أكبر عدد ممكن من البيئات.
هذا الاختلاف يغير كل شيء في كيفية تصميم خط أنابيب للواجهة الأمامية. الاستراتيجيات التي تنجح في نشر الواجهة الخلفية غالبًا ما تفشل أو تسبب مشاكل جديدة عند تطبيقها على كود الواجهة الأمامية.
الأصول الثابتة مقابل التقديم من جانب الخادم
عادةً ما تتضمن عمليات نشر الواجهة الأمامية للويب نوعين من الأصول. الأصول الثابتة هي ملفات لا تتغير بناءً على من يطلبها: HTML و CSS و JavaScript والصور والخطوط. يمكن تخزين هذه الملفات على شبكة توصيل المحتوى (CDN)، وتخزينها مؤقتًا بواسطة المتصفح، وتقديمها من الخادم الأقرب للمستخدم. نشرها بسيط: رفعها إلى حاوية تخزين أو CDN، ويحصل المستخدمون على أحدث إصدار عند تحديث الصفحة.
التعقيد يأتي من التخزين المؤقت. حتى بعد نشر إصدار جديد، قد يستمر المتصفح أو CDN في تقديم الملفات القديمة. المستخدم الذي زار موقعك قبل ساعة قد يرى الواجهة القديمة لساعات أو أيام، اعتمادًا على رؤوس التخزين المؤقت وسلوك عامل الخدمة. هذه مشكلة خاصة بالواجهة الأمامية نادرًا ما تتعامل معها فرق الواجهة الخلفية. تغيير واجهة برمجة تطبيقات خلفية يصبح ساريًا فورًا على الخادم. تغيير في الواجهة الأمامية قد يكون غير مرئي للمستخدمين لأن متصفحهم قرر الاحتفاظ بالملفات القديمة.
النوع الآخر من أصول الواجهة الأمامية هو المحتوى المقدم من جانب الخادم (SSR). في SSR، يتم بناء الصفحة على الخادم وإرسالها إلى المتصفح كـ HTML جاهز. هذا النهج شائع للتطبيقات التي تحتاج إلى تحميل أولي سريع للصفحة، أو تحسين محركات بحث جيد، أو محتوى ديناميكي يتغير لكل مستخدم. يعني SSR أن كود الواجهة الأمامية يعمل على خادم تتحكم فيه، على الأقل للتقديم الأولي. لكن JavaScript التي ترطب الصفحة لا تزال تعمل في متصفح المستخدم، لذلك لا تزال مشكلة التوافق قائمة. يضيف SSR هدف نشر آخر: تحتاج الآن إلى إدارة عمليات الخادم التي تنشئ HTML، والتعامل مع التوسع، ومراقبة الأخطاء.
لفرض أن CDN تجلب أحدث الملفات بعد النشر، يمكنك إبطال ذاكرة التخزين المؤقت الخاصة بها. على سبيل المثال، مع AWS CloudFront:
aws cloudfront create-invalidation \
--distribution-id E1234567890ABC \
--paths "/*"
هذا الأمر يخبر CDN بتجاهل جميع الملفات المخزنة مؤقتًا وطلب نسخ جديدة من المصدر. بدون هذه الخطوة، قد يرى المستخدمون أصولًا قديمة لساعات حتى بعد نشر ناجح.
مشكلة الاعتماد على واجهة برمجة التطبيقات
نادرًا ما تقف تطبيقات الواجهة الأمامية بمفردها. تقريبًا كل تطبيق ويب حديث يجلب بيانات من واجهة برمجة تطبيقات، أو يرسل إدخال مستخدم، أو يتعامل مع المصادقة. هذا يخلق ارتباطًا وثيقًا بين الواجهة الأمامية والخلفية مما يجعل تصميم خط الأنابيب أصعب مما يبدو.
عند إصدار إصدار جديد من الواجهة الأمامية، تحتاج إلى التأكد من أن واجهة برمجة التطبيقات الخلفية لا تزال متطابقة. إذا غيرت الواجهة الخلفية بنية الاستجابة دون إبلاغ فريق الواجهة الأمامية، سيرى المستخدمون صفحات معطلة أو بيانات مفقودة. إذا بدأت الواجهة الأمامية في استدعاء نقطة نهاية غير موجودة بعد على الواجهة الخلفية، سيفشل التطبيق.
هذا يعني أن خط أنابيب الواجهة الأمامية لا يمكن أن يتوقف عند "نجح البناء". يجب أن يتحقق خط الأنابيب أيضًا من أن إصدار الواجهة الأمامية الذي سيتم إصداره متوافق مع واجهة برمجة التطبيقات التي تعمل حاليًا في الإنتاج. يحتاج الفريق إلى معرفة أي إصدار من واجهة برمجة التطبيقات نشط، وما إذا تم إدخال أي تغييرات جذرية، وكيفية التعامل مع الفترة الانتقالية عندما يتم إصدار الواجهة الأمامية والخلفية في أوقات مختلفة.
في الممارسة العملية، يؤدي هذا غالبًا إلى واجهات برمجة تطبيقات ذات إصدارات، أو أعلام الميزات، أو تنسيق دقيق بين دورات إصدار الواجهة الأمامية والخلفية. تتبنى بعض الفرق نهج اختبار العقد حيث يقوم خط أنابيب الواجهة الأمامية بتشغيل اختبارات ضد مواصفات واجهة برمجة تطبيقات معروفة قبل السماح بالنشر. يستخدم آخرون إصدارات الكناري أو عمليات النشر الأزرق والأخضر على الواجهة الأمامية لاكتشاف عدم التوافق مبكرًا.
الاختبار مختلف للواجهة الأمامية
اختبار الوحدة في الواجهة الأمامية له شكل مختلف عن الواجهة الخلفية. اختبار الوحدة في الواجهة الخلفية عادةً ما يستدعي دالة أو نقطة نهاية ويتحقق من الاستجابة. اختبار الوحدة في الواجهة الأمامية يحتاج إلى مراعاة تفاعل المستخدم وسلوك المتصفح والمخرجات المرئية.
العادة الصناعية في مساواة اختبارات الوحدة باختبار الدوال أو الفئات الفردية مضللة للواجهة الأمامية. يجب أن يتحقق اختبار الوحدة من سلوك ذي معنى واحد من نقطة دخول ذات صلة. بالنسبة للواجهة الأمامية، غالبًا ما تكون نقطة الدخول هذه إجراء مستخدم: نقرة، إرسال نموذج، تنقل، أو تغيير حالة مرئي. يجب أن يثبت الاختبار أن النظام يستجيب بشكل صحيح لهذا التفاعل، وليس أنه تم استدعاء طريقة داخلية بالوسائط الصحيحة.
هذا يعني أن مجموعة الاختبارات الخاصة بك لا يجب أن تفشل فقط لأنك أعدت هيكلة الكود الداخلي. إذا غيرت كيفية إدارة المكون لحالته الداخلية ولكن المستخدم لا يزال يرى نفس النتيجة، يجب أن تظل الاختبارات ناجحة. الاختبارات المرتبطة بإحكام بتفاصيل التنفيذ تصبح عبئًا صيانة وتبطئ خط الأنابيب دون إضافة أمان حقيقي.
بالنسبة للواجهة الأمامية، قد تتضمن بيئة الاختبار ذات الصلة بيئة تشغيل متصفح. يمكن أن تكون المحاكيات أو المحاكيات الافتراضية بيئات تنفيذ صالحة لاختبارات الوحدة إذا كان السلوك الذي يتم اختباره يتطلب واجهات برمجة تطبيقات المتصفح أو حسابات التخطيط أو ميزات وقت التشغيل. الأجهزة المادية لا تزال ضرورية للسيناريوهات المعتمدة على الأجهزة: الكاميرا، أجهزة الاستشعار، تباينات الشبكة، والأداء في العالم الحقيقي.
خطوة البناء ليست مجرد ترجمة
في CI/CD للواجهة الخلفية، عادةً ما تعني خطوة البناء ترجمة الكود وتعبئته في قطعة أثرية قابلة للنشر. بالنسبة للواجهة الأمامية، خطوة البناء تفعل أكثر من ذلك بكثير. إنها تجمع وحدات JavaScript، وتصغر الكود، وتحسن الصور، وتنشئ خرائط المصدر، وتحقق متغيرات البيئة، وتنتج إصدارات متعددة من الملفات لمتصفحات أو أجهزة مختلفة.
مخرجات البناء ليست قطعة أثرية واحدة. إنها مجموعة من الملفات مع تجزئات لكسر التخزين المؤقت في أسمائها. هذه التجزئات حاسمة لإدارة التخزين المؤقت. عند نشر إصدار جديد، فقط الملفات التي تغيرت تحصل على تجزئات جديدة. الملفات التي لم تتغير تحتفظ بتجزئاتها القديمة، لذلك يستمر متصفح التخزين المؤقت في تقديمها. هذا يقلل من حجم التنزيل للمستخدمين الذين زاروا موقعك بالفعل.
لكن كسر التخزين المؤقت يعمل فقط إذا تعامل خط الأنابيب الخاص بك معه بشكل صحيح. إذا كانت عملية البناء لا تنشئ تجزئات فريدة للملفات التي تغيرت، أو إذا كانت عملية النشر لا تقوم بتحديث مراجع HTML للإشارة إلى التجزئات الجديدة، سيحصل المستخدمون على مزيج من الملفات القديمة والجديدة. النتيجة هي واجهة مستخدم معطلة يصعب تصحيحها لأنها تحدث فقط على بعض المتصفحات أو بعد أنماط تنقل معينة.
قائمة تحقق عملية لـ CI/CD للواجهة الأمامية
- تحقق من أن خطوة البناء تنشئ تجزئات فريدة لكسر التخزين المؤقت للملفات التي تغيرت.
- اختبر الواجهة الأمامية الخاصة بك ضد إصدار واجهة برمجة التطبيقات الدقيق الذي يعمل في الإنتاج، وليس مجرد وهمية أو واجهة برمجة تطبيقات مرحلية.
- قم بتضمين اختبارات قائمة على المتصفح تحاكي تفاعلات المستخدم الحقيقية، وليس فقط اختبارات وحدة على دوال داخلية.
- قم بإعداد سياسات رؤوس التخزين المؤقت التي توازن بين النضارة والأداء. أوقات تخزين مؤقت قصيرة لـ HTML، وأوقات طويلة للأصول المجزأة.
- قم بتشغيل فحص انحدار بصري سريع لاكتشاف تغييرات الواجهة غير المقصودة قبل الإصدار.
- تأكد من أن عملية النشر تقوم بتحديث جميع المراجع إلى تجزئات الأصول الجديدة، بما في ذلك ملفات عامل الخدمة إذا كنت تستخدم واحدًا.
الخلاصة الملموسة
CI/CD للواجهة الأمامية ليس نسخة مبسطة من CI/CD للواجهة الخلفية. له قيوده الخاصة: بيئات مستخدم غير خاضعة للسيطرة، سلوك تخزين مؤقت يمكن أن يخفي أو يكسر إصدارك، ارتباط وثيق بواجهات برمجة التطبيقات الخلفية، وخطوة بناء تفعل أكثر من مجرد ترجمة الكود. معاملة نشر الواجهة الأمامية على أنه "مجرد رفع بعض الملفات" سيؤدي إلى تجارب مستخدم معطلة يصعب تشخيصها. ابنِ خط أنابيب الواجهة الأمامية الخاص بك حول حقيقة أن الكود يعمل في متصفح شخص آخر، على شبكة شخص آخر، ولديك فرصة واحدة فقط لجعل الانطباع الأول يعمل.