एक्सप्रेस में कई फाइलों में रूट हैंडलर कैसे शामिल करें?


223

मेरे नोड्स expressएप्लिकेशन में मेरे पास app.jsकुछ सामान्य मार्ग हैं। फिर एक wf.jsफ़ाइल में मैं कुछ और मार्गों को परिभाषित करना चाहूंगा।

मैं फ़ाइल app.jsमें परिभाषित अन्य मार्ग संचालकों को कैसे पहचान सकता हूं wf.js?

एक साधारण आवश्यकता काम नहीं लगती है।


2
इस जवाब की जांच stackoverflow.com/a/38718561/1153703
Bikesh एम

जवाबों:


399

यदि आप मार्गों को एक अलग फ़ाइल में रखना चाहते हैं , उदाहरण के लिए routes.js, आप routes.jsफ़ाइल को इस तरह से बना सकते हैं :

module.exports = function(app){

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

    //other routes..
}

और फिर आपको वस्तु को इस तरह से app.jsपास करने की आवश्यकता हो सकती है :app

require('./routes')(app);

इन उदाहरणों पर भी एक नजर डालिए

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


18
दरअसल, लेखक (TJ Holowaychuck) एक बेहतर दृष्टिकोण देता है: vimeo.com/56166857
avetisk

एकाधिक फ़ाइलों के लिए रूटिंग समस्या को हल करता है, लेकिन एप्लिकेशन में परिभाषित फ़ंक्शन रूटों में पहुंच योग्य नहीं होते हैं।
XIMRX

5
यदि आपको कुछ कार्यों की आवश्यकता है, तो बस उन्हें किसी अन्य मॉड्यूल / फ़ाइल में डालें और इसे app.js और मार्गों दोनों से की आवश्यकता होगी ।js
BFil

2
मैंने सब कुछ सुना है लेकिन आवश्यकता है ('./ मार्गों') (ऐप) इस सिंटेक्स ने मेरे दिमाग को उड़ा दिया है, क्या कोई मुझे बता सकता है कि यह वास्तव में क्या है, या इसका उपयोग क्या है जहाँ तक मुझे इसकी पासिंग ऐप ऑब्जेक्ट "ऐप" पता है
ANJJa

6
नीचे इस सवाल का बेहतर जवाब है - stackoverflow.com/a/37309212/297939
दिमित्री

124

हालांकि यह एक पुराना सवाल है कि मैं यहां एक समान मुद्दे के समाधान की तलाश में ठोकर खाई। यहाँ कुछ समाधानों की कोशिश करने के बाद मैंने एक अलग दिशा में जाना समाप्त किया और सोचा कि मैं अपना समाधान किसी और के लिए जोड़ूंगा जो यहाँ समाप्त होता है।

एक्सप्रेस 4.x में आप राउटर ऑब्जेक्ट का एक उदाहरण प्राप्त कर सकते हैं और एक अन्य फ़ाइल आयात कर सकते हैं जिसमें अधिक मार्ग हैं। आप इसे पुनरावर्ती रूप से भी कर सकते हैं, इसलिए आपके मार्ग अन्य मार्गों को आयात करते हैं, जिससे आपको url पथ बनाए रखने में आसानी होती है। उदाहरण के लिए यदि मेरे पास मेरे / 'परीक्षणों' के समापन बिंदु के लिए पहले से ही एक अलग रूट फ़ाइल है और '/ परीक्षण / स्वचालित' के लिए मार्गों का एक नया सेट जोड़ना चाहते हैं, तो मैं इन '/ स्वचालित' मार्गों को किसी अन्य फ़ाइल में तोड़ना चाहता हूँ। मेरी '/ परीक्षण' फ़ाइल को छोटा और प्रबंधित करने के लिए आसान रखें। यह आपको URL पथ द्वारा तार्किक रूप से समूह मार्ग भी देता है जो वास्तव में सुविधाजनक हो सकता है।

/ .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);

की सामग्री ./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;

./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;

2
यह सबसे अच्छा उत्तर है, सूची में सबसे ऊपर होना चाहिए! धन्यवाद
कोस्तनोस

क्या मैं नोड जेएस रेस्ट एपीआई के लिए इस संरचना का उपयोग कर सकता हूं?
एमएसएम

@MSMurugan yep u इस पैटर्न के साथ एक बाकी एपीआई का निर्माण कर सकता है।
शॉर्टराउंड1911

@ ShortRound1911 मैं एक बाकी एपीआई का निर्माण कर रहा हूं और इस प्लानिंग होस्टिंग सर्वर में डालूंगा, मुझे एक त्रुटि मिल रही है
एमएसएम

96

@ShadowCloud के उदाहरण पर बिल्डिंग मैं एक उप निर्देशिका में सभी मार्गों को गतिशील रूप से शामिल करने में सक्षम था।

