web-dev-qa-db-fra.com

Comment inclure des gestionnaires d'itinéraires dans plusieurs fichiers dans Express?

Dans mon application NodeJS express, j'ai app.js qui comporte quelques itinéraires communs. Puis, dans un fichier wf.js, j'aimerais définir quelques itinéraires supplémentaires.

Comment obtenir que app.js reconnaisse les autres gestionnaires de routage définis dans le fichier wf.js?

Un simple requis ne semble pas fonctionner.

192
rafidude

Si vous voulez placer les routes dans un fichier séparé , par exemple routes.js, vous pouvez créer le fichier _routes.js_ de la manière suivante:

_module.exports = function(app){

    app.get('/login', function(req, res){
        res.render('login', {
            title: 'Express Login'
        });
    });

    //other routes..
}
_

Et ensuite, vous pouvez le demander à app.js en passant l'objet app de cette manière:

_require('./routes')(app);
_

Regardez aussi ces exemples

https://github.com/visionmedia/express/tree/master/examples/route-separation

356
BFil

En me basant sur l’exemple de @ShadowCloud, j’ai pu inclure de manière dynamique toutes les routes dans un sous-répertoire.

routes/index.js

var fs = require('fs');

module.exports = function(app){
    fs.readdirSync(__dirname).forEach(function(file) {
        if (file == "index.js") return;
        var name = file.substr(0, file.indexOf('.'));
        require('./' + name)(app);
    });
}

Ensuite, en plaçant les fichiers route dans le répertoire routes comme ceci:

routes/test1.js

module.exports = function(app){

    app.get('/test1/', function(req, res){
        //...
    });

    //other routes..
}

Répéter cela autant de fois que nécessaire et enfin dans app.js

require('./routes')(app);
93
Sam Corder

Même si c’est une question plus ancienne, j’ai trébuché ici à la recherche d’une solution à un problème similaire. Après avoir essayé certaines des solutions ici, je me suis retrouvé dans une direction différente et j'ai pensé que j'ajouterais ma solution à toute personne qui se retrouverait ici.

Dans Express 4.x, vous pouvez obtenir une instance de l'objet routeur et importer un autre fichier contenant plus de routes. Vous pouvez même le faire de manière récursive afin que vos itinéraires importent d'autres itinéraires vous permettant de créer des chemins d'accès faciles à gérer. Par exemple, si j’ai déjà un fichier de route distinct pour mon point de terminaison '/ tests' et que je souhaite ajouter un nouvel ensemble de routes pour '/ tests/automatic', il se peut que je veuille dissocier ces routes '/ automatisées' dans un autre fichier afin de: garder mon fichier '/ test' petit et facile à gérer. Il vous permet également de regrouper logiquement des itinéraires par chemin d’URL, ce qui peut être très pratique.

Contenu de ./app.js:

var express = require('express'),
    app = express();

var testRoutes = require('./routes/tests');

// Import my test routes into the path '/test'
app.use('/tests', testRoutes);

Contenu de ./routes/tests.js

var express = require('express'),
    router = express.Router();

var automatedRoutes = require('./testRoutes/automated');

router
  // Add a binding to handle '/test'
  .get('/', function(){
    // render the /tests view
  })

  // Import my automated routes into the path '/tests/automated'
  // This works because we're already within the '/tests' route so we're simply appending more routes to the '/tests' endpoint
  .use('/automated', automatedRoutes);

module.exports = router;

Contenu de ./routes/testRoutes/automated.js:

var express = require('express'),
    router = express.Router();

router
   // Add a binding for '/tests/automated/'
  .get('/', function(){
    // render the /tests/automated view
  })

module.exports = router;
86
ShortRound1911

Et construisez encore plus sur la réponse précédente, cette version de routes/index.js ignorera tous les fichiers ne se terminant pas par .js (et elle-même)

var fs = require('fs');

module.exports = function(app) {
    fs.readdirSync(__dirname).forEach(function(file) {
        if (file === "index.js" || file.substr(file.lastIndexOf('.') + 1) !== 'js')
            return;
        var name = file.substr(0, file.indexOf('.'));
        require('./' + name)(app);
    });
}
18
Brad Proctor

Routage complet récursif de tous les fichiers .js dans le dossier /routes, placez-le dans app.js.

// Initialize ALL routes including subfolders
var fs = require('fs');
var path = require('path');

function recursiveRoutes(folderName) {
    fs.readdirSync(folderName).forEach(function(file) {

        var fullName = path.join(folderName, file);
        var stat = fs.lstatSync(fullName);

        if (stat.isDirectory()) {
            recursiveRoutes(fullName);
        } else if (file.toLowerCase().indexOf('.js')) {
            require('./' + fullName)(app);
            console.log("require('" + fullName + "')");
        }
    });
}
recursiveRoutes('routes'); // Initialize it

dans /routes vous mettez whatevername.js et initialisez vos routes comme ceci:

module.exports = function(app) {
    app.get('/', function(req, res) {
        res.render('index', { title: 'index' });
    });

    app.get('/contactus', function(req, res) {
        res.render('contactus', { title: 'contactus' });
    });
}
17
infinity1975

J'essaie de mettre à jour cette réponse avec "express": "^ 4.16.3". Cette réponse est similaire à ShortRound1911.

server.js

const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const db = require('./src/config/db');
const routes = require('./src/routes');
const port = 3001;

const app = new express();

//...use body-parser
app.use(bodyParser.urlencoded({ extended: true }));

