6 أفضل الممارسات ونصائح Pro عند استخدام Angular CLI

المستقبل الآن ( بواسطة سيباستيان جيرمر)
إخلاء المسئولية: تركز المقالة على إصدار Angular CLI LESS THAN 6.0.0 الذي تم إصداره في أبريل 2018 ، كل شيء لا يزال صالحًا إلى حد كبير ، الشيء الوحيد الذي تم تغييره هو الأعلام الافتراضية لبناء prod ، يرجى إلقاء نظرة على الإصدار الرسمي Angular CLI ng build كابل بيانات.
اتبع Release Butler ، برنامج روبوت تويتر أنشأته لمساعدتك على مواكبة التطورات مع إصدارات Angular CLI و Angular والعديد من مكتبات الواجهة الأمامية الشائعة ...

تطوير تطبيقات Angular مع Angular CLI هو تجربة ممتعة للغاية! قدم لنا فريق Angular CLI المدهش الذي يدعم معظم الأشياء المطلوبة لأي مشروع جاد خارج الصندوق.

هيكل مشروع موحد مع قدرات اختبار كاملة (اختبار الوحدة و e2e) ، سقالة الكود ، تصميم درجة الإنتاج مع دعم لاستخدام التهيئة الخاصة بالبيئة. لقد تحقق هذا الحلم وأصبح الكثير من ساعات التوفير في كل المشاريع الجديدة. شكرا فريق الزاوي!

على الرغم من أن Angular CLI تعمل بشكل رائع من البداية ، إلا أن هناك بعض التحسينات المحتملة في التكوين وأفضل الممارسات التي يمكننا الاستفادة منها لجعل مشاريعنا أفضل!

ما الذي سنتعلمه؟

  1. أفضل الممارسات للهندسة المعمارية مع وحدات الميزة الأساسية والمشتركة والمحملة بالكسل
  2. استخدام الأسماء المستعارة لمجلدات التطبيق والبيئات لدعم عمليات الاستيراد الأنظف
  3. لماذا وكيفية استخدام ساس والمواد الزاوي
  4. كيفية إعداد بناء الإنتاج الجيد
  5. كيفية تلويح وداع PhantomJS واستخدام Headless Chrome بدلاً من ذلك (اختبار)
  6. كيفية إطلاق مشروعنا مع سجل التغيير الذي تم إنشاؤه تلقائيا والإصدار الصحيح عثرة

1. قليلا من الهندسة المعمارية

حسنًا ، لذلك أنشأنا مشروعنا الجديد باستخدام Angular CLI لكن ماذا الآن؟ يجب أن نستمر في توليد خدماتنا ومكوناتنا في بعض المجلدات العشوائية. كيف يمكننا هيكلة مشروعنا؟

من المبادئ التوجيهية الجيدة التي يجب اتباعها هي تقسيم تطبيقنا إلى ثلاث وحدات مختلفة على الأقل - أساسية ومشتركة وميزة (ربما نحتاج إلى أكثر من وحدة ميزات واحدة).

الوحدة الأساسية

يجب تنفيذ جميع الخدمات التي يجب أن يكون لها مثيل واحد فقط لكل تطبيق (خدمات مفردة) هنا. مثال نموذجي يمكن أن يكون خدمة المصادقة أو خدمة المستخدم. دعونا نلقي نظرة على مثال لتطبيق CoreModule.

SharedModule

يجب تنفيذ جميع المكونات والأنابيب "الغبية" هنا. لا تستورد هذه المكونات وحقن الخدمات من الميزات الأساسية أو غيرها في مُنشئيها. يجب أن يتلقوا جميع البيانات من خلال السمات الموجودة في قالب المكون الذي يستخدمونها. كل هذا يلخص حقيقة أن SharedModule ليس لديه أي تبعية لبقية طلبنا.

إنه أيضًا المكان المثالي لاستيراد وإعادة تصدير مكونات Angular Material.

كيفية إعداد هيكل المشروع باستخدام Angular CLI

يمكننا إنشاء الوحدات الأساسية والمشتركة مباشرةً بعد إنشاء مشروعنا الجديد. بهذه الطريقة ، سنكون مستعدين لتوليد مكونات وخدمات إضافية منذ البداية.

تشغيل نانوغرام توليد وحدة الأساسية. ثم قم بإنشاء ملف index.ts في المجلد الأساسي وأعد تصدير CoreModule نفسه. سنقوم بإعادة تصدير الخدمات العامة الإضافية التي يجب أن تكون متوفرة في التطبيق بأكمله خلال مزيد من التطوير.

أن يتم ذلك ، يمكننا أن نفعل الشيء نفسه لوحدة مشتركة.

FeatureModule