मार्गों / 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);
    });
}

फिर रूट डायरेक्टरी में रूट फाइल को इस तरह रखना:

मार्गों / test1.js

module.exports = function(app){

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

    //other routes..
}

दोहरा कि के लिए कई बार के रूप के रूप में मैं में अंत में की जरूरत है और फिर app.js रखने

require('./routes')(app);

1
मैं इस दृष्टिकोण को बेहतर पसंद करता हूं, मुख्य एप्लिकेशन फ़ाइल के लिए कुछ भी जोड़ने के बिना नए मार्गों को जोड़ने की अनुमति देता है।
जेसन Miesionczek 4

3
अच्छा, मैं इस दृष्टिकोण का भी उपयोग करता हूं , फ़ाइल एक्सटेंशन की अतिरिक्त जांच के साथ जैसा कि मैंने स्वैप फ़ाइलों के साथ समस्याओं का सामना किया है।
गीकफिश

तुम भी readdirSync w / यह प्रयोग करने की जरूरत नहीं है, readdir ठीक काम करता है।
पॉल

5
क्या निर्देशिका में फ़ाइलों को पढ़ने के लिए इस पद्धति का उपयोग करने में कोई ओवरहेड है। बस आपके app.js फ़ाइल में मार्गों की आवश्यकता है?
अबादबा ३

मैं @Aadaba के समान भी जानना चाहूंगा। इसका मूल्यांकन कब किया जाता है, जब आप सर्वर या हर अनुरोध पर लॉन्च करते हैं?
imns

19

और पिछले उत्तर पर और अधिक निर्माण करें, मार्गों / index.js के इस संस्करण में .js (और अपने आप) समाप्त न होने वाली किसी भी फ़ाइल को अनदेखा कर दिया जाएगा।

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);
    });
}

इसके लिए धन्यवाद। मैं एक पर एक था MAC .DS_Storeफ़ाइलें जोड़ने और यह सब कुछ गड़बड़ कर रहा था।
JayQuerie.com

19

फ़ोल्डर के .jsअंदर सभी फ़ाइलों की पूर्ण पुनरावर्ती रूटिंग /routes, इसे डालें 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

इस तरह से /routesआप whatevername.jsअपने मार्गों को आरंभ और आरंभ करेंगे:

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' });
    });
}

8

मैं इस उत्तर को "एक्सप्रेस": "^ 4.16.3" के साथ अपडेट करने का प्रयास कर रहा हूं। यह उत्तर 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;

मुझे उम्मीद है कि यह किसी की मदद कर सकता है। हैप्पी कोडिंग!


8

यदि आप टाइपस्क्रिप्ट और ES6 के साथ एक्सप्रेस 4.x का उपयोग कर रहे हैं , तो यह उपयोग करने के लिए सबसे अच्छा टेम्पलेट होगा:

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");
});

उपयोग करने की तुलना में बहुत क्लीनर varऔर module.exports


5

इन सभी उत्तरों के लिए एक ट्वीक करें:

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

सरणी में प्रत्येक फ़ाइल का परीक्षण करके फ़िल्टर करने के लिए बस एक regex का उपयोग करें। यह पुनरावर्ती नहीं है, लेकिन यह उन फ़ोल्डरों को फ़िल्टर कर देगा जो .js में समाप्त नहीं होते हैं


5

मुझे पता है कि यह एक पुराना प्रश्न है, लेकिन मैं अपने लिए कुछ जानने की कोशिश कर रहा था और यह वह जगह है जिस पर मैं समाप्त हुआ था, इसलिए मैं इसी तरह की समस्या के लिए अपना समाधान रखना चाहता था जब किसी और के पास समान मुद्दे हों ' मैं कर रहा हूँ वहाँ एक अच्छा नोड मॉड्यूल है जिसे कंसाइन कहा जाता है जो आपके लिए यहां देखी जाने वाली फ़ाइल सिस्टम सामग्री का एक बहुत कुछ करता है (यानी - कोई readdirSync सामान)। उदाहरण के लिए:

मेरे पास एक आरामदायक एपीआई एप्लिकेशन है जिसे मैं बनाने की कोशिश कर रहा हूं और मैं उन सभी अनुरोधों को रखना चाहता हूं जो '/ एपीआई / *' पर जाते हैं और प्रमाणित होना चाहते हैं और मैं अपने सभी मार्गों को संग्रहीत करना चाहता हूं जो एपीआई में अपनी निर्देशिका में जाते हैं। (चलो इसे 'आपी' कहते हैं)। एप्लिकेशन के मुख्य भाग में:

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

मार्ग निर्देशिका के अंदर, मेरे पास "एपीआई" नामक एक निर्देशिका और एपीआई.जेएस नामक एक फाइल है। Api.js में, मेरे पास बस:

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;

