
مرحبا يا هبر! أقدم إليكم الترجمة المُكيَّفة للفصل الأول من "
Node.js Best Practices " للمخرج Yoni Goldberg. تم نشر مجموعة مختارة من التوصيات على Node.js على github ، ولديها ما يقرب من 30 طنًا من النجوم ، ولكن لم يتم ذكرها حتى الآن على Habré. أفترض أن هذه المعلومات ستكون مفيدة ، على الأقل للمبتدئين.
1. نصائح هيكل المشروع
1.1 هيكل المشروع الخاص بك حسب المكون
أسوأ خطأ في التطبيقات الكبيرة هو بنية متراصة في شكل قاعدة رمز ضخمة مع عدد كبير من التبعيات (رمز السباغيتي) ، هذا الهيكل يبطئ كثيرا من التطوير ، وخاصة إدخال وظائف جديدة. نصيحة - افصل الكود الخاص بك إلى مكونات منفصلة ، ولكل مكون ، حدد المجلد الخاص بك لوحدات المكون. من المهم أن تظل كل وحدة صغيرة وبسيطة. في قسم "التفاصيل" ، يمكنك رؤية أمثلة على البنية الصحيحة للمشاريع.
خلاف ذلك: سيكون من الصعب على المطورين تطوير المنتج - ستكون إضافة وظائف جديدة وإجراء تغييرات على الرمز بطيئة ولديهم فرصة كبيرة لكسر المكونات التابعة الأخرى. يُعتقد أنه إذا لم يتم تقسيم وحدات الأعمال ، فقد تكون هناك مشاكل في توسيع نطاق التطبيق.
معلومات مفصلةشرح فقرة واحدةبالنسبة للتطبيقات ذات الحجم المتوسط وما فوق ، فإن المتراصة سيئة للغاية - يصعب فهم برنامج واحد كبير يحتوي على العديد من التبعيات ، وغالبًا ما يؤدي إلى شفرة السباغيتي. حتى المبرمجين المتمرسين الذين يعرفون كيفية "إعداد الوحدات النمطية" بشكل صحيح يبذلون الكثير من الجهد في التصميم المعماري ويحاولون تقييم عواقب كل تغيير بعناية في العلاقات بين الأشياء. الخيار الأفضل هو بنية تستند إلى مجموعة من برامج المكونات الصغيرة: قسّم البرنامج إلى مكونات منفصلة لا تشارك ملفاتهم مع أي شخص ، يجب أن يتكون كل مكون من عدد صغير من الوحدات (على سبيل المثال ، الوحدات النمطية: API ، الخدمة ، الوصول إلى قاعدة البيانات ، الاختبار وما إلى ذلك) ، بحيث هيكل وتكوين المكون واضحة. قد يطلق البعض على هذه البنية "الخدمة المصغرة" ، ولكن من المهم أن نفهم أن الخدمات المصغرة ليست مواصفات يجب عليك اتباعها ، ولكنها مجموعة من بعض المبادئ. بناءً على طلبك ، يمكنك تبني كلٍّ من هذه المبادئ وكل مبادئ هندسة الخدمات الميكروية. كلتا الطريقتين جيدة إذا كنت تبقي التعقيد رمز منخفضة.
أقل ما عليك القيام به هو تحديد الحدود بين المكونات: قم بتعيين مجلد في جذر المشروع لكل منها وجعلها قائمة بذاتها. يجب تنفيذ الوصول إلى وظيفة المكون فقط من خلال واجهة عامة أو API. هذا هو الأساس للحفاظ على بساطة المكونات الخاصة بك ، وتجنب "جحيم التبعيات" والسماح للتطبيق الخاص بك بالنمو إلى خدمة ميكروية كاملة.
اقتباس من المدونة: "التحجيم يتطلب تحجيم التطبيق بأكمله"من مدونة MartinFowler.com
يمكن أن تكون التطبيقات الأحادية ناجحة ، لكن الناس يشعرون بالإحباط بشكل متزايد معهم ، خاصة عند التفكير في النشر على السحابة. أي تغييرات ، حتى صغيرة ، في التطبيق تتطلب تجميع وإعادة توزيع متراصة بأكملها. غالبًا ما يكون من الصعب الحفاظ على بنية معيارية جيدة لا تؤثر فيها التغييرات في وحدة واحدة على الآخرين. يتطلب القياس زيادة حجم التطبيق بالكامل ، وليس فقط الأجزاء الفردية ، وهذا النهج يتطلب بالطبع مزيدًا من الجهد.
أقتبس من المدونة: "ما هو هيكل تطبيقك الذي يتحدث عنه؟"من بلوق
العم بوب... إذا كنت قد ذهبت إلى المكتبة ، فإنك تمثل هندستها المعمارية: المدخل الرئيسي ، مكاتب الاستقبال ، غرف القراءة ، قاعات المؤتمرات والعديد من القاعات مع أرفف الكتب. العمارة نفسها ستقول: هذا المبنى مكتبة.
إذن ما هو هيكل تطبيقك يتحدث؟ عندما تنظر إلى بنية الدليل ذات المستوى الأعلى وملفات الوحدة النمطية الموجودة بها ، فإنهم يقولون: أنا متجر على الإنترنت ، وأنا محاسب ، وأنا نظام لإدارة الإنتاج؟ أم أنهم يصرخون: أنا ريلز ، أنا ربيع / سبات ، أنا أسبا؟
(ملاحظة المترجم ، Rails ، Spring / Hibernate ، ASP هي أطر وتقنيات الويب).
هيكل المشروع السليم مع مكونات الحكم الذاتي
بنية المشروع غير صحيحة مع تجميع الملفات حسب الغرض
1.2 افصل طبقات مكوناتك ولا تخلطها مع بنية بيانات Express
يجب أن يكون لكل مكون من مكوناتك "طبقات" ، على سبيل المثال ، للعمل مع الويب ، ومنطق العمل ، والوصول إلى قاعدة البيانات ، ويجب أن يكون لهذه الطبقات تنسيق بيانات خاص بها لا يختلط بتنسيق بيانات مكتبات الأطراف الثالثة. هذا لا يفصل بين المشاكل بوضوح فحسب ، بل يسهل أيضًا التحقق من النظام واختباره. غالبًا ما يقوم مطورو واجهة برمجة التطبيقات بخلط الطبقات بتمرير كائنات طبقة الويب Express (مثل req ، res) إلى منطق الأعمال وطبقة البيانات - مما يجعل تطبيقك معتمدًا ومتصلًا بشدة بـ Express.
خلاف ذلك: بالنسبة للتطبيق الذي يتم فيه خلط كائنات الطبقة ، يكون من الصعب توفير اختبار الكود وتنظيم مهام CRON والمكالمات الأخرى غير Express.
معلومات مفصلةقسّم رمز المكون إلى طبقات: الويب والخدمات و DAL
الجانب الآخر هو مزج الطبقات في صورة متحركة واحدة
1.3 التفاف المرافق الأساسية الخاصة بك في حزم npm
في تطبيق كبير يتألف من خدمات مختلفة مع مستودعاتها الخاصة ، ينبغي أن تكون الأدوات المساعدة العالمية مثل المسجل والتشفير وما إلى ذلك ، ملفوفة بكودك الخاص وتقدم كحزم npm خاصة. هذا يتيح لك مشاركتها بين العديد من codebases والمشاريع.
خلاف ذلك: عليك أن تخترع دراجتك الخاصة لمشاركة هذا الكود بين قواعد الشفرة المنفصلة.
معلومات مفصلةشرح فقرة واحدةبمجرد أن يبدأ المشروع بالنمو ولديك مكونات مختلفة على خوادم مختلفة باستخدام نفس الأدوات المساعدة ، يجب أن تبدأ في إدارة التبعيات. كيف يمكنني السماح بمكونات متعددة لاستخدامها دون تكرار رمز الأداة المساعدة بين المستودعات؟ هناك أداة خاصة لهذا ، ويسمى npm .... ابدأ بلف حزم الأداة المساعدة التابعة لجهة خارجية برمزك الخاص بحيث يمكنك استبدالها بسهولة في المستقبل ، ونشر هذا الرمز كحزمة npm خاصة. الآن بإمكان قاعدة الشفرة بأكملها استيراد رمز الأدوات المساعدة واستخدام جميع ميزات إدارة التبعية في npm. تذكر أن هناك الطرق التالية لنشر حزم npm للاستخدام الشخصي دون فتحها للوصول العام:
الوحدات النمطية الخاصة أو
السجل الخاص أو
حزم npm المحلية .
مشاركة الأدوات المساعدة المشتركة الخاصة بك في بيئات مختلفة
1.4 فصل Express إلى "تطبيق" و "خادم"
تجنب العادة غير السارة المتمثلة في تعريف تطبيق Express بالكامل في ملف واحد ضخم ، وقم بتقسيم رمز "Express" الخاص بك إلى ملفين على الأقل: إعلان API (app.js) ورمز خادم www. من أجل بنية أفضل ، ضع إعلان API في الوحدات المكونة.
خلاف ذلك: لن تتوفر واجهة برمجة التطبيقات الخاصة بك إلا للاختبار من خلال مكالمات HTTP (وهو إصدار تقارير تغطية أبطأ وأكثر صعوبة بكثير). ومع ذلك ، أعتقد أنه ليس من المرح للغاية العمل مع مئات أسطر التعليمات البرمجية في ملف واحد.
معلومات مفصلةشرح فقرة واحدةنوصي باستخدام منشئ تطبيق Express ونهجه في إنشاء قاعدة بيانات التطبيق: يتم فصل إعلان API عن تكوين الخادم (بيانات المنفذ ، البروتوكول ، إلخ). يسمح لك هذا باختبار واجهة برمجة التطبيقات (API) دون إجراء مكالمات عبر الشبكة ، مما يسرع عملية الاختبار ويجعل الحصول على مقاييس تغطية الرمز أسهل. كما يتيح لك نشر واجهة برمجة التطبيقات (API) نفسها بمرونة لإعدادات مختلفة لشبكة الخادم. كمكافأة ، تحصل أيضًا على فصل أفضل للمسؤوليات ورمز أنظف.
نموذج التعليمة البرمجية: إعلان API ، يجب أن يكون في app.jsvar app = express(); app.use(bodyParser.json()); app.use("/api/events", events.API); app.use("/api/forms", forms);
مثال على الكود: معلمات شبكة الخادم ، يجب أن تكون في / bin / www var app = require('../app'); var http = require('http'); var port = normalizePort(process.env.PORT || '3000'); app.set('port', port); var server = http.createServer(app);
مثال: اختبار واجهة برمجة التطبيقات لدينا باستخدام الاختبار الفائق (حزمة اختبار شائعة) const app = express(); app.get('/user', function(req, res) { res.status(200).json({ name: 'tobi' }); }); request(app) .get('/user') .expect('Content-Type', /json/) .expect('Content-Length', '15') .expect(200) .end(function(err, res) { if (err) throw err; });
1.5 استخدم تكوينًا هرميًا آمنًا استنادًا إلى متغيرات البيئة
يجب أن يوفر إعداد التكوين المثالي:
(1) مفاتيح القراءة من كل من ملف التكوين ومتغيرات البيئة ،
(2) حفظ الأسرار خارج رمز المستودع ،
(3) هيكل البيانات الهرمي (وليس مسطح) من ملف التكوين لتسهيل العمل مع الإعدادات.
هناك العديد من الحزم التي يمكن أن تساعد في تطبيق هذه النقاط ، مثل: rc ، nconf ، و config.
خلاف ذلك: سيؤدي الفشل في الامتثال لمتطلبات التكوين هذه إلى تعطيل عمل كل من المطور الفردي والفريق بأكمله.
معلومات مفصلةشرح فقرة واحدةعند التعامل مع إعدادات التكوين ، يمكن أن تكون هناك أشياء كثيرة مزعجة وتبطئ:
1. يصبح تعيين جميع المعلمات باستخدام متغيرات البيئة مملاً للغاية إذا كنت بحاجة إلى إدخال أكثر من 100 مفتاح (بدلاً من مجرد إصلاحها في ملف التكوين) ، ومع ذلك ، إذا كان سيتم تحديد التكوين فقط في ملفات الإعدادات ، فقد يكون هذا غير مريح لـ DevOps. يجب أن يجمع حل التكوين الموثوق بين كلا الطريقتين: ملفات التكوين وتجاوز المعلمات من متغيرات البيئة.
2. إذا كان ملف التكوين "مسطحًا" JSON (أي ، تتم كتابة جميع المفاتيح كقائمة واحدة) ، فمع زيادة عدد الإعدادات ، سيكون من الصعب التعامل معها. يمكن حل هذه المشكلة عن طريق تكوين هياكل متداخلة تحتوي على مجموعات من المفاتيح وفقًا لمقاطع الإعدادات ، أي تنظيم بنية بيانات JSON هرمية (انظر المثال أدناه). هناك مكتبات تتيح لك تخزين هذا التكوين في عدة ملفات ودمج البيانات منها في وقت التشغيل.
3. لا يوصى بتخزين المعلومات السرية (مثل كلمة مرور قاعدة البيانات) في ملفات التكوين ، ولكن لا يوجد حل مناسب محدد لمكان وكيفية تخزين هذه المعلومات. تسمح لك بعض مكتبات التكوين بتشفير ملفات التكوين ، بينما تقوم الأخرى بتشفير هذه الإدخالات أثناء أوامر git ، أو يمكنك حفظ المعلمات السرية في الملفات وتعيين قيمها أثناء النشر عبر متغيرات البيئة.
4. تتطلب بعض سيناريوهات التكوين المتقدمة إدخال المفاتيح من خلال سطر الأوامر (vargs) أو مزامنة بيانات التكوين من خلال ذاكرة تخزين مؤقت مركزية مثل Redis بحيث تستخدم خوادم متعددة البيانات نفسها.
هناك مكتبات npm ستساعدك في تنفيذ معظم هذه التوصيات ، ننصحك
بالاطلاع على المكتبات التالية:
rc و
nconf و
config .
مثال على الكود: الهيكل الهرمي يساعد في العثور على السجلات والعمل مع ملفات التكوين الضخمة
{ // Customer module configs "Customer": { "dbConfig": { "host": "localhost", "port": 5984, "dbName": "customers" }, "credit": { "initialLimit": 100, // Set low for development "initialDays": 1 } } }
(ملاحظة المترجم ، لا يمكن استخدام التعليقات في ملف JSON الكلاسيكي. المثال أعلاه مأخوذ من وثائق مكتبة التهيئة ، التي تضيف وظيفة للتصفية المسبقة لملفات JSON من التعليقات. لذلك ، المثال يعمل بشكل جيد ، ومع ذلك ، قد يتم استخدام لينتر مثل إعدادات ESLint الافتراضية "أقسم" بتنسيق مماثل).
الكلمة الأخيرة من المترجم:
- يقول وصف المشروع أن الترجمة إلى اللغة الروسية قد تم إطلاقها بالفعل ، لكنني لم أجد هذه الترجمة هناك ، لذا تناولت المقال.
- إذا بدت الترجمة مختصرة جدًا لك ، فحاول توسيع المعلومات التفصيلية في كل قسم.
- آسف أن الرسوم التوضيحية لم تترجم.