NodeJS: Schnellstart



Hallo alle zusammen! Sehr bald wird der Node.js-Entwicklerkurs beginnen , in dessen Zusammenhang wir eine traditionelle offene Lektion durchgeführt haben . Das Webinar untersuchte die Stärken und Schwächen von Node und diskutierte auch, für welche Aufgaben diese Softwareplattform am besten geeignet ist und für welche anderen Sprachen und Frameworks ausgewählt werden sollte. Und natürlich nicht ohne Übung. Ausführen der Beispiele und der Software, die zur Installation von Node.js erforderlich sind .

Dozent - Alexander Korzhikov , Dev IT Engineer bei der ING Group (Niederlande).






Ein paar Worte zu Node.js.


Node.js ist eine asynchrone JavaScript-Laufzeit, die auf Konzepten wie Event Loop und ereignisorientierter Architektur basiert. Mit der Node.js-Plattform und dem Standard-NPM-Paketmanager können Sie effektive Anwendungen für verschiedene Themenbereiche erstellen - vom Web bis zum maschinellen Lernen.

Das einfachste Webserver-Beispiel ( node server.js):

const http = require('http')
const hostname = '127.0.0.1'
const port = 3000
const server = http.createServer((req, res) => {
res.statusCode = 200
res.setHeader('Content-Type', 'text/plain')
res.end('Hello World\n')
})
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`)
})

Mit Blick auf den obigen Code können die folgenden Funktionen von Node.js festgestellt werden:

  1. Wir können JavaScript-Code direkt auf dem Server ausführen, dh es ist möglich, JavaScript-Dateien mit dem Befehl node auszuführen.
  2. Das CommonJS-Format von Modulen zum Laden von Abhängigkeiten und ES-Modulen wird unterstützt, und beide Formate können verwendet werden.
  3. Es wird eine Standardmodulbibliothek unterstützt, zu der auch HTTP gehört.
  4. Die API basiert auf dem Muster für asynchrone Rückrufe, Promise wird jedoch ebenfalls unterstützt.
  5. Die ES2015-Syntax wird unterstützt. Übrigens, hier ist ein nützlicher Link, mit dem Sie immer sehen können, in welcher Version von Node welche JS-Funktionen unterstützt werden . Wenn etwas schief geht, können Sie das Problem vergleichen und verstehen.

Auch verpassen Sie nicht die kleine Demo (VSCode + Chrome Debug).

Ein kurzer Ausflug in die Geschichte


Die Node.js-Plattform erschien 2009, der Hauptentwickler und Schöpfer des Projekts war Ryan Dahl. Seine Hauptidee war es, eine nicht blockierende E / A (Eingabe-Ausgabe) für den Server zu erstellen, außerdem mit JavaScript. Zu dieser Zeit waren solche Ansätze nicht sehr verbreitet, und JavaScript war eine der besten Lösungen.

Node.js verwendet die Chromium-Engine in sich selbst oder vielmehr den Teil davon, der JavaScript - V8 interpretiert . Aufgrund der Tatsache, dass sich der Dolmetscher zu einem Zeitpunkt in ein separates V8-Projekt trennte, wurde es möglich, einfach ein Ökosystem um dieses herum zu erstellen. Genau genommen hat der Schöpfer von Node.js Ryan Dahl genau das getan. Übrigens gibt es heute die Node.js Foundation, eine Organisation, die das Projekt unterstützt.



Struktur


Erstens ist die Bibliothek in C ++ und JavaScript geschrieben. Das Projekt selbst liegt auf GitHub . Wenn Sie also neugierig sind, können Sie sich mit dem Quellcode vertraut machen. Sie können sich sehr lange mit dem Studium befassen )).

Zweitens enthält es, wie bereits erwähnt, V8 (die JavaScript-Ausführungsplattform von Google) und libuv als Teil der Ereignisschleife (asynchrone Ereignisschleife).

Natürlich gibt es verschiedene Module für die Arbeit mit dem Betriebssystem, mit denen Sie die Geschäftsaufgaben ausführen können, die Sie benötigen.

Erwähnenswert sind auch die wichtigsten Entwurfsmuster, die üblicherweise in Node.js verwendet werden:

  • Rückruf (es wurde bereits erwähnt);
  • Beobachter (einfacheres Ereignismuster);
  • Modul (obwohl es jetzt in der JavaScript-Sprache selbst organisiert ist, ist es in Node.js immer noch relevant);
  • Reaktor (Muster der asynchronen Interaktion mit einigen Ressourcen, wenn Sie den Hauptcodestrom nicht blockieren). Dieses Muster ist JS-Entwicklern bekannt. Wenn wir beispielsweise in einem Browser arbeiten und ein Frontend schreiben, blockieren wir nicht die gesamte Browserarbeit, sondern abonnieren einfach Ereignisse des Benutzers. Wenn ein Ereignis auftritt (nach einem „Klick“, einer „Eingabe“ usw.), führen wir es aus unser Code.

Übrigens, hier ist ein kleiner Wettbewerb , den wir beim Webinar hatten)). Und fahre fort.

Knotenstandardverteilungsmodule




Wissen Sie, welche Module in der Standardknotenverteilung enthalten sind? Das heißt, wir sprechen von Modulen, die bereits eingebaut sind, daher können sie nicht installiert werden. Im Allgemeinen gibt es ungefähr 50 von ihnen, lassen Sie uns die wichtigsten auflisten. Zur Erleichterung der Wahrnehmung teilen wir sie herkömmlicherweise in 5 Punkte ein:

1. Hauptpunkt (für normale Operationen):

  • fs;
  • Timer;
  • Streams (zum Arbeiten mit Streams).

2. Dienstprogramme:

  • Pfad (zum Arbeiten mit Pfaden);
  • util;
  • zlib (Archivieren und Entpacken);
  • Krypto (für kryptografische Funktionen).

3. Prozesse (alles in Bezug auf Multiprocessing und Parallelität):

  • child_process (das Hauptmodul zum Starten kleinerer Module bietet großartige Möglichkeiten zum Starten und Überwachen von Prozessen);
  • Cluster (ähnlich dem ersten, ermöglicht jedoch das Parallelisieren von Aufgaben auf den Kernen Ihres Prozessors);
  • worker_threads (Implementierung von Threads oder Threads, aber nicht vollständig threadsicher, aber warum ist es besser, die Dokumentation zu lesen).

4. Protokolle (alle Arten von Protokollen):

  • http (s);
  • Netz;
  • DNS.

5. System (bzw. Systemmodule, einschließlich Debugging):

  • os
  • v8;
  • async_hooks;
  • perf_hooks;
  • trace_events

Was noch hinzuzufügen ist:

- globales Objekt - analog zum Fenster;
- Alle im Browser verfügbaren JavaScript-Objekte sind auch in Node.js verfügbar.
- Timeouts - fast wie in einem Browser;
- Prozess - Darstellung des aktuellen Prozesses;
- Konsole ist verfügbar.

Rückrufe


Rückruf - Eine Funktion, die als Argument an den Code übergeben wird und die Ausführung zu einem bestimmten Zeitpunkt umfasst. Übrigens denken die Leute selten, dass ihre Ausführung synchron oder asynchron sein kann.

const server = http.createServer((req, res) => {
res.statusCode = 200
res.setHeader('Content-Type', 'text/plain')
res.end('Hello World\n')
})
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`)
})