سنقوم بإنشاء وحدات ميزة متعددة لكل ميزة مستقلة من تطبيقنا. يجب على الوحدات النمطية للميزات استيراد الخدمات فقط من CoreModule. إذا احتاجت الوحدة النمطية A إلى استيراد الخدمة من الوحدة النمطية B ، فكر في نقل هذه الخدمة إلى الأساسية.

في بعض الحالات ، هناك حاجة للخدمات التي تتم مشاركتها فقط من قبل بعض الميزات ولن يكون من المنطقي نقلها إلى قلبها. في هذه الحالة ، يمكننا إنشاء وحدات ميزة مشتركة خاصة كما هو موضح لاحقًا في هذا المنشور.
تتمثل قاعدة التجربة في محاولة إنشاء ميزات لا تعتمد على أي ميزات أخرى فقط على الخدمات التي تقدمها CoreModule والمكونات التي تقدمها SharedModule.

سيؤدي ذلك إلى الحفاظ على رمزنا نظيفًا وسهل الصيانة والتوسعة مع ميزات جديدة. كما أنه يقلل من الجهد اللازم لإعادة البناء. إذا تم اتباعها بشكل صحيح ، فسوف نكون على ثقة من أن التغييرات في ميزة واحدة لا يمكن أن تؤثر على بقية طلبنا أو تحطمه.

تحميل كسول

يجب علينا تحميل وحدات ميزة لدينا كسول كلما أمكن ذلك. من الناحية النظرية ، يجب تحميل وحدة ميزة واحدة فقط بشكل متزامن أثناء بدء تشغيل التطبيق لإظهار المحتوى الأولي. يجب أن يتم تحميل كل وحدة ميزة أخرى بتكاسل بعد قيام المستخدم بتشغيل التنقل.

2. الأسماء المستعارة للتطبيق والبيئات

سيمكننا إنشاء مجلدات التطبيق والبيئات من تطبيق عمليات الاستيراد النظيفة التي ستكون متسقة خلال تطبيقنا.

النظر في الوضع الافتراضي ، ولكن المعتاد. نحن نعمل على مكون يقع في ثلاثة مجلدات بعمق في ميزة A ونريد استيراد الخدمة من المركز الذي يقع في مجلدين عميقين. قد يؤدي ذلك إلى ظهور بيان استيراد يشبه الاستيراد {SomeService} من '../../../core/subpackage1/subpackage2/some.service'.

بالتأكيد ليست أنظف استيراد على الإطلاق ...

وما هو أسوأ من ذلك ، في أي وقت نريد فيه تغيير موقع أي من هذين الملفين ، سيتم كسر بيان الاستيراد الخاص بنا. قارن ذلك بالاستيراد الأقصر {SomeService} من "@ app / core". تبدو أفضل ، أليس كذلك؟

لتكون قادرًا على استخدام الأسماء المستعارة ، يتعين علينا إضافة خصائص baseUrl ومسارات إلى ملف tsconfig.json لدينا مثل هذا ...

نقوم أيضًا بإضافةenv alias لتتمكن من الوصول بسهولة إلى متغيرات البيئة من أي مكان في تطبيقنا باستخدام نفس الاستيراد {environment} من عبارة "@ env / environment". ستعمل مع جميع البيئات المحددة لأنها ستحل تلقائيًا ملف البيئة الصحيح بناءً على - إشارة env التي تم تمريرها إلى الأمر ng build.

مع مساراتنا في مكاننا ، يمكننا الآن استيراد البيئة والخدمات مثل هذا ...

ربما لاحظت أننا نستورد كيانات (مثل SomeSingletonService في المثال أعلاه) مباشرةً من @ app / core بدلاً من @ app / core / some-package / some-singleton.service. هذا ممكن بفضل إعادة تصدير كل كيان عام في ملف index.ts الرئيسي. نقوم بإنشاء ملف index.ts واحد لكل حزمة (مجلد) ويبدو أنه يشبه هذا ...

في معظم التطبيقات ، سيتعين عادةً على مكونات وخدمات وحدة الميزات الخاصة فقط الوصول إلى الخدمات من CoreModule والمكونات من SharedModule. في بعض الأحيان قد لا يكون هذا كافيًا لحل حالة عمل معينة وسنحتاج أيضًا إلى نوع من "وحدة الميزات المشتركة" التي توفر وظائف لمجموعة فرعية محدودة من الوحدات النمطية الأخرى.

في هذه الحالة ، سننتهي بشيء مثل استيراد {SomeService} من '@ app / ميزة مشتركة' ؛ وعلى نحو مشابه للوضع الأساسي ، يتم الوصول إلى الميزة المشتركة أيضًا باستخدامapp ​​الاسم المستعار.

