Heim >Web-Frontend >js-Tutorial >Express.js beherrschen: Ein tiefer Einblick
Express ist ein äußerst häufig verwendetes Webserver-Anwendungsframework in Node.js. Im Wesentlichen ist ein Framework eine Codestruktur, die sich an bestimmte Regeln hält und zwei Hauptmerkmale aufweist:
Die Kernfunktionen des Express-Frameworks sind wie folgt:
In diesem Artikel wird analysiert, wie Express die Middleware-Registrierung, den nächsten Mechanismus und die Routenbehandlung durch Implementierung einer einfachen LikeExpress-Klasse implementiert.
Erkunden wir zunächst die bereitgestellten Funktionen anhand von zwei Express-Codebeispielen:
const express = require('express'); const app = express(); const port = 3000; app.get('/', (req, res) => { res.send('Hello World!'); }); app.listen(port, () => { console.log(`Example app listening at http://localhost:${port}`); });
Das Folgende ist der Code der Eintragsdatei app.js des Express-Projekts, die vom Express-Generator-Gerüst generiert wurde:
// Handle errors caused by unmatched routes const createError = require('http-errors'); const express = require('express'); const path = require('path'); const indexRouter = require('./routes/index'); const usersRouter = require('./routes/users'); // `app` is an Express instance const app = express(); // View engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'jade'); // Parse JSON format data in post requests and add the `body` field to the `req` object app.use(express.json()); // Parse the urlencoded format data in post requests and add the `body` field to the `req` object app.use(express.urlencoded({ extended: false })); // Static file handling app.use(express.static(path.join(__dirname, 'public'))); // Register top-level routes app.use('/', indexRouter); app.use('/users', usersRouter); // Catch 404 errors and forward them to the error handler app.use((req, res, next) => { next(createError(404)); }); // Error handling app.use((err, req, res, next) => { // Set local variables to display error messages in the development environment res.locals.message = err.message; // Decide whether to display the full error according to the environment variable. Display in development, hide in production. res.locals.error = req.app.get('env') === 'development'? err : {}; // Render the error page res.status(err.status || 500); res.render('error'); }); module.exports = app;
Aus den beiden oben genannten Codesegmenten können wir erkennen, dass die Express-Instanz-App hauptsächlich über drei Kernmethoden verfügt:
Basierend auf der Analyse der Funktionen des Express-Codes wissen wir, dass sich die Implementierung von Express auf drei Punkte konzentriert:
Basierend auf diesen Punkten werden wir unten eine einfache LikeExpress-Klasse implementieren.
Klären Sie zunächst die Hauptmethoden, die diese Klasse implementieren muss:
Überprüfen Sie die Verwendung des nativen Knoten-httpServers:
const express = require('express'); const app = express(); const port = 3000; app.get('/', (req, res) => { res.send('Hello World!'); }); app.listen(port, () => { console.log(`Example app listening at http://localhost:${port}`); });
Dementsprechend ist die Grundstruktur der LikeExpress-Klasse wie folgt:
// Handle errors caused by unmatched routes const createError = require('http-errors'); const express = require('express'); const path = require('path'); const indexRouter = require('./routes/index'); const usersRouter = require('./routes/users'); // `app` is an Express instance const app = express(); // View engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'jade'); // Parse JSON format data in post requests and add the `body` field to the `req` object app.use(express.json()); // Parse the urlencoded format data in post requests and add the `body` field to the `req` object app.use(express.urlencoded({ extended: false })); // Static file handling app.use(express.static(path.join(__dirname, 'public'))); // Register top-level routes app.use('/', indexRouter); app.use('/users', usersRouter); // Catch 404 errors and forward them to the error handler app.use((req, res, next) => { next(createError(404)); }); // Error handling app.use((err, req, res, next) => { // Set local variables to display error messages in the development environment res.locals.message = err.message; // Decide whether to display the full error according to the environment variable. Display in development, hide in production. res.locals.error = req.app.get('env') === 'development'? err : {}; // Render the error page res.status(err.status || 500); res.render('error'); }); module.exports = app;
Aus app.use([path,] callback [, callback...]) können wir ersehen, dass Middleware ein Array von Funktionen oder eine einzelne Funktion sein kann. Um die Implementierung zu vereinfachen, verarbeiten wir die Middleware einheitlich als Funktionsarray. In der LikeExpress-Klasse können die drei Methoden use(), get() und post() alle die Middleware-Registrierung implementieren. Lediglich die ausgelöste Middleware variiert aufgrund unterschiedlicher Anforderungsmethoden. Also überlegen wir:
Das Middleware-Array muss in einem öffentlichen Bereich platziert werden, damit Methoden in der Klasse leicht darauf zugreifen können. Also fügen wir das Middleware-Array in die Konstruktorfunktion „constructor()“ ein.
const http = require("http"); const server = http.createServer((req, res) => { res.end("hello"); }); server.listen(3003, "127.0.0.1", () => { console.log("node service started successfully"); });
Middleware-Registrierung bedeutet, dass die Middleware im entsprechenden Middleware-Array gespeichert wird. Die Middleware-Registrierungsfunktion muss die eingehenden Parameter analysieren. Der erste Parameter kann eine Route oder Middleware sein. Daher muss zunächst festgestellt werden, ob es sich um eine Route handelt. Wenn ja, geben Sie es so aus, wie es ist. Andernfalls ist die Standardroute die Root-Route und konvertiert dann die verbleibenden Middleware-Parameter in ein Array.
const http = require('http'); class LikeExpress { constructor() {} use() {} get() {} post() {} // httpServer callback function callback() { return (req, res) => { res.json = function (data) { res.setHeader('content-type', 'application/json'); res.end(JSON.stringify(data)); }; }; } listen(...args) { const server = http.createServer(this.callback()); server.listen(...args); } } module.exports = () => { return new LikeExpress(); };
Mit der allgemeinen Middleware-Registrierungsfunktion register() ist es einfach, use(), get() und post() zu implementieren, indem Sie die Middleware einfach in den entsprechenden Arrays speichern.
const express = require('express'); const app = express(); const port = 3000; app.get('/', (req, res) => { res.send('Hello World!'); }); app.listen(port, () => { console.log(`Example app listening at http://localhost:${port}`); });
Wenn der erste Parameter der Registrierungsfunktion eine Route ist, wird die entsprechende Middleware-Funktion nur ausgelöst, wenn der Anforderungspfad mit der Route übereinstimmt oder deren Unterroute ist. Wir benötigen also eine Routen-Matching-Funktion, um das Middleware-Array der passenden Route entsprechend der Anforderungsmethode und dem Anforderungspfad zu extrahieren, damit die nachfolgende callback()-Funktion ausgeführt werden kann:
// Handle errors caused by unmatched routes const createError = require('http-errors'); const express = require('express'); const path = require('path'); const indexRouter = require('./routes/index'); const usersRouter = require('./routes/users'); // `app` is an Express instance const app = express(); // View engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'jade'); // Parse JSON format data in post requests and add the `body` field to the `req` object app.use(express.json()); // Parse the urlencoded format data in post requests and add the `body` field to the `req` object app.use(express.urlencoded({ extended: false })); // Static file handling app.use(express.static(path.join(__dirname, 'public'))); // Register top-level routes app.use('/', indexRouter); app.use('/users', usersRouter); // Catch 404 errors and forward them to the error handler app.use((req, res, next) => { next(createError(404)); }); // Error handling app.use((err, req, res, next) => { // Set local variables to display error messages in the development environment res.locals.message = err.message; // Decide whether to display the full error according to the environment variable. Display in development, hide in production. res.locals.error = req.app.get('env') === 'development'? err : {}; // Render the error page res.status(err.status || 500); res.render('error'); }); module.exports = app;
Dann extrahieren Sie in der Rückruffunktion callback() des httpServers die Middleware, die ausgeführt werden muss:
const http = require("http"); const server = http.createServer((req, res) => { res.end("hello"); }); server.listen(3003, "127.0.0.1", () => { console.log("node service started successfully"); });
Die Parameter der Express-Middleware-Funktion sind req, res und next, wobei next eine Funktion ist. Nur durch den Aufruf können die Middleware-Funktionen nacheinander ausgeführt werden, ähnlich wie bei next() im ES6 Generator. In unserer Implementierung müssen wir eine next()-Funktion mit den folgenden Anforderungen schreiben:
const http = require('http'); class LikeExpress { constructor() {} use() {} get() {} post() {} // httpServer callback function callback() { return (req, res) => { res.json = function (data) { res.setHeader('content-type', 'application/json'); res.end(JSON.stringify(data)); }; }; } listen(...args) { const server = http.createServer(this.callback()); server.listen(...args); } } module.exports = () => { return new LikeExpress(); };
constructor() { // List of stored middleware this.routes = { all: [], // General middleware get: [], // Middleware for get requests post: [], // Middleware for post requests }; }
Lassen Sie mich abschließend eine Plattform vorstellen, die sich sehr gut für die Bereitstellung von Express eignet: Leapcell.
Leapcell ist eine serverlose Plattform mit den folgenden Eigenschaften:
Erfahren Sie mehr in der Dokumentation!
Leapcell Twitter: https://x.com/LeapcellHQ
Das obige ist der detaillierte Inhalt vonExpress.js beherrschen: Ein tiefer Einblick. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!