Node.js / Express.js - ऐप कैसे काम करता है?


298

इससे पहले कि मैं app.routerसोचता हूं कि मुझे लगता है कि मुझे कम से कम यह बताना चाहिए कि मिडलवेयर के साथ काम करने पर मुझे क्या लगता है। मिडलवेयर का उपयोग करने के लिए, उपयोग करने का कार्य है app.use()। जब मिडलवेयर को निष्पादित किया जा रहा है, तो यह या तो अगले मिडलवेयर का उपयोग करके कॉल करेगा या next()इसे बना देगा ताकि कोई और मिडलवेयर कॉल न हो। इसका मतलब है कि जिस क्रम में मैं अपनी मिडलवेयर कॉल करता हूं, वह महत्वपूर्ण है, क्योंकि कुछ मिडलवेयर अन्य मिडलवेयर पर निर्भर करता है, और अंत के पास के कुछ मिडलवेयर को भी नहीं बुलाया जा सकता है।

आज मैं अपने एप्लिकेशन पर काम कर रहा था और मेरा सर्वर बैकग्राउंड में चल रहा था। मैं कुछ बदलाव करना चाहता था और अपने पेज को रीफ्रेश करके तुरंत बदलाव देखना चाहता था। विशेष रूप से, मैं अपने लेआउट में परिवर्तन कर रहा था। मुझे यह काम करने के लिए नहीं मिला इसलिए मैंने उत्तर के लिए स्टैक ओवरफ्लो की खोज की और इस प्रश्न को पाया । यह सुनिश्चित करने के लिए कहता है कि express.static()नीचे है require('stylus')। लेकिन जब मैं उस ओपी कोड को देख रहा था, तो मैंने देखा कि app.routerउसके मिडलवेयर कॉल के अंत में उसका कॉल था, और मैंने यह जानने की कोशिश की कि वह क्यों था।

जब मैंने अपना Express.js एप्लिकेशन (संस्करण 3.0.0rc4) बनाया, तो मैंने कमांड का उपयोग किया express app --sessions --css stylusऔर अपने app.js फ़ाइल में कोड को मेरे app.routerऊपर express.static()और require('stylus')कॉल दोनों के साथ सेटअप किया । तो ऐसा लगता है, अगर यह पहले से ही उस तरह से आता है, तो इसे उस तरह से रहना चाहिए।

अपने कोड को फिर से व्यवस्थित करने के बाद मैं अपना स्टाइलस परिवर्तन देख सकता था, यह इस तरह दिखता है:

app.configure(function(){
  //app.set() calls
  //app.use() calls
  //...
  app.use(app.router);
  app.use(require('stylus').middleware(__dirname + '/public'));
  app.use(express.static(__dirname + '/public', {maxAge: 31557600000}));
});

app.get('/', routes.index);

app.get('/test', function(req, res){
  res.send('Test');
});

इसलिए मैंने फैसला किया कि पहला कदम यह पता लगाना होगा कि app.routerमेरे कोड में भी क्यों महत्वपूर्ण है । इसलिए मैंने इसे टिप्पणी की, अपना ऐप शुरू किया और नेविगेट किया /। इसने मेरे सूचकांक पृष्ठ को ठीक प्रदर्शित किया। हम्म, शायद यह काम किया क्योंकि मैं अपने मार्गों फ़ाइल (मार्गों.index) से मार्ग निर्यात कर रहा था। इसलिए अगली बार मैंने /testइसे नेविगेट किया और इसने स्क्रीन पर टेस्ट प्रदर्शित किया। हाहा, ठीक है, मुझे नहीं पता कि क्या app.routerकरता है। यह मेरे कोड में शामिल है या नहीं, मेरी रूटिंग ठीक है। इसलिए मुझे निश्चित रूप से कुछ याद आ रहा है।

तो ये रहा मेरा प्रश्न:

क्या कोई app.routerयह बता सकता है कि इसका क्या महत्व है, और मुझे इसे अपने मिडलवेयर कॉल में कहां रखना चाहिए? यह भी अच्छा होगा अगर मुझे इसके बारे में एक संक्षिप्त विवरण मिला express.static()। जहां तक ​​मैं बता सकता हूं, express.static()मेरी जानकारी का एक कैश है, और यदि एप्लिकेशन अनुरोधित पेज नहीं ढूंढ सकता है, तो यह देखने के लिए कैश की जांच करेगा कि क्या यह मौजूद है।


