Maison >interface Web >js tutoriel >Maîtriser Express.js : une plongée approfondie
Express est un framework d'application de serveur Web extrêmement couramment utilisé dans Node.js. Essentiellement, un framework est une structure de code qui adhère à des règles spécifiques et présente deux caractéristiques clés :
Les principales fonctionnalités du framework Express sont les suivantes :
Cet article analysera comment Express implémente l'enregistrement du middleware, le prochain mécanisme et la gestion des routes en implémentant une simple classe LikeExpress.
Explorons d'abord les fonctions qu'il propose à travers deux exemples de code Express :
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}`); });
Ce qui suit est le code du fichier d'entrée app.js du projet Express généré par l'échafaudage du générateur express :
// 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;
À partir des deux segments de code ci-dessus, nous pouvons voir que l'application d'instance Express comporte principalement trois méthodes principales :
Sur la base de l'analyse des fonctions du code Express, nous savons que la mise en œuvre d'Express se concentre sur trois points :
Sur la base de ces points, nous implémenterons ci-dessous une simple classe LikeExpress.
Tout d'abord, clarifiez les principales méthodes que cette classe doit implémenter :
Revoir l'utilisation du serveur http natif de Node :
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}`); });
En conséquence, la structure de base de la classe LikeExpress est la suivante :
// 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;
De app.use([path,] callback [, callback...]), nous pouvons voir que le middleware peut être un tableau de fonctions ou une seule fonction. Pour simplifier la mise en œuvre, nous traitons uniformément le middleware comme un ensemble de fonctions. Dans la classe LikeExpress, les trois méthodes use(), get() et post() peuvent toutes implémenter l'enregistrement du middleware. Seul le middleware déclenché varie en raison des différentes méthodes de requête. Nous considérons donc :
Le tableau middleware doit être placé dans une zone publique pour un accès facile par les méthodes de la classe. Nous mettons donc le tableau middleware dans la fonction constructeur constructor().
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"); });
L'enregistrement du middleware signifie stocker le middleware dans le tableau de middleware correspondant. La fonction d'enregistrement du middleware doit analyser les paramètres entrants. Le premier paramètre peut être une route ou un middleware, il faut donc d'abord déterminer s'il s'agit d'une route. Si tel est le cas, affichez-le tel quel ; sinon, la valeur par défaut est la route racine, puis convertissez les paramètres middleware restants en un tableau.
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(); };
Avec la fonction générale d'enregistrement du middleware register(), il est facile d'implémenter use(), get() et post(), il suffit de stocker le middleware dans les tableaux correspondants.
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}`); });
Lorsque le premier paramètre de la fonction d'enregistrement est une route, la fonction middleware correspondante ne sera déclenchée que lorsque le chemin de la requête correspond à la route ou est sa sous-route. Nous avons donc besoin d'une fonction de correspondance de route pour extraire le tableau middleware de la route correspondante en fonction de la méthode de requête et du chemin de requête pour que la fonction callback() suivante s'exécute :
// 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;
Ensuite, dans la fonction de rappel callback() du httpServer, extrayez le middleware qui doit être exécuté :
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"); });
Les paramètres de la fonction middleware Express sont req, res et next, où next est une fonction. Ce n'est qu'en l'appelant que les fonctions middleware peuvent être exécutées dans l'ordre, similaire à next() dans ES6 Generator. Dans notre implémentation, nous devons écrire une fonction next() avec les exigences suivantes :
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 }; }
Enfin, permettez-moi de vous présenter une plateforme très adaptée au déploiement d'Express : Leapcell.
Leapcell est une plateforme sans serveur présentant les caractéristiques suivantes :
Explorez-en davantage dans la documentation !
Twitter de Leapcell : https://x.com/LeapcellHQ
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!