


Verwendung von Angular5 zur Implementierung serverseitiger Rendering-Praktiken
Dieser Artikel stellt hauptsächlich die detaillierte Erläuterung der serverseitigen Rendering-Praxis von Angular5 vor. Jetzt teile ich ihn mit Ihnen und gebe ihn als Referenz.
Dieser Artikel setzt die Entwicklung basierend auf dem vorherigen Angular5-Artikel fort. Der obige Artikel befasst sich mit dem Prozess der Erstellung von Angular5 Youdao Translation und den Lösungen für die aufgetretenen Probleme.
Dann wurde die Benutzeroberfläche von Bootstrap4 auf Angular Material geändert. Ich werde hier nicht auf Details eingehen, was mit der Änderung der Benutzeroberfläche zu tun hat.
Wer die vorherigen Artikel gelesen hat, wird feststellen, dass der Inhalt der Artikel auf serverseitiges Rendering, Vue’s Nuxt und React’s Next ausgerichtet ist.
Vor dieser Überarbeitung habe ich auch versucht, Verpackungsbibliotheken der obersten Ebene wie nuxt.js und next.js zu finden, was viel Zeit sparen kann, aber ohne Erfolg.
Ich habe mich schließlich für Angular Universal (universelle (isomorphe) JavaScript-Unterstützung für Angular) entschieden, eine isomorphe Front-End- und Back-End-Lösung, die seit Angular2 verfügbar ist.
Das werde ich nicht tun Gehen Sie hier detailliert auf den Inhalt des Dokuments ein. Versuchen Sie, Angulars SSR in einer leicht verständlichen Sprache darzustellen
Voraussetzung
Das oben beschriebene udao-Projekt ist Völlig kompatibel mit Angular-Cli, von der Konstruktion bis zur Verpackung, wodurch dieser Artikel auch universell für alle Angular5-Projekte anwendbar ist, die mit Angular-Cli erstellt wurden.
Erstellungsprozess
Zuerst die Serverabhängigkeiten installieren
yarn add @angular/platform-server express yarn add -D ts-loader webpack-node-externals npm-run-all
Hier ist zu beachten, dass die Versionsnummer von @angular/platform-server am besten ist Basierend auf der aktuellen Version. Installieren Sie die Angular-Version, z. B.: @angular/platform-server@5.1.0, um Versionskonflikte mit anderen Abhängigkeiten zu vermeiden.
Datei erstellen: src/app/app.server.module.ts
import { NgModule } from '@angular/core' import { ServerModule } from '@angular/platform-server' import { AppModule } from './app.module' import { AppComponent } from './app.component' @NgModule({ imports: [ AppModule, ServerModule ], bootstrap: [AppComponent], }) export class AppServerModule { }
Datei aktualisieren: src/app/app.module.ts
import { BrowserModule } from '@angular/platform-browser' import { NgModule } from '@angular/core' // ... import { AppComponent } from './app.component' // ... @NgModule({ declarations: [ AppComponent // ... ], imports: [ BrowserModule.withServerTransition({ appId: 'udao' }) // ... ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Wir brauchen einen Master Datei zum Exportieren des Servermoduls
Erstellen Sie die Datei: src/main.server.ts
export { AppServerModule } from './app/app.server.module'
Aktualisieren Sie nun die Konfigurationsdatei von @angular/cli.angular-cli.json
{ "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "project": { "name": "udao" }, "apps": [ { "root": "src", "outDir": "dist/browser", "assets": [ "assets", "favicon.ico" ] // ... }, { "platform": "server", "root": "src", "outDir": "dist/server", "assets": [], "index": "index.html", "main": "main.server.ts", "test": "test.ts", "tsconfig": "tsconfig.server.json", "testTsconfig": "tsconfig.spec.json", "prefix": "app", "scripts": [], "environmentSource": "environments/environment.ts", "environments": { "dev": "environments/environment.ts", "prod": "environments/environment.prod.ts" } } ] // ... }
Das //... oben bedeutet, dass es weggelassen wird, aber es gibt keinen Kommentar in JSON, was seltsam aussieht....
Natürlich ist die Konfiguration von .angular-cli.json nicht festgelegt und hängt von den Anforderungen ab. Ändern Sie es selbst.
Wir müssen eine tsconfig-Konfigurationsdatei für den Server erstellen: src/tsconfig.server.json
{ "extends": "../tsconfig.json", "compilerOptions": { "outDir": "../out-tsc/app", "baseUrl": "./", "module": "commonjs", "types": [] }, "exclude": [ "test.ts", "**/*.spec.ts", "server.ts" ], "angularCompilerOptions": { "entryModule": "app/app.server.module#AppServerModule" } }
Dann aktualisieren: src/tsconfig.app. json
{ "extends": "../tsconfig.json", "compilerOptions": { "outDir": "../out-tsc/app", "baseUrl": "./", "module": "es2015", "types": [] }, "exclude": [ "test.ts", "**/*.spec.ts", "server.ts" ] }
Jetzt können Sie den folgenden Befehl ausführen, um zu sehen, ob die Konfiguration gültig ist
ng build -prod --build-optimizer --app 0 ng build --aot --app 1
Das Laufergebnis sollte wie unten gezeigt aussehen
Dann erstellen Sie den Express.js-Dienst und erstellen die Datei: src /server.ts
import 'reflect-metadata' import 'zone.js/dist/zone-node' import { renderModuleFactory } from '@angular/platform-server' import { enableProdMode } from '@angular/core' import * as express from 'express' import { join } from 'path' import { readFileSync } from 'fs' enableProdMode(); const PORT = process.env.PORT || 4200 const DIST_FOLDER = join(process.cwd(), 'dist') const app = express() const template = readFileSync(join(DIST_FOLDER, 'browser', 'index.html')).toString() const { AppServerModuleNgFactory } = require('main.server') app.engine('html', (_, options, callback) => { const opts = { document: template, url: options.req.url } renderModuleFactory(AppServerModuleNgFactory, opts) .then(html => callback(null, html)) }); app.set('view engine', 'html') app.set('views', 'src') app.get('*.*', express.static(join(DIST_FOLDER, 'browser'))) app.get('*', (req, res) => { res.render('index', { req }) }) app.listen(PORT, () => { console.log(`listening on http://localhost:${PORT}!`) })
Natürlich benötigen Sie eine Webpack-Konfigurationsdatei, um die server.ts-Datei zu packen: webpack.config.js
const path = require('path'); var nodeExternals = require('webpack-node-externals'); module.exports = { entry: { server: './src/server.ts' }, resolve: { extensions: ['.ts', '.js'], alias: { 'main.server': path.join(__dirname, 'dist', 'server', 'main.bundle.js') } }, target: 'node', externals: [nodeExternals()], output: { path: path.join(__dirname, 'dist'), filename: '[name].js' }, module: { rules: [ { test: /\.ts$/, loader: 'ts-loader' } ] } }
Zur Vereinfachung des Paketierens fügen Sie am besten ein paar Skriptzeilen zu package.json hinzu, wie folgt:
"scripts": { "ng": "ng", "start": "ng serve", "build": "run-s build:client build:aot build:server", "build:client": "ng build -prod --build-optimizer --app 0", "build:aot": "ng build --aot --app 1", "build:server": "webpack -p", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e" }
Versuchen Sie nun, npm run build auszuführen, und Sie werden die folgende Ausgabe sehen:
Knoten Führen Sie die gerade gepackte Knotendist/Server-Datei aus
Öffnen Sie http://localhost:4200/ und die Hauptseite des Projekts wird normal angezeigt
Wie aus den Entwicklertools oben ersichtlich ist, wird das HTML-Dokument vom Server direkt gerendert. Versuchen Sie als Nächstes, Daten anzufordern.
Hinweis: Keine der expliziten (anklickbares Menü) Routeninitialisierungen dieses Projekts fordert Daten an, aber die Detailseite der Worterklärung ruft Daten in der ngOnInit()-Methode ab, zum Beispiel: http:// A seltsam Das Phänomen tritt auf, wenn localhost:4200/detail/add direkt geöffnet wird. Die Anforderung wird einmal an den Server bzw. den Client gesendet. Die Anforderung für die Initialisierungsdaten des ersten Bildschirms des normalen serverseitigen Rendering-Projekts wird ausgeführt serverseitig, aber nicht zweimal auf der Clientseite!
Nachdem wir das Problem entdeckt haben, beseitigen wir die Grube
Stellen Sie sich vor, dass eine Markierung verwendet wird, um zu unterscheiden, ob der Server die Daten empfangen hat. Wenn die Daten nicht abgerufen wurden, fordert der Client sie an. Senden Sie keine Anfrage, wenn die Daten abgerufen wurden.
Natürlich hat Angular sie bereits vorbereitet, das heißt Angular-Module für die Statusübertragung
Wie nutzt man es also eigentlich? Siehe unten
Anfrage zum Ausfüllen der Grube
Führen Sie TransferStateModule am Servereingang bzw. Clienteingang ein
import { ServerModule, ServerTransferStateModule } from '@angular/platform-server'; // ... @NgModule({ imports: [ // ... ServerModule, ServerTransferStateModule ] // ... }) export class AppServerModule { } import { BrowserModule, BrowserTransferStateModule } from '@angular/platform-browser'; // ... @NgModule({ declarations: [ AppComponent // ... ], imports: [ BrowserModule.withServerTransition({ appId: 'udao' }), BrowserTransferStateModule // ... ] // ... }) export class AppModule { }
Nehmen Sie dieses Projekt im Detail als Beispiel.component.ts und Ändern Sie es wie folgt:
import { Component, OnInit } from '@angular/core' import { HttpClient } from '@angular/common/http' import { Router, ActivatedRoute, NavigationEnd } from '@angular/router' import { TransferState, makeStateKey } from '@angular/platform-browser' const DETAIL_KEY = makeStateKey('detail') // ... export class DetailComponent implements OnInit { details: any // some variable constructor( private http: HttpClient, private state: TransferState, private route: ActivatedRoute, private router: Router ) {} transData (res) { // translate res data } ngOnInit () { this.details = this.state.get(DETAIL_KEY, null as any) if (!this.details) { this.route.params.subscribe((params) => { this.loading = true const apiURL = `https://dict.youdao.com/jsonapi?q=${params['word']}` this.http.get(`/?url=${encodeURIComponent(apiURL)}`) .subscribe(res => { this.transData(res) this.state.set(DETAIL_KEY, res as any) this.loading = false }) }) } else { this.transData(this.details) } } }
Der Code ist einfach und klar genug und entspricht dem oben beschriebenen Prinzip.
Jetzt müssen wir nur noch kleine Anpassungen an der Datei main.ts vornehmen, um unseren Code auszuführen DOMContentLoaded, damit TransferState normal funktioniert:
import { enableProdMode } from '@angular/core' import { platformBrowserDynamic } from '@angular/platform-browser-dynamic' import { AppModule } from './app/app.module' import { environment } from './environments/environment' if (environment.production) { enableProdMode() } document.addEventListener('DOMContentLoaded', () => { platformBrowserDynamic().bootstrapModule(AppModule) .catch(err => console.log(err)) })
Gehen Sie hierher, um npm run build && node dist/server.js auszuführen und aktualisieren Sie dann http://localhost:4200/detail/add in der Konsole, um das Netzwerk anzuzeigen wie folgt:
Es wurde festgestellt, dass in der XHR-Kategorie keine Anfrage initiiert wurde, sondern nur der Cache von Service-Worker getroffen wurde.
Alle Fallstricke wurden bisher überwunden. Das Projekt läuft normal und es wurden keine weiteren Fehler gefunden.
Zusammenfassung
Der erste Artikel im Jahr 2018 zielt darauf ab, die Implementierung von serverseitigem Rendering in allen gängigen Frameworks zu untersuchen, und eröffnet Angular, ein Framework, das am Ende nicht ausprobiert wurde.
Natürlich ist Orange immer noch ein Front-End-Grundschüler. Ich weiß nur, wie man es implementiert, und der Quellcode ist nicht sehr klar. Ich hoffe, Sie können mich aufklären.
Die endgültige Github-Adresse ist dieselbe wie im vorherigen Artikel: https://github.com/OrangeXC/udao
Das Obige habe ich für alle zusammengestellt an alle in der Zukunft.
Verwandte Artikel:
Ausführliche Erklärung zur Implementierung von Vuex (ausführliches Tutorial)
Implementierung der WeChat-Zahlung über vue.js
Implementierung der Benutzerberechtigungskontrolle in Vue2.0
Das obige ist der detaillierte Inhalt vonVerwendung von Angular5 zur Implementierung serverseitiger Rendering-Praktiken. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

Detaillierte Erläuterung der Methode für JavaScript -Zeichenfolge und FAQ In diesem Artikel werden zwei Möglichkeiten untersucht, wie String -Zeichen in JavaScript ersetzt werden: Interner JavaScript -Code und interne HTML für Webseiten. Ersetzen Sie die Zeichenfolge im JavaScript -Code Die direkteste Möglichkeit ist die Verwendung der Ersatz () -Methode: str = str.replace ("find", "ersetzen"); Diese Methode ersetzt nur die erste Übereinstimmung. Um alle Übereinstimmungen zu ersetzen, verwenden Sie einen regulären Ausdruck und fügen Sie das globale Flag G hinzu:: STR = Str.Replace (/fi

Dieses Tutorial zeigt Ihnen, wie Sie eine benutzerdefinierte Google -Such -API in Ihr Blog oder Ihre Website integrieren und ein raffinierteres Sucherlebnis bieten als Standard -WordPress -Themen -Suchfunktionen. Es ist überraschend einfach! Sie können die Suche auf y beschränken

Verbessern Sie Ihre Codepräsentation: 10 Syntax -Hochlichter für Entwickler Das Teilen von Code -Snippets auf Ihrer Website oder Ihrem Blog ist eine gängige Praxis für Entwickler. Die Auswahl des richtigen Syntax -Highlighter kann die Lesbarkeit und die visuelle Anziehungskraft erheblich verbessern. T

Hier sind Sie also bereit, alles über dieses Ding namens Ajax zu lernen. Aber was genau ist das? Der Begriff AJAX bezieht sich auf eine lose Gruppierung von Technologien, mit denen dynamische, interaktive Webinhalte erstellt werden. Der Begriff Ajax, ursprünglich von Jesse J geprägt

Diese Artikelserie wurde Mitte 2017 mit aktuellen Informationen und neuen Beispielen umgeschrieben. In diesem JSON -Beispiel werden wir uns ansehen, wie wir einfache Werte in einer Datei mit JSON -Format speichern können. Mit der Notation des Schlüsselwertpaares können wir jede Art speichern

Nutzen Sie JQuery für mühelose Webseiten -Layouts: 8 Essential Plugins JQuery vereinfacht das Webseitenlayout erheblich. In diesem Artikel werden acht leistungsstarke JQuery -Plugins hervorgehoben, die den Prozess optimieren, insbesondere nützlich für die manuelle Website -Erstellung

Dieser Artikel enthält eine kuratierte Auswahl von über 10 Tutorials zu JavaScript- und JQuery Model-View-Controller-Frameworks (MVC). Diese Tutorials decken eine Reihe von Themen von Foundatio ab

Kernpunkte Dies in JavaScript bezieht sich normalerweise auf ein Objekt, das die Methode "besitzt", aber es hängt davon ab, wie die Funktion aufgerufen wird. Wenn es kein aktuelles Objekt gibt, bezieht sich dies auf das globale Objekt. In einem Webbrowser wird es durch Fenster dargestellt. Wenn Sie eine Funktion aufrufen, wird das globale Objekt beibehalten. Sie können den Kontext mithilfe von Methoden wie CALL (), Apply () und Bind () ändern. Diese Methoden rufen die Funktion mit dem angegebenen Wert und den Parametern auf. JavaScript ist eine hervorragende Programmiersprache. Vor ein paar Jahren war dieser Satz