//...fire connection
mongoose.connect(db.url, (err, database) => {
  if (err) return console.log(err);

  //...fire the routes
  app.use('/', routes);

  app.listen(port, () => {
    console.log('we are live on ' + port);
  });
});

/src/routes/index.js

const express = require('express');
const app = express();

const siswaRoute = require('./siswa_route');

app.get('/', (req, res) => {
  res.json({item: 'Welcome ini separated page...'});
})
.use('/siswa', siswaRoute);

module.exports = app;

/src/routes/siswa_route.js

const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.json({item: 'Siswa page...'});
});

module.exports = app;

J'espère que cela peut aider quelqu'un. Bonne codage!

6
Sukma Saputra

Je sais que c’est une vieille question, mais j’essayais de trouver une solution pour moi-même et c’est là où je me suis retrouvé. C’est pourquoi j’ai voulu trouver une solution à un problème similaire au cas où une autre personne aurait les mêmes problèmes que moi. m avoir. Il y a un module de noeud Nice appelé consign qui fait beaucoup de choses sur le système de fichiers que l'on voit ici pour vous (c'est-à-dire - pas de choses readdirSync). Par exemple:

J'ai une application API reposante que j'essaie de créer et je veux mettre toutes les demandes qui vont dans '/ api/*' pour être authentifié et je veux stocker toutes mes routes qui vont dans api dans leur propre répertoire (appelons ça simplement 'api'). Dans la partie principale de l'application:

app.use('/api', [authenticationMiddlewareFunction], require('./routes/api'));

À l'intérieur du répertoire routes, j'ai un répertoire appelé "api" et un fichier appelé api.js. Dans api.js, j'ai simplement:

var express = require('express');
var router = express.Router();
var consign = require('consign');

// get all routes inside the api directory and attach them to the api router
// all of these routes should be behind authorization
consign({cwd: 'routes'})
  .include('api')
  .into(router);

module.exports = router;

Tout a fonctionné comme prévu. J'espère que ça aide quelqu'un.

5
Mike S.

Un Tweak à toutes ces réponses:

var routes = fs.readdirSync('routes')
      .filter(function(v){
         return (/.js$/).test(v);
      });

Utilisez simplement une expression rationnelle pour filtrer en testant chaque fichier du tableau. Ce n'est pas récursif, mais il filtrera les dossiers qui ne se terminent pas par .js

5
regretoverflow

Si vous voulez un fichier .js séparé pour mieux organiser vos itinéraires, créez simplement une variable dans le fichier app.js pointant vers son emplacement dans le système de fichiers:

var wf = require(./routes/wf);

ensuite,

app.get('/wf', wf.foo );

.foo est une fonction déclarée dans votre fichier wf.js. par exemple

// wf.js file 
exports.foo = function(req,res){

          console.log(` request object is ${req}, response object is ${res} `);

}
5
NiallJG

J'ai écrit un petit plugin pour faire ça! J'en ai marre d'écrire le même code encore et encore.

https://www.npmjs.com/package/js-file-req

J'espère que ça aide.

1
Evan Burbidge

Si vous utilisez express-4.x avec TypeScript et ES6, ce serait le meilleur modèle à utiliser;

src/api/login.ts

import express, { Router, Request, Response } from "express";

const router: Router = express.Router();
// POST /user/signin
router.post('/signin', async (req: Request, res: Response) => {
    try {
        res.send('OK');
    } catch (e) {
        res.status(500).send(e.toString());
    }
});

export default router;

src/app.ts

import express, { Request, Response } from "express";
import compression from "compression";  // compresses requests
import expressValidator from "express-validator";
import bodyParser from "body-parser";
import login from './api/login';

const app = express();

app.use(compression());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(expressValidator());

app.get('/public/hc', (req: Request, res: Response) => {
  res.send('OK');
});

app.use('/user', login);

app.listen(8080, () => {
    console.log("Press CTRL-C to stop\n");
});

Beaucoup plus clair en utilisant plutôt var et module.exports.

1
gihanchanuka

C’est peut-être la question/la réponse la plus impressionnante en matière de débordement de pile. Je amour Les solutions de Sam/Brad ci-dessus. Je pensais mettre le doigt sur la version async que j'ai implémentée:

function loadRoutes(folder){
    if (!folder){
        folder = __dirname + '/routes/';
    }

    fs.readdir(folder, function(err, files){
        var l = files.length;
        for (var i = 0; i < l; i++){
            var file = files[i];
            fs.stat(file, function(err, stat){
                if (stat && stat.isDirectory()){
                    loadRoutes(folder + '/' + file + '/');
                } else {
                    var dot = file.lastIndexOf('.');
                    if (file.substr(dot + 1) === 'js'){
                        var name = file.substr(0, dot);

                        // I'm also passing argv here (from optimist)
                        // so that I can easily enable debugging for all
                        // routes.
                        require(folder + name)(app, argv);
                    }
                }
            });
        }
    });
}

Ma structure de répertoire est un peu différente. Je définis généralement des routes dans app.js (dans le répertoire racine du projet) avec require- ing './routes'. En conséquence, je saute la vérification sur index.js parce que je veux l'inclure également.

EDIT: Vous pouvez également mettre cela dans une fonction et l'appeler de manière récursive (j'ai édité l'exemple pour le montrer) si vous voulez imbriquer vos itinéraires dans des dossiers de profondeur arbitraire.

1
tandrewnichols