18
यह सवाल पूछने के लिए धन्यवाद। मैं इस उत्तर को खोजने के लिए चारों ओर घूम रहा हूं (और इसे शीघ्र करने के लिए प्रश्न)।
हरि सेलडन

8
यह वास्तव में अच्छी तरह से लिखा गया प्रश्न था, मैं एक ही बात पर ध्यान दे रहा था।
किरण

जवाबों:


329

नोट: यह वर्णन करता है कि एक्सप्रेस 2 और 3 में कैसे काम किया। एक्सप्रेस 4 के बारे में जानकारी के लिए इस पोस्ट का अंत देखें।


staticबस डिस्क से फ़ाइलें ( स्थिर संसाधन) कार्य करता है । आप इसे एक पथ देते हैं (कभी-कभी आरोह बिंदु कहा जाता है), और यह उस फ़ोल्डर में फ़ाइलों का कार्य करता है।

उदाहरण के लिए, express.static('/var/www')उस फ़ोल्डर में फ़ाइलों की सेवा करेंगे। तो आपके नोड सर्वर के लिए एक अनुरोध http://server/file.htmlकाम करेगा /var/www/file.html

routerवह कोड है जो आपके मार्गों को चलाता है। जब आप करते हैं app.get('/user', function(req, res) { ... });, यह routerवास्तव में अनुरोध को संसाधित करने के लिए कॉलबैक फ़ंक्शन को आमंत्रित करता है।

वह क्रम जो आप चीजों को पास करते हैं, app.useउस क्रम को निर्धारित करने के लिए जिसमें प्रत्येक मिडलवेयर को अनुरोध संसाधित करने का अवसर दिया जाता है। उदाहरण के लिए, यदि आपके पास test.htmlअपने स्थिर फ़ोल्डर और रूट में एक फ़ाइल है :

app.get('/test.html', function(req, res) {
    res.send('Hello from route handler');
});

कौन से ग्राहक को अनुरोध करने पर भेजा जाता है http://server/test.html? जो भी मिडलवेयर useपहले दिया जाता है ।

अगर तुम यह करते हो:

app.use(express.static(__dirname + '/public'));
app.use(app.router);

फिर डिस्क पर फ़ाइल परोसी जाती है।

यदि आप इसे दूसरे तरीके से करते हैं,

app.use(app.router);
app.use(express.static(__dirname + '/public'));

तब मार्ग हैंडलर को अनुरोध प्राप्त होता है, और "हैलो से रूट हैंडलर" ब्राउज़र को भेजा जाता है।

आमतौर पर, आप राउटर को स्टेटिक मिडलवेयर के ऊपर रखना चाहते हैं ताकि गलती से नाम वाली फाइल आपके किसी रूट को ओवरराइड न कर सके।

ध्यान दें कि यदि आप स्पष्ट रूप useसे नहीं करते हैं router, तो यह स्पष्ट रूप से एक्सप्रेस द्वारा जोड़ा जाता है बिंदु पर आप एक मार्ग को परिभाषित करते हैं (यही कारण है कि आपके मार्गों ने अभी भी काम किया, हालांकि आपने टिप्पणी की थी app.use(app.router))।


एक टिप्पणीकार है पाला के आदेश के बारे में एक अन्य बिंदु staticहै और routerसंबोधित नहीं है कि मैं था: अपने एप्लिकेशन के समग्र प्रदर्शन पर प्रभाव।

use routerऊपर एक और कारण staticप्रदर्शन को अनुकूलित करना है। यदि आप staticपहले डालते हैं , तो आप हर एकल अनुरोध पर हार्ड ड्राइव को देखेंगे कि कोई फ़ाइल मौजूद है या नहीं। एक त्वरित परीक्षण में , मैंने पाया कि यह ओवरहेड एक अनलोड किए गए सर्वर पर ~ 1ms था। (यह संख्या लोड के तहत अधिक होने की संभावना है, जहां अनुरोध डिस्क एक्सेस के लिए प्रतिस्पर्धा करेंगे।)