सब कुछ उम्मीद के मुताबिक काम किया। आशा है कि यह किसी की मदद करता है।


5

यदि आप अपने मार्गों को बेहतर ढंग से व्यवस्थित करने के लिए एक अलग .js फ़ाइल चाहते हैं, तो app.jsफ़ाइल सिस्टम में इसके स्थान की ओर इशारा करते हुए फ़ाइल में एक चर बनाएं :

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

फिर,

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

.fooआपकी wf.jsफ़ाइल में कुछ फ़ंक्शन कहाँ घोषित किया गया है । जैसे

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

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

}

1
+1। यह यहाँ आधिकारिक उदाहरण में दिखाया गया है: github.com/strongloop/express/tree/master/examples/…
मैट ब्राउन

1
क्या यह app.js के तहत वैश्विक कार्यों और चर साझा करने के लिए काम करता है? या क्या आप उन्हें "पास" करेंगे wf.fooआदि, क्योंकि वे अन्य प्रस्तुत समाधानों के साथ दायरे से बाहर हैं? मैं उस मामले का जिक्र कर रहा हूं जहां आम तौर पर आप साझा किए गए चर / कार्यों को wf.foo में एक्सेस करेंगे, अगर यह ऐप से अलग नहीं हुआ है।
डेविड

हाँ यह करता है, यदि आप app.js में 'foo' फंक्शन की घोषणा करते हैं तो app.get ('/ wf', foo); काम करेगा
NiallJG


0

यह संभवतः अब तक का सबसे भयानक स्टैक ओवरफ्लो प्रश्न / उत्तर है। मैं प्यार से ऊपर सैम / ब्राड का समाधान। सोचा था कि मैं async संस्करण है कि मैं कार्यान्वित के साथ झंकार में हूँ:

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);
                    }
                }
            });
        }
    });
}

मेरी निर्देशिका संरचना थोड़ी अलग है। मैं आम तौर पर द्वारा app.js में मार्गों (परियोजना के रूट निर्देशिका में) को परिभाषित requireआईएनजी './routes'। नतीजतन, मैं चेक को छोड़ रहा हूं index.jsक्योंकि मैं उसे भी शामिल करना चाहता हूं ।

संपादित करें: आप इसे एक फ़ंक्शन में भी डाल सकते हैं और इसे पुनरावर्ती रूप से कॉल कर सकते हैं (मैंने इसे दिखाने के लिए उदाहरण संपादित किया है) यदि आप अपने मार्गों को मनमाने गहराई के फ़ोल्डरों में घोंसला बनाना चाहते हैं।


2
आप aysnc संस्करण क्यों चाहते हैं? संभवत: आप ट्रैफ़िक की सेवा शुरू करने से पहले अपने सभी मार्गों को स्थापित करना चाहते हैं अन्यथा आप कुछ 'गलत' 404 भेज सकते हैं।
जो अब्राम्स

6
वास्तव में। मैंने इसे अभी भी नोड सीखते हुए लिखा है। मैं पूर्वव्यापी में सहमत हूं कि इसका कोई मतलब नहीं है।
tandrewnichols

0

आप अन्य फ़ाइल (मॉड्यूल) में सभी रूट फ़ंक्शंस डाल सकते हैं, और इसे मुख्य सर्वर फ़ाइल से लिंक कर सकते हैं। मुख्य एक्सप्रेस फ़ाइल में, एक फ़ंक्शन जोड़ें जो मॉड्यूल को सर्वर से लिंक करेगा:

   function link_routes(app, route_collection){
       route_collection['get'].forEach(route => app.get(route.path, route.func));
       route_collection['post'].forEach(route => app.post(route.path, route.func));
       route_collection['delete'].forEach(route => app.delete(route.path, route.func));
       route_collection['put'].forEach(route => app.put(route.path, route.func));
   }

और प्रत्येक रूट मॉडल के लिए उस फ़ंक्शन को कॉल करें:

link_routes(app, require('./login.js'))

मॉड्यूल फ़ाइलों में (उदाहरण के लिए - login.js फ़ाइल), हमेशा की तरह कार्यों को परिभाषित करें:

const login_screen = (req, res) => {
    res.sendFile(`${__dirname}/pages/login.html`);
};

const forgot_password = (req, res) => {
    console.log('we will reset the password here')
}

और एक कुंजी के रूप में अनुरोध विधि के साथ इसे निर्यात करें और मूल्य वस्तुओं की एक सरणी है, प्रत्येक पथ और फ़ंक्शन कुंजियों के साथ।

module.exports = {
   get: [{path:'/',func:login_screen}, {...} ],
   post: [{path:'/login:forgotPassword', func:forgot_password}]
};   
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.