Winkelseo in Aktion:


Dieses Repository wird von Trilon.io und dem Angular Universal-Team aufrechterhalten und soll ein erweiterter Starter für ASP.NET Core 2.1 unter Verwendung von Angular 7.0+ sein, nicht nur für die clientseitige, sondern auch um auf dem Server gerendert zu werden.
Dies soll eine Funktionsanwendung von Funktionen sein, die alle neuesten Technologien, die besten Build-Systeme enthält, und viele Beispiele und Bibliotheken in der realen Welt enthalten, die in den heutigen Single-Page-Anwendungen (SPAs) benötigt werden.
Dies verwendet die neuesten Standards, keinen Schluck, keine Bower, keine Typierungen, keine manuell "bauen" irgendetwas. NPM, WebPack und .NET verarbeiten alles für Sie!
Dies sind nur einige der Funktionen in diesem Starter!
ASP.NET 2.1 - VS2017 Support jetzt!
Angular 7.0.0 :
ng gc components/example-componentng gs shared/some-serviceWebpack -Build -System (Webpack 4)
Testen von Frameworks
Produktivität
ASP.NET CORE 2.1
Azurblau
npm i -S @markpieszak/ng-application-insights als Abhängigkeiten. // Add the Module to your imports
ApplicationInsightsModule . forRoot ( {
instrumentationKey : 'Your-Application-Insights-instrumentationKey'
} )Docker
Stellen Sie sicher, dass .NET Core 2.1 und/oder VS2017 15.3 installiert sind. VS2017 installiert automatisch die gesamten neccessarischen NPM- und .NET -Abhängigkeiten, wenn Sie das Projekt öffnen.
Schieben Sie einfach F5, um zu debuggen!
Docker-Support : Ändern Sie das Startprojekt in Docker-Compose und drücken Sie F5
HINWEIS : Wenn Sie danach Fehler erhalten, wie z. B. module not found: boot.server (oder ähnlich), öffnen Sie die Befehlszeile und führen Sie npm run build:dev aus, um sicherzustellen, dass alle Vermögenswerte von WebPack ordnungsgemäß erstellt wurden.
Hinweis: Stellen Sie sicher, dass Sie die C# -Erweiterung und den .NET -Core -Debugger installiert haben.
Das Projekt verfügt über die konfigurierten Dateien mit konfigurierter Startung.json, mit dem Sie nur F5 drücken können, um das Projekt zu starten.
# cd into the directory you cloned the project into
npm install && npm run build:dev && dotnet restore
# or yarn install Wenn Sie das Projekt aus der Befehlszeile mit dotnet run ausführen, stellen Sie sicher, dass Sie Ihre Umgebungsvariablen auf die Entwicklung festlegen (ansonsten funktionieren Dinge wie HMR möglicherweise nicht).
# on Windows:
set ASPNETCORE_ENVIRONMENT=Development
# on Mac/Linux
export ASPNETCORE_ENVIRONMENT=Development Wenn Sie mit dotnet publish den generierten Ordner fertigstellen, können Sie auf Ihrem Server fertig sind und mit IIS alles abfeuern.
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 HINWEIS: Diese Anwendung verfügt über WebAPI -Setup (unsere Rest -API) im selben Projekt, aber all dies könnte idealerweise in ein vollständig separates Projekt ('s) abstrahiert werden. .NET CORE -Dinge werden alle im selben Projekt um den Einfachheit halber geschehen.
Root Level -Dateien
Hier haben wir die üblichen Verdächtigen auf der Wurzelebene.
Front-End-orientierte Dateien:
package.json - NPM -Projektabhängigkeiten und -Skripte.tsconfig - TypeScript -Konfiguration (hier richten wir auch Pfade ein)webpack - Konfigurationsdateien (modulares Bundling + so viel mehr)karma - Konfigurationsdateien (Unit -Test)protractor - Konfigurationsdateien (E2E -Test)tslint - Typscript -Code -Lining -RegelnSchauen wir uns an, wie sich das strukturiert, damit wir alles für alles machen können!
Mit Angular Universal müssen wir unsere Applicatoin -Logik pro Plattform teilen. Wenn wir in diesem Ordner schauen, sehen Sie die beiden Root -Dateien, die die gesamte Logik für Browser und Server verzweigen.
Hier richten wir ein paar Dinge ein, Client Angular Bootstrapping.
Sie müssen diese Datei kaum berühren, aber etwas zu beachten. Dies ist die Datei, in der Sie Bibliotheken importieren, die Sie nur im Browser verwenden möchten. (Wisse nur, dass du dabei eine Scheinimplementierung für den Server bereitstellen müsstest.)
Beachten Sie die Ordnerstruktur hier in ./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 Wenn Sie Ihrer Anwendung neue Funktionen/Komponenten/usw. hinzufügen, fügen Sie dem root ngmodule (befindet sich in /ClientApp/app/app.module.ts ) häufig hinzu .
Dies liegt daran, dass wir unsere Logik pro Plattform teilen möchten, aber feststellen, dass beide das gemeinsame Ngmodule namens app.module.ts teilen. Wenn app.module.browser || app.module.server die meisten Dinge zu Ihrer Anwendung hinzufügen, müssen Sie Ihre neue Komponente / Richtlinie / Pipe / usw. hinzufügen. app.module.browser || app.module.server .
Um diesen Punkt mit einem Beispiel zu veranschaulichen, können Sie sehen, wie wir eine Abhängigkeitsinjektion verwenden, um einen StorageService zu injizieren, der für den Browser und Server unterschiedlich ist.
// For the Browser (app.module.browser)
{ provide : StorageService , useClass : BrowserStorage }
// For the Server (app.module.server)
{ provide : StorageService , useClass : ServerStorage }Denken Sie daran, dass Sie sich normalerweise nur um
app.module.tsmachen müssen, da Sie dort die meisten neuen Aspekte hinzufügen!
Wie wir betonten, sind diese hier zu Simplicity Sake da, und realistisch möchten Sie möglicherweise separate Projekte für alle Ihre Microservices / REST -API -Projekte / usw. erhalten.
Wir verwenden MVC in dieser Anwendung, brauchen aber nur einen Controller namens HomeController . Hier wird unsere gesamte Winkelanwendung in eine Zeichenfolge serialisiert, an den Browser gesendet, zusammen mit allen Vermögenswerten, die sie dann auf der Client-Seite starten müssen, und danach ein ausgewachsenes Spa werden.
Die Kurzversion ist, dass wir diesen Knotenprozess aufrufen, in unserem Anforderungsobjekt übergeben und die boot.server Datei aufrufen. Wir erhalten ein schönes Objekt, das wir in .NETS ViewData Objekt übergeben und unsere Views/Shared/_Layout.cshtml und /Views/Home/index.cshtml durchstreuen!
Eine detailliertere Erklärung finden Sie hier: NG-Aspnetcore-Engine 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 Schauen Sie sich die Datei _Layout.cshtml an, beachten Sie, wie wir alle unsere SEO -Magie verarbeiten und injizieren lassen (die wir aus dem Angular selbst extrahiert haben)!
<!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 ... Unsere Views/Home/index.cshtml rendern einfach die Anwendung und bedient die gebündelten Webpack -Dateien darin.
@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 >
}Nun, Ihr kundenseitiger Winkel übernimmt und Sie haben ein voll funktionsfähiges Spa. (Aber wir haben all diese großartigen SEO-Vorteile von serverbereiteten gewonnen)!
Beim Bauen von Komponenten in Angular 7 sind einige Dinge zu beachten.
Stellen Sie sicher, dass Sie absolute URLs bereitstellen, wenn Sie APIs aufrufen. (Der Server kann die relativen Pfade nicht verstehen, also /api/whatever fehlschlägt).
API -Anrufe werden während eines Servers und erneut während des Client -Renders ausgeführt. Stellen Sie daher sicher, dass Sie Daten verwenden, die für Sie wichtig sind, damit Sie keinen Flacker sehen.
window , document , navigator und andere Browsertypen - existieren nicht auf dem Server . Verwenden Sie diese oder in einer Bibliothek, die sie verwendet (z. B. JQuery), nicht. Sie haben einige Optionen, wenn Sie wirklich einen Teil dieser Funktionen benötigen:
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 zu beschränken oder zu vermeiden . Es verlangsamt den serverseitigen Rendering-Prozess. Stellen Sie sicher, dass Sie sie in Komponenten ngOnDestroy .Manipulieren Sie die NativeElement nicht direkt . Verwenden Sie den Renderer2 . Wir tun dies, um sicherzustellen, dass wir in jeder Umgebung unsere Sichtweise ändern können.
constructor ( element : ElementRef , renderer : Renderer2 ) {
this . renderer . setStyle ( element . nativeElement , 'font-size' , 'x-large' ) ;
}sass-loader benötigt node-sass > = 4: Entweder im Docker-Container oder im Localhost Run NPM Rebuild Node-Sass -f -f -f -f -f Kommentieren Sie einfach die Logik in HomeController und ersetzen Sie @Html.Raw(ViewData["SpaHtml"]) durch nur Ihre Anwendungen Root AppComponent Tag ("App-Root" in unserem Fall): <app-root></app-root> .
Sie können auch jede
isPlatformBrowser/etc-Logik entfernen und den Boot.Server, app.module.browser & app.module.server -Dateien löschen. Stellen Sie einfach sicher, dass Ihrboot.browser-Datei aufapp.modulezeigt.
Überprüfen Sie die GotChas, wie Sie isPlatformBrowser() verwenden.
Sie möchten entweder SSR vorerst entfernen oder warten, da Unterstützung für das Rendering der Plattform-Server-Renderung gelten sollte. Dies ist jetzt möglich, da sich die kürzlich aktualisierten Winkelmaterialänderungen ändern. Dafür haben wir noch kein Tutorial zur Verfügung.
Hinweis: Wenn möglich, versuchen Sie, JQuery oder Bibliotheken abhängig davon zu vermeiden, da es bessere, abstraktere Möglichkeiten gibt, mit dem DOM in Angular (5+) umzugehen, z. B. die Verwendung des Renderers usw.
Ja, natürlich, aber es gibt ein paar Dinge, die Sie vor dem Taten einrichten müssen. Stellen Sie zunächst sicher, dass JQuery in der WebPack -Anbieterdatei enthalten ist und ein WebPack -Plugin -Setup dafür verfügt. new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' })
Stellen Sie nun sicher, dass alle "Plugins" usw., die Sie haben, nur in Ihrer Datei boot.browser.ts -Datei enthalten sind. (IE: import 'slick-carousel'; ) In einer Komponente, die Sie JQuery verwenden möchten, importieren Sie es so in der Nähe der Oberseite wie SO:
import * as $ from 'jquery' ; Stellen Sie immer sicher, dass Sie alles wickeln, was in Angulars isPlatformBrowser() bedingt einwickelt!
Um IE9 über IE11 zu unterstützen, öffnen Sie die Datei polyfills.ts im polyfills -Ordner und wenden Sie sich nach Bedarf an "Importieren von Polyfills". Außerdem - stellen Sie sicher, dass Ihre webpack.config und webpack.config.vendor Änderung Option von TerserPlugin von ecma: 6 bis ecma: 5 .
Vielen Dank an Steve Sanderson (@stevesandersonms) von Microsoft und seine erstaunliche Arbeit an JavaScriptservices und integrieren Sie die Welt des Knotens in ASP.NET Core.
Vielen Dank auch an die vielen Mitwirkenden!
Schauen Sie sich hier unsere einfacheren Probleme an
Nichts ist jemals perfekt, aber bitte lassen Sie es mich wissen, indem Sie ein Problem erstellen (stellen Sie sicher, dass es noch keine vorhanden ist), und wir werden versuchen, eine Lösung dafür zu erarbeiten! Wenn Sie gute Ideen haben oder dazu beitragen möchten, können Sie entweder ein Problem mit dem Vorschlag machen oder einfach nur eine PR aus Ihrer Gabel machen.
Copyright (C) 2016-2019 Mark Pieszak
Weitere Informationen finden Sie in Trilon.io ! Twitter @trilon_io
Kontaktieren Sie uns unter [email protected] und lassen Sie uns über Ihre Projektanforderungen sprechen.
Twitter: @trilon_io