routerपहले के साथ , रूट से मेल खाने वाले अनुरोध में डिस्क को हिट करने के लिए कभी नहीं, कीमती मिलीसेकंड की बचत होती है।

बेशक, staticउपरि को कम करने के तरीके हैं ।

सबसे अच्छा विकल्प अपने सभी स्थिर संसाधनों को एक विशिष्ट फ़ोल्डर के तहत रखना है। (IE /static) तब आप staticउस पथ पर चढ़ सकते हैं ताकि वह केवल तभी चले जब पथ आरंभ होता है /static:

app.use('/static', express.static(__dirname + '/static'));

इस स्थिति में, आप इसे ऊपर रखेंगे router। यह अन्य मिडलवेयर / राउटर को संसाधित करने से बचता है यदि कोई फ़ाइल मौजूद है, लेकिन ईमानदार होने के लिए, मुझे संदेह है कि आप इसे बहुत अधिक प्राप्त करेंगे।

आप उपयोग भी कर सकते हैं staticCache, जो स्थैतिक संसाधनों को स्मृति में कैश करता है ताकि आपको आमतौर पर अनुरोधित फ़ाइलों के लिए डिस्क को हिट न करना पड़े। ( चेतावनी: staticCache जाहिर तौर पर भविष्य में हटा दी जाएगी।)

हालाँकि, मुझे नहीं लगता है कि staticCacheनकारात्मक उत्तर कैश करते हैं (जब कोई फ़ाइल मौजूद नहीं है), तो यह मदद नहीं करता है अगर आपने इसे एक पथ पर माउंट किए बिना staticCacheऊपर रखा है router

प्रदर्शन के बारे में सभी सवालों के साथ, मापें और अपने वास्तविक दुनिया ऐप (लोड के तहत) को देखें कि वास्तव में अड़चनें कहां हैं।


एक्सप्रेस ४

एक्सप्रेस 4.0 निकालता है app.router । सभी मिडलवेयर ( app.use) और मार्गों ( app.getएट अल) को अब ठीक उसी क्रम में संसाधित किया जाता है जिसमें वे जोड़े जाते हैं।

दूसरे शब्दों में:

सभी रूटिंग विधियों को उस क्रम में जोड़ा जाएगा जिसमें वे दिखाई देते हैं। आपको नहीं करना चाहिए app.use(app.router)। यह एक्सप्रेस के साथ सबसे आम मुद्दे को समाप्त करता है।

दूसरे शब्दों में, मिश्रण app.use()और ठीक उसी क्रम में app[VERB]()काम करेगा जिस क्रम में उन्हें बुलाया जाता है।

app.get('/', home);
app.use('/public', require('st')(process.cwd()));
app.get('/users', users.list);
app.post('/users', users.create);

एक्सप्रेस 4 में बदलाव के बारे में और पढ़ें।


2
routerएक ही स्थान पर चला जाता है। यदि, आप पहली बार कॉल app.get(या postअन्य) करते हैं, तो आप अभी तक used नहीं app.routerहैं, एक्सप्रेस आपके लिए इसे जोड़ता है।
josh3736

4
@ माइक कैसर: नहीं, क्योंकि डिस्क एक्सेस का ओवरहेड (यह देखने के लिए कि फाइल मौजूद है या नहीं) फ़ंक्शन इनवोकेशन के ओवरहेड से बड़ा है। मेरे परीक्षण में , वह ओवरहेड एक अनलोड किए गए सर्वर पर 1ms तक था। यह लोड के तहत अधिक होने की संभावना है, जहां डिस्क एक्सेस के लिए अनुरोध प्रतिस्पर्धा करेंगे। इसके staticबाद router, अन्य मिडलवेयर के बारे में सवाल अप्रासंगिक हो जाता है क्योंकि यह राउटर के ऊपर होना चाहिए।
josh3736

2
अद्भुत व्याख्या! आपको बहुत - बहुत धन्यवाद!
किरण

3
app.routerवर्तमान मास्टर शाखा में हटा दिया जाता है , जो एक्सप्रेस-4.0 होगा । प्रत्येक मार्ग एक अलग मिडलवेयर बन जाता है।
यानि