تتبع تبعيات الوحدة هيكل الشجرة الذي يشبه إلى حد بعيد شجرة المكونات المعروفة

3. باستخدام ساس

تعد Sass أحد أساليب المعالجة المسبقة التي تقدم الدعم للأشياء الفاخرة مثل المتغيرات (على الرغم من أن css ستحصل على المتغيرات قريبًا جدًا) ، والوظائف ، والخلطات ... سمها ما شئت ...

مطلوب أيضًا من Sass أن تستخدم مكتبة Angular Material Components الرسمية بفعالية مع إمكانياتها الواسعة. من الآمن افتراض أن استخدام Sass هو الخيار الافتراضي لمعظم المشاريع.

لاستخدام Sass ، يجب علينا إنشاء مشروعنا باستخدام Angular CLI ng الأمر الجديد مع --style scss flag. هذا يضع معظم التكوين اللازم. شيء واحد لا تتم إضافته افتراضيًا هو stylePreprocessorOptions with includePaths ويمكننا إعداده بأنفسنا باستخدام قيم الجذر "./" والاختيارية "./themes".

يساعد هذا محررنا في العثور على رموز مستوردة ويعزز تجربة المطورين من خلال إكمال تعليمات برمجية لمتغيرات Angular Material ووظائف الأداة المساعدة.

عند تطبيق تطبيقات Angular Material ، من الممارسات الجيدة استخراج تعريفات السمات في مجلد سمات منفصل ، سمة واحدة لكل ملف.
اتبعني على Twitter للحصول على إشعار بأحدث منشورات المدونة وأشياء الواجهة الأمامية المثيرة للاهتمام

4. "PROD" بناء

المشروع الذي تم إنشاؤه بواسطة Angular CLI يأتي فقط مع برنامج نصي بسيط للغاية. لتوليد التحف الصف الإنتاج ، علينا أن نفعل القليل من التخصيص أنفسنا.

نضيف "build: prod": "ng build - هدف الإنتاج - build-optimizer - بائع - القطعة" إلى نصوص package.json الخاصة بنا.

الإنتاج المستهدف

هذا هو علامة مظلة تمكن التصغير رمز والكثير من علامات البناء مفيدة بشكل افتراضي. وهو ما يعادل استخدام التالية ...

  • - end prod —use ملف environment.prod.ts لمتغيرات البيئة
  • --aot - تمكين تجميع Ahead-of-Time. سيصبح هذا إعدادًا افتراضيًا في الإصدارات المستقبلية من Angular CLI ، ولكن يتعين علينا الآن تمكين ذلك يدويًا
  • - output-hashing all - محتويات التجزئة للملفات التي تم إنشاؤها وإلحاق اسم الملف لتسهيل اختراق ذاكرة التخزين المؤقت للمتصفح (أي تغيير في محتوى الملف سينتج عنه تجزئة مختلفة وبالتالي يضطر المستعرض إلى تحميل نسخة جديدة من الملف)
  • --extract-css true - استخراج جميع المغلق في ملف ورقة أنماط منفصلة
  • --sourcemaps false - تعطيل توليد خرائط المصدر
  • - aka-chunks false - تعطيل استخدام الأسماء القابلة للقراءة البشرية للمقطع واستخدام الأرقام بدلاً من ذلك

أعلام مفيدة أخرى

  • - build-optimizer - ميزة جديدة تؤدي إلى حزم أصغر ولكن أوقات بناء أطول بكثير لذا استخدم بحذر! (يجب أيضًا تمكينه افتراضيًا في المستقبل)
  • - قطعة البائع - قم باستخراج رمز البائع (المكتبة) إلى جزء منفصل

تحقق أيضًا من المستندات الرسمية لعلامات التكوين المتاحة الأخرى التي قد تكون مفيدة في مشروعك الفردي.

5. فانتوم JS ميت! عاشت كروم بلا رأس!

PhantomJS هو متصفح مقطوع الرأس ومعروف جدًا والذي كان defacto الحل لإجراء اختبارات الواجهة الأمامية على خوادم CI والعديد من آلات التطوير.

على الرغم من كونك على ما يرام ، إلا أن دعم ميزات ECMAScript الحديثة كان متخلفًا. والأكثر من ذلك ، هو أن السلوك غير القياسي تسبب صداعًا في العديد من المناسبات عندما كانت الاختبارات تمر محليًا دون مشكلة ، لكنها لا تزال تعمل على كسر بيئة CI.

لحسن الحظ ، لم يعد علينا التعامل معها بعد الآن!

كروم بلا رأس - بدأ اختبار النهضة الأمامية!

كما تقول الوثائق الرسمية ...

