SEO الزاوي في العمل:


يتم الحفاظ على هذا المستودع من قبل Trilon.io والفريق العالمي الزاوي ، ومن المفترض أن يكون بداية متقدمة لكل من ASP.NET Core 2.1 باستخدام Angular 7.0+ ، ليس فقط بالنسبة إلى جانب العميل ، ولكن ليتم تقديمه على الخادم لطلاء التطبيقات الفورية (ملاحظة: إذا كنت لا تحتاج إلى قراءة SSR هنا على تعطيله).
من المفترض أن يكون هذا تطبيق بداية غني بالميزات يحتوي على جميع أحدث التقنيات ، وأفضل أنظمة البناء المتاحة ، ويتضمن العديد من الأمثلة والمكتبات في العالم الحقيقي المطلوبة في تطبيقات الصفحة الفردية اليوم (SPAS).
هذا يستخدم جميع المعايير الأخيرة ، لا غلب ، لا مقصورة ، لا طبقة ، لا "بناء" يدويا أي شيء. NPM و WebPack و .net التعامل مع كل شيء لك!
هذه مجرد بعض الميزات الموجودة في هذا المبتدئ!
ASP.NET 2.1 - VS2017 دعم الآن!
Angular 7.0.0 :
ng gc components/example-componentng gs shared/some-serviceWebPack Build System (WebPack 4)
أطر الاختبار
إنتاجية
ASP.NET CORE 2.1
أزور
npm i -S @markpieszak/ng-application-insights كتبعيات. // Add the Module to your imports
ApplicationInsightsModule . forRoot ( {
instrumentationKey : 'Your-Application-Insights-instrumentationKey'
} )عامل ميناء
تأكد من تثبيت .NET Core 2.1 و/أو VS2017 15.3. ستقوم VS2017 بتثبيت جميع تبعيات NPM & .NET الضرورية تلقائيًا عند فتح المشروع.
ببساطة دفع F5 لبدء تصحيح الأخطاء!
Docker-Support : قم بتغيير مشروع بدء التشغيل إلى Docker-Compose واضغط على F5
ملاحظة : إذا حصلت على أي أخطاء بعد هذا مثل module not found: boot.server (أو ما شابه ذلك) ، فتح سطر الأوامر و regh npm run build:dev للتأكد من أن جميع الأصول قد تم تصميمها بشكل صحيح بواسطة WebPack.
ملاحظة: تأكد من تثبيت C# Extension & .NET Core Debugger.
يأتي المشروع مع ملفات Launch.json التي تم تكوينها للسماح لك بالدفع F5 فقط لبدء المشروع.
# cd into the directory you cloned the project into
npm install && npm run build:dev && dotnet restore
# or yarn install إذا كنت تقوم بتشغيل المشروع من سطر الأوامر باستخدام dotnet run فتأكد من تعيين متغيرات البيئة الخاصة بك على التطوير (وإلا فإن أشياء مثل HMR قد لا تعمل).
# on Windows:
set ASPNETCORE_ENVIRONMENT=Development
# on Mac/Linux
export ASPNETCORE_ENVIRONMENT=Development باستخدام dotnet publish ، عند الانتهاء ، وضع المجلد الذي تم إنشاؤه على الخادم الخاص بك واستخدام IIS لإطلاق كل شيء.
git remote add azure https://[email protected]:443/my-angular2-site.git
// ^ get this from Azure (Web App Overview section - Git clone url)
git push --set-upstream azure master ملاحظة: يحتوي هذا التطبيق على إعداد WebAPI (API الخاص بنا) داخل نفس المشروع ، ولكن بالطبع يمكن تجريد كل هذا إلى مشروع (مشروع) منفصل تمامًا. .NET Core Things يتم كل شيء في نفس المشروع من أجل البساطة.
ملفات مستوى الجذر
هنا لدينا المشتبه بهم المعتاد الموجودين على مستوى الجذر.
الملفات الموجهة نحو الواجهة الأمامية:
package.json - NPM Project Tendencies & Scripts.tsconfig - تكوين TypeScript (هنا نقوم بإعداد المسارات أيضًا)webpack - ملفات التكوين (مجموعة معيارية + أكثر من ذلك بكثير)karma - ملفات التكوين (اختبار الوحدة)protractor - ملفات التكوين (اختبار E2E)tslint - قواعد رمز TypeScriptدعنا نلقي نظرة على كيفية تنظيم هذا حتى نتمكن من فهم بعض الشيء!
باستخدام Angular Universal ، نحتاج إلى تقسيم منطق تطبيقنا لكل منصة ، لذلك إذا نظرنا داخل هذا المجلد ، فسترى ملفين الجذرين ، هذا المنطق بالكامل للمستعرض والخادم على التوالي.
هنا نقوم بإعداد بعض الأشياء ، bootstrapping العميل الزاوي.
بالكاد ستحتاج إلى لمس هذا الملف ، ولكن شيء يجب ملاحظته ، هذا هو الملف الذي ستحصل فيه على المكتبات التي تريد استخدامها فقط في المتصفح. (فقط اعلم أنه يتعين عليك تقديم تطبيق وهمية للخادم عند القيام بذلك).
لاحظ بنية المجلد هنا في ./ClientApp/ :
+ /ClientApp/
+ /app/
App NgModule - our Root NgModule (you'll insert Components/etc here most often)
AppComponent / App Routes / global css styles
* Notice that we have 2 dividing NgModules:
app.module.browser & app.module.server
You'll almost always be using the common app.module, but these 2 are used to split up platform logic
for situations where you need to use Dependency Injection / etc, between platforms.
Note: You could use whatever folder conventions you'd like, I prefer to split up things in terms of whether they are re-usable
"components" or routeable / page-like components that group together and organize entire sections.
+ + > ++ > /components/
Here are all the regular Components that aren't "Pages" or container Components
+ + > ++ > /containers/
These are the routeable or "Page / Container" Components, sometimes known as "Dumb" Components
+ + > ++ > /shared/
Here we put all shared Services / Directives / Pipes etc عند إضافة ميزات/مكونات جديدة/إلخ إلى تطبيقك ، ستضيف الأشياء بشكل شائع إلى ngmodule الجذر (الموجود في /ClientApp/app/app.module.ts ) ، ولكن لماذا يوجد ngmodules في هذا المجلد؟
هذا لأننا نريد تقسيم منطقنا لكل منصة ، ولكن لاحظ أنهما يشتركان في NgModule المشتركة المسماة app.module.ts . عند إضافة معظم الأشياء إلى تطبيقك ، هذا هو المكان الوحيد الذي يجب عليك إضافته في المكون / التوجيه / التوجيه / الأنابيب / وما إلى ذلك. ستحتاج فقط إلى إضافة أشياء محددة من النظام الأساسي إلى app.module.browser || app.module.server .
لتوضيح هذه النقطة بمثال ، يمكنك أن ترى كيف نستخدم حقن التبعية لحقن StorageService الذي يختلف عن المتصفح والخادم.
// For the Browser (app.module.browser)
{ provide : StorageService , useClass : BrowserStorage }
// For the Server (app.module.server)
{ provide : StorageService , useClass : ServerStorage }فقط تذكر ، ستحتاج عادةً إلى القلق بشأن
app.module.ts، حيث ستضيف معظم تطبيقاتك الجوانب الجديدة!
كما أشرنا ، هذه هنا من أجل البساطة ، ومن الناحية الواقعية ، قد ترغب في مشاريع منفصلة لجميع مشاريع API / REST الخاصة بـ MicroServices / REST / إلخ.
نحن نستخدم MVC ضمن هذا التطبيق ، لكننا نحتاج فقط ولدينا وحدة تحكم واحدة ، تدعى HomeController . هذا هو المكان الذي يتم فيه تسلسل تطبيقنا الزاوي بأكمله في سلسلة ، وإرساله إلى المتصفح ، إلى جانب جميع الأصول التي يحتاجها بعد ذلك إلى bootstrap على جانب العميل ، وتصبح منتجعًا كاملًا بعد ذلك.
النسخة القصيرة هي أننا ندعو عملية العقدة هذه ، التي تمرير في كائن طلبنا واستدعاء ملف boot.server ، ونحن نعود كائنًا لطيفًا نمرره إلى كائن .nets ViewData ، ونرش من خلال ملفات Views/Shared/_Layout.cshtml و /Views/Home/index.cshtml !
يمكن الاطلاع على شرح أكثر تفصيلاً هنا: NG-Aspnetcore-readme
// Prerender / Serialize application
var prerenderResult = await Prerenderer . RenderToString (
/* all of our parameters / options / boot.server file / customData object goes here */
) ;
ViewData [ "SpaHtml" ] = prerenderResult . Html ;
ViewData [ "Title" ] = prerenderResult . Globals [ "title" ] ;
ViewData [ "Styles" ] = prerenderResult . Globals [ "styles" ] ;
ViewData [ "Meta" ] = prerenderResult . Globals [ "meta" ] ;
ViewData [ "Links" ] = prerenderResult . Globals [ "links" ] ;
return View ( ) ; // let's render the MVC View ألقِ نظرة على ملف _Layout.cshtml على سبيل المثال ، لاحظ كيف ندع .NET التعامل مع جميع سحر كبار المسئولين الاقتصاديين (الذي استخرجناه من Angular نفسه)!
<!DOCTYPE html >
< html >
< head >
< base href =" / " />
<!-- Title will be the one you set in your Angular application -->
< title > @ViewData["Title"] - AspNET.Core Angular 7.0.0 (+) starter </ title >
< meta charset =" utf-8 " />
< meta name =" viewport " content =" width=device-width, initial-scale=1.0 " />
@Html.Raw(ViewData["Meta"]) <!-- <meta /> tags -->
@Html.Raw(ViewData["Links"]) <!-- <link /> tags -->
< link rel =" stylesheet " href =" ~/dist/vendor.css " asp-append-version =" true " />
@Html.Raw(ViewData["Styles"]) <!-- <style /> tags -->
</ head >
... etc ... Views/Home/index.cshtml .
@Html.Raw(ViewData["SpaHtml"])
< script src =" ~/dist/vendor.js " asp-append-version =" true " > </ script >
@section scripts {
< script src =" ~/dist/main-client.js " asp-append-version =" true " > </ script >
}حسنًا الآن ، سوف يتولى الزاوية من جانب العميل الخاص بك ، وسيكون لديك منتجع صحي يعمل بالكامل. (لكننا اكتسبنا كل هذه الفوائد الكبرى لكبار المسئولين الاقتصاديين من أن تكون خادمًا)!
عند بناء مكونات في Angular 7 ، هناك بعض الأشياء التي يجب وضعها في الاعتبار.
تأكد من تقديم عناوين URL المطلقة عند الاتصال بأي واجهات برمجة التطبيقات. (لا يستطيع الخادم فهم المسارات النسبية ، SO /api/whatever سيفشل).
سيتم تشغيل مكالمات API أثناء الخادم ، ومرة أخرى أثناء عرض العميل ، لذا تأكد من استخدام نقل البيانات التي تعتبر مهمة لك حتى لا ترى وميضًا.
window ، document ، navigator ، وأنواع المتصفح الأخرى - غير موجودة على الخادم - لذلك لن يعمل استخدامها ، أو أي مكتبة تستخدمها (jQuery على سبيل المثال). لديك بعض الخيارات ، إذا كنت بحاجة حقًا إلى بعض هذه الوظائف:
import { PLATFORM_ID } from '@angular/core' ;
import { isPlatformBrowser , isPlatformServer } from '@angular/common' ;
constructor ( @ Inject ( PLATFORM_ID ) private platformId : Object ) { ... }
ngOnInit ( ) {
if ( isPlatformBrowser ( this . platformId ) ) {
// Client only code.
...
}
if ( isPlatformServer ( this . platformId ) ) {
// Server only code.
...
}
}setTimeout . سوف تبطئ عملية تقديم جانب الخادم. تأكد من إزالتها ngOnDestroy في المكونات.لا تتلاعب بالإعداد الأصلي مباشرة . استخدم Renderer2 . نحن نفعل هذا لضمان أننا في أي بيئة يمكننا تغيير وجهة نظرنا.
constructor ( element : ElementRef , renderer : Renderer2 ) {
this . renderer . setStyle ( element . nativeElement , 'font-size' , 'x-large' ) ;
}sass-loader node-sass > = 4: إما في حاوية Docker أو LocalHost Run NPM Node-Sass -F ما عليك سوى التعليق على المنطق داخل HomeController ، واستبدل @Html.Raw(ViewData["SpaHtml"]) مع علامة تطبيقات الجذر الخاصة بك فقط ("App-Root" في حالتنا): <app-root></app-root> .
يمكنك أيضًا إزالة أي منطق
isPlatformBrowser/etc، وحذف boot.server ، app.module.browser & app.module.server ، فقط تأكد من نقاط ملفboot.browserإلىapp.module.
تحقق من gotchas حول كيفية استخدام isPlatformBrowser() .
ستحتاج إما إلى إزالة SSR في الوقت الحالي ، أو تنتظر لأن الدعم يجب أن يأتي للتعامل مع عرض خادم النظام الأساسي. هذا ممكن الآن ، مع تغييرات المواد الزاوية التي تم تحديثها مؤخرًا. ليس لدينا برنامج تعليمي متاح لهذا حتى الآن.
ملاحظة: إذا كان ذلك ممكنًا ، فحاول تجنب استخدام jQuery أو المكتبات التي تعتمد عليها ، حيث توجد طرق أفضل وأكثر تجريدًا للتعامل مع DOM في الزاوي (5+) مثل استخدام العارض ، إلخ.
نعم ، بالطبع ولكن هناك بعض الأشياء التي تحتاج إلى إعدادها قبل القيام بذلك. أولاً ، تأكد من تضمين jQuery في ملف بائع WebPack ، وأن لديك إعداد إضافي لـ WebPack. new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' })
الآن ، تأكد من إدراج أي "ملحقات مكونات" وما إلى ذلك ، فقط في ملف boot.browser.ts . (أي: import 'slick-carousel'; ) في مكون تريد استخدامه ، تأكد من استيراده بالقرب من الأعلى مثل:
import * as $ from 'jquery' ; تأكد دائمًا من لف أي شيء موجه نحو jQuery في Angular's isPlatformBrowser() مشروطة!
لدعم IE9 من خلال IE11 ، افتح ملف polyfills.ts في مجلد polyfills وتوضيح "استيراد ملفيات" حسب الحاجة. أيضًا - تأكد من أن خيار تغيير webpack.config و webpack.config.vendor من TerserPlugin من ecma: 6 إلى ecma: 5 .
شكراً جزيلاً إلى Steve Sanderson (STEVESANDERSONMS) من Microsoft وعمله المذهل على JavaScriptServices ودمج عالم العقدة مع ASP.NET Core.
شكرا لك أيضا للعديد من المساهمين!
تحقق من مشكلاتنا الأسهل هنا
لا شيء مثالي على الإطلاق ، ولكن يرجى إعلامي عن طريق إنشاء مشكلة (تأكد من عدم وجود مشكلة حالية حول هذا الموضوع بالفعل) ، وسنحاول تحديد إصلاح لها! إذا كان لديك أي أفكار جيدة ، أو تريد المساهمة ، فلا تتردد في تقديم مشكلة في الاقتراح ، أو مجرد تقديم علاقات عامة من شوكةك.
حقوق الطبع والنشر (ج) 2016-2019 مارك فايساك
تحقق من Trilon.io لمزيد من المعلومات! Twittertrilon_io
اتصل بنا على [email protected] ، ودعنا نتحدث عن احتياجات مشاريعك.
Twitter: Trilon_io