3
एक और स्पष्टीकरण, जैसा कि मैं इस के साथ काम करता हूं। एक्सप्रेस 4 में, कई मार्गों को एक राउटर को सौंपा जा सकता है, और फिर राउटर का उपयोग करने के लिए, राउटर को एक रूट पथ दिया जाता है और app.use (पथ, राउटर) के माध्यम से "मिडलवेयर" स्टैक में रखा जाता है। इससे संबंधित मार्ग प्रत्येक को अपने स्वयं के राउटर का उपयोग करने और एक इकाई के रूप में एक आधार पथ सौंपा जा सकता है। अगर मैंने इसे बेहतर समझा, तो मैं एक और उत्तर पोस्ट करने की पेशकश करूंगा। फिर से, मैं इसे scotch.io/tutorials/javascript/…
जो लैप

2

रूटिंग का अर्थ है यह निर्धारित करना कि कोई एप्लिकेशन किसी विशेष समापन बिंदु पर क्लाइंट अनुरोध का जवाब कैसे देता है, जो एक यूआरआई (या पथ) और एक विशिष्ट HTTP अनुरोध विधि (GET, POST, और इसी तरह) है। प्रत्येक मार्ग में एक या एक से अधिक हैंडलर फ़ंक्शन हो सकते हैं, जो रूट से मेल खाने पर निष्पादित होते हैं।

एक्सप्रेस 4.0 राउटर में, हमें अपने मार्गों को परिभाषित करने में पहले से कहीं अधिक लचीलापन दिया जाता है।

एक्सप्रेस। रूटर () मार्गों के समूहों को परिभाषित करने के लिए कई बार उपयोग किया जाता है।

अनुरोधों को संसाधित करने के लिए मिडलवेयर के रूप में उपयोग किया जाने वाला मार्ग।

".param ()" का उपयोग करके मापदंडों को मान्य करने के लिए मिडलवेयर के रूप में उपयोग किया जाने वाला मार्ग।

app.route () एक मार्ग पर कई अनुरोधों को परिभाषित करने के लिए राउटर के शॉर्टकट के रूप में उपयोग किया जाता है

जब हम app.route () का उपयोग कर रहे हैं, हम उस राउटर के साथ अपना ऐप संलग्न कर रहे हैं।

var express = require('express'); //used as middleware
var app = express(); //instance of express.
app.use(app.router);
app.use(express.static(__dirname + '/public')); //All Static like [css,js,images] files are coming from public folder
app.set('views',__dirname + '/views'); //To set Views
app.set('view engine', 'ejs'); //sets View-Engine as ejs
app.engine('html', require('ejs').renderFile); //actually rendering HTML files through EJS. 
app.get('/', function (req, res) {
  res.render('index');  
})
app.get('/test', function (req, res) {
  res.send('test')
})

0

एक्सप्रेस संस्करण 4 में हम निम्नलिखित तरीके से मार्गों को आसानी से परिभाषित कर सकते हैं:

server.js:

const express = require('express');
const app = express();
const route = require('./route');

app.use('/route', route);
// here we pass in the imported route object

app.listen(3000, () => console.log('Example app listening on port 3000!'));

route.js:

const express = require('express');
const router = express.Router();

router.get('/specialRoute', function (req, res, next) {
     // route is now http://localhost:3000/route/specialRoute
});

router.get('/', function (req, res, next) {
    // route is now http://localhost:3000/route
});

module.exports = router;

में server.jsहम में से रूटर वस्तु आयातित route.jsफ़ाइल और में निम्नलिखित तरीके से इसे लागू server.js:

app.use('/route', route);

अब सभी मार्गों में route.jsनिम्न आधार URL है:

http: // localhost: 3000 / मार्ग

यह दृष्टिकोण क्यों:

इस दृष्टिकोण को लेने का मुख्य लाभ यह है कि अब हमारा ऐप अधिक मॉड्यूलर है । एक निश्चित मार्ग के लिए सभी मार्ग संचालकों को अब अलग-अलग फाइलों में डाला जा सकता है, जो सब कुछ अधिक टिकाऊ और खोजने में आसान बनाता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.