In Node wird der Rückruf standardmäßig mit einem "Fehler" ausgeführt und das Ergebnis ist asynchron:

fs.readFile('/etc/passwd', (err, data) => {
if (err) throw err
console.log(data)
})

Und so sieht das Antimuster aus - ein gutes Beispiel für die falsche Verwendung von Rückrufen. Wie sie sagen, die klassische Callback Hell :

fs.readdir(source, function (err, files) {
if (err) {
console.log('Error finding files: ' + err)
} else {
files.forEach(function (filename, fileIndex) {
console.log(filename)
gm(source + filename).size(function (err, values) {
if (err) {
console.log('Error identifying file size: ' + err)
} else {
console.log(filename + ' : ' + values)
aspect = (values.width / values.height)
widths.forEach(function (width, widthIndex) {
height = Math.round(width / aspect)
console.log('resizing ' + filename + 'to ' + height + 'x' + height)
this.resize(width, height).write(dest + 'w' + width + '_' + filename, function(err) {
if (err) console.log('Error writing file: ' + err)
})
}.bind(this))
}
})
})
}
})

Lassen Sie uns nun sehen, wie Sie einen einfachen Webserver erstellen und den HTML-Index als Client-Antwort rendern:

const http = require('http')
const server = http.createServer((req, res) => {
res.statusCode = 200
res.setHeader('Content-Type', 'text/plain')
res.end('Hello World\n')
})

So lesen Sie die lokale HTML-Datei:

const fs = require('fs')
fs.readFile('./index.html', (err, text) => {
console.log(text)
})

Zum Abschluss des Themas Rückrufe möchte ich Rückruftypen erwähnen. Es gibt Rückrufe, die nur dann einen Fehler zurückgeben, wenn ein Fehler vorliegt:

fs.access('/etc/passwd', fs.constants.R_OK, (err) => {
console.log(err ? 'no access!' : 'read')
})

Auch jetzt verwenden immer mehr Module und APIs Promises out of the box, was gut ist. Knoten unterstützt Versprechen:

util.promisify()
fs.promises.*

Rückgabetyp:

http.request('https://example.com', (error, response, body) => {
...
})

Fragen und Antworten zu Knoten


Beim Schreiben von Webservern wird häufig Express verwendet, obwohl es viele andere Bibliotheken und Frameworks gibt, die ähnliche Funktionen implementieren. Trotzdem ist Express am beliebtesten und stabilsten. Man könnte sagen, dies ist der Standard zum Schreiben von Servern.

import express from "express";
const app = express();
const port = 3000;
app.get("/", (req, res) => {
res.send("Hello World!");
});
app.listen(port, () => {
console.log(`Example app listening
});



Nun können Sie versuchen, selbst einen Webserver mit einem Express-Generator zu erstellen :

  • mit Jade, Cookie-Session;
  • ein naives Login Logout machen.

Oder schauen Sie sich einfach an, wie der Lehrer es gemacht hat, der die fertige Lösung in TypeScript vorbereitet hat .

Das ist alles. Zum Schluss noch ein paar nützliche Links:


Und wir sehen uns auf dem Kurs .

All Articles