يشحن Chrome مقطوعة الرأس في Chrome 59. إنها طريقة لتشغيل متصفح Chrome في بيئة مقطوعة الرأس. في الأساس ، تشغيل Chrome بدون كروم! إنه يجلب جميع ميزات منصة الويب الحديثة التي يوفرها Chromium ومحرك Blink لتقديم إلى سطر الأوامر.
عظيم! فكيف يمكننا استخدامه في مشروعنا Angular CLI؟

نضيف --browser ChromeHeadless flag إلى أمر الاختبار الخاص بنا حتى ننتهي بـ "test": "ng test --browser ChromeHeadless -" تشغيل فردي "و" watch ":" ng test --browser ChromeHeadless "في الحزمة الخاصة بنا. مخطوطات json. بسيط جدا ، ها!

6. استخدام رسائل الالتزام موحدة ومولد التغيير التلقائي

من الجيد دائمًا أن يكون لديك نظرة عامة سريعة على الميزات الجديدة وإصلاح الأخطاء في المشروع الذي يهمنا.

دعنا نوفر لمستخدمينا نفس الراحة!

كتابة سجل التغيير يدويًا ستكون مهمة شاقة للغاية للخطأ ، لذا فمن الأفضل أتمتة هذه العملية بدلاً من ذلك. هناك العديد من الأدوات المتاحة التي يمكنها القيام بالمهمة ولكن دعونا نركز على الإصدار القياسي.

تقوم هذه الأداة تلقائيًا بإنشاء وتحديث ملف CHANGELOG.md مع جميع التعيينات التالية لمواصفات الالتزامات التقليدية وتحديد الإصدار الجديد من مشروعنا بشكل صحيح.

يُعرّف الالتزام التقليدي النوع الإلزامي ، اختياري (النطاق): متبوعًا برسالة الالتزام. من الممكن أيضًا إضافة نص وتذييل اختياري ، مفصولين بخط فارغ. دعونا نرى كيف يبدو ذلك في الممارسة العملية عن طريق التحقق من مثال لرسالة الالتزام الكامل لمكتبة طراز ngx.

الإصلاح (التبعية): إصدارات متعددة من rxjs في مشروع واحد (TS90010)
تغيير الكسر: أصبحت rxjs الآن تعتمد على النظير بدلاً من التبعية
يغلق # 1

سوف الإصدار القياسي بشكل صحيح نتوء الإصدار الرئيسي من المشروع بسبب وجود BREAKING CHANGE الكلمة الأساسية في نص الالتزام.

سيظهر CHANGELOG.md الذي تم إنشاؤه بعد ذلك مثل هذا ...

مثال على ملف CHANGELOG.md الذي تم إنشاؤه بواسطة مكتبة الإصدار القياسي

تبدو حلوة! إذا كيف يمكننا استخدام هذا في مشروعنا؟

نبدأ بتثبيت npm install -D الإصدار القياسي لحفظه في devDependencies لدينا وإضافة "الإصدار": "الإصدار القياسي" إلى برامجنا النصية package.json.

يمكننا أيضًا إضافة git push ونشر npm لأتمتة العملية بالكامل. في هذه الحالة ، سننتهي بـ "release": "الإصدار القياسي && git push - master-tags منشأ العلامات && npm publish".

لاحظ أننا استخدمنا && لتسلسل أوامرنا التي تعتمد على النظام الأساسي وتعمل فقط على الأنظمة المستندة إلى Unix (وكذلك أيضًا على Windows باستخدام Cygwin أو Gitbash أو النظام الفرعي Win10 الجديد لنظام Linux).

BONUS: استخدام جذر الموارد (Intellij IDEA ، Webstorm فقط)

لن تجد Intellij IDEA دائمًا جميع المسارات افتراضيًا مما سينتج عنه العديد من علامات الخطأ الحمراء ودعم إكمال الكود المعطل. لحسن الحظ ، الحل بسيط للغاية. ما عليك سوى اختيار مجلد src ووضع علامة عليه كجذر Sources.

حدد مجلد src كمصدر للجذر

عظيم! قمت بها حتى النهاية!

أتمنى أن تكون قد وجدت بعض هذه النصائح وأفضل الممارسات مفيدة! يرجى دعم هذه المقالة مع your لنشر هذه النصائح على جمهور أوسع!

بدء مشروع الزاوي؟ تحقق من الزاوي NgRx المواد كاتب!
الزاوي NgRx Material Starter مع المدمج في أفضل الممارسات ، theming وأكثر من ذلك بكثير!

أيضا ، لا تتردد في التحقق من بعض المشاركات الزاوي أخرى مثيرة للاهتمام ...

و لا تنسى أبدا ، المستقبل مشرق
من الواضح المستقبل المشرق ( بواسطة سفين شويرمير)