Node.js / Express.js - app.router nasıl çalışır?


298

Sormadan önce app.router, en azından ara katman yazılımı ile çalışırken ne düşündüğümü açıklamam gerektiğini düşünüyorum. Ara katman yazılımı kullanmak için kullanılacak işlev app.use(). Ara katman yazılımı yürütülürken, ya bir sonraki ara katman yazılımını kullanarak next()çağrılır ya da artık ara katman yazılımı çağrılmaz. Bu, bazı ara katman yazılımları diğer ara katman yazılımlarına bağlı olduğu ve sonuna yakın bazı ara katman yazılımlarının çağrılmayabileceği için ara katman aramalarımı yerleştirdiğim sıralamanın önemli olduğu anlamına gelir.

Bugün uygulamam üzerinde çalışıyordum ve sunucum arka planda çalışıyordu. Bazı değişiklikler yapmak ve sayfamı yenilemek ve değişiklikleri hemen görmek istedim. Özellikle, düzenimde değişiklikler yapıyordum. Çalışmak için alamadım, bu yüzden cevap için Stack Overflow aradı ve bu soru bulundu . Altında olduğundan emin olmak express.static()için söylüyor require('stylus'). Ama bu OP koduna bakarken, app.routerara katman yazılım çağrılarının sonunda çağrısını gördüm ve bunun neden olduğunu anlamaya çalıştım.

Benim Express.js uygulamasını (sürüm 3.0.0rc4) yaptığında, ben komutu kullanılır express app --sessions --css stylusve benim app.js dosya kod benim ile kurulum geldi app.routeryukarıda hem express.static()ve require('stylus')çağrılar. Öyle görünüyor ki, eğer zaten bu şekilde kurulursa, o şekilde kalmalıdır.

Stylus değişikliklerimi görebilmek için kodumu yeniden düzenledikten sonra şöyle görünüyor:

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

Bu yüzden ilk adımın kodumda bile olmanın neden önemli olduğunu bulmak olduğuna karar verdim app.router. Bu yüzden yorum yaptım, uygulamamı başlattım ve adresine gittim /. Dizin sayfamı gayet iyi gösterdi. Hmm, belki de rotalarım dosyasından (route.index) yönlendirmeyi dışa aktardığım için işe yaradı. Sonra ilerledim /testve ekranda Test'i gösterdi. Haha, tamam, ne app.routeryapacağına dair hiçbir fikrim yok. Benim koduma dahil olsun ya da olmasın, benim yönlendirme gayet iyi. Bu yüzden kesinlikle bir şey eksik.

Benim sorum budur:

Birisi lütfen ne yaptığını app.router, önemini ve ara katman yazılım çağrılarıma nereye koymam gerektiğini açıklayabilir mi? Hakkında kısa bir açıklama alırsam da iyi olur express.static(). Anlayabildiğim kadarıyla, express.static()bilgilerimin önbelleğidir ve uygulama istenen sayfayı bulamazsa, var olup olmadığını görmek için önbelleği kontrol edecektir.


18
Bu soruyu sorduğunuz için teşekkür ederiz. Bu yanıtı (ve sormak için soru) bulmak için googling.
Hari Seldon

8
Bu gerçekten iyi yazılmış bir soruydu, ben de aynı şeyi yapıyordum.
Kirn

Yanıtlar:


329

Not: Bu, Express'in sürüm 2 ve 3'te nasıl çalıştığını açıklar. Express 4 hakkında bilgi için bu yayının sonuna bakın.


staticdiskteki dosyaları ( statik kaynaklar) sunar. Ona bir yol (bazen bağlama noktası da denir) verirsiniz ve bu klasördeki dosyaları sunar.

Örneğin, express.static('/var/www')bu klasördeki dosyaları sunar. İçin Düğüm sunucusuna bir istek Yani http://server/file.htmlhizmet verecek /var/www/file.html.

routerrotalarınızı çalıştıran koddur. Bunu yaptığınızda app.get('/user', function(req, res) { ... });, routeraslında isteği işlemek için geri arama işlevini başlatır.

Bir şeyleri app.useiletme sırası, her ara katman yazılımının bir isteği işleme fırsatı verildiğini belirler. Örneğin, test.htmlstatik klasörünüzde bir dosyanız ve bir rotanız varsa:

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

Hangisi istekte bulunan bir müşteriye gönderilir http://server/test.html? useÖnce hangi ara katman yazılımı verilir .

Eğer bunu yaparsan:

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

Ardından diskteki dosya sunulur.

Eğer bunu başka şekilde yaparsan,

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

Ardından rota işleyicisi isteği alır ve "Rota işleyicisinden merhaba" tarayıcıya gönderilir.

Genellikle, yanlışlıkla adlandırılmış bir dosyanın yollarınızdan birini geçersiz kılamaması için yönlendiriciyi statik ara katman yazılımının üstüne koymak istersiniz .

Açıkça belirtmezseniz use, routerbir rota tanımladığınız noktada Express tarafından dolaylı olarak eklendiğini unutmayın (bu yüzden yorum yazmanıza rağmen rotalarınız hala çalışır app.use(app.router)).


Bir yorumcu sıralamasıyla ve ele almadığımla ilgili başka bir nokta daha getirdi : Uygulamanızın genel performansı üzerindeki etkisi.staticrouter

use routerYukarıdakilerin bir başka nedeni staticperformansı optimize etmektir. staticÖnce koyarsanız , bir dosyanın var olup olmadığını görmek için her istekte sabit sürücüye çarparsınız. Bir de hızlı bir test , bu havai yüksüz bir sunucuda ~ 1 ms olarak gerçekleşti bulundu. (Bu sayı, isteklerin disk erişimi için yarışacağı yük altında daha yüksek olacaktır.)

İle routerilk, asla bir rota eşleşen bir istek değerli milisaniye tasarruf diski vurmak zorundadır.

Tabii ki, staticyükünü hafifletmenin yolları var .

En iyi seçenek, tüm statik kaynaklarınızı belirli bir klasörün altına koymaktır. (IE /static) Daha sonra staticbu yola yalnızca yol şu şekilde başladığında çalışacak şekilde bağlayabilirsiniz /static:

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

Bu durumda, bunu yukarıda yazardınız router. Bu, bir dosya varsa diğer ara katman yazılımlarını / yönlendiriciyi işlemekten kaçınır, ancak dürüst olmak gerekirse, bu kadar kazanacağınızdan şüpheliyim.

Ayrıca staticCache, yaygın olarak istenen dosyalar için diske vurmak zorunda kalmamak için statik kaynakları bellekte önbelleğe alan da kullanabilirsiniz . ( Uyarı: staticCache Görünüşe göre gelecekte kaldırılacak .)

Ancak, staticCacheolumsuz yanıtları (bir dosya olmadığında) önbelleğe almayı düşünmüyorum, bu yüzden bir yola bağlamadan staticCacheyukarıda koyarsanız yardımcı olmaz router.

Performansla ilgili tüm sorularda olduğu gibi, darboğazların gerçekten nerede olduğunu görmek için gerçek dünyadaki uygulamanızı (yük altında) ölçün ve kıyaslayın .


Hızlı 4

Express 4.0 kaldırır app.router . Tüm ara katman yazılımı ( app.use) ve yollar ( app.getet al) artık tam olarak eklendiği sırada işlenmektedir.

Diğer bir deyişle:

Tüm yönlendirme yöntemleri, göründükleri sırayla eklenir. Sen gerektiğini değil yapmak app.use(app.router). Bu, Express ile ilgili en yaygın sorunu ortadan kaldırır.

Başka bir deyişle, karıştırma app.use()ve tam olarak çağrıldıkları sırayla app[VERB]()çalışır .

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

Express 4'teki değişiklikler hakkında daha fazla bilgi edinin.


2
routerTek bir yerde gider. İlk kez app.get(veya postbaşkalarını) aradığınızda henüz used yapmadıysanız app.router, Express bunu sizin için ekler.
josh3736

4
@MikeCauser: Hayır, çünkü disk erişiminin ek yükü (bir dosyanın var olup olmadığını görmek için) işlev çağırma ek yükünden daha büyük. Benim içinde testte , o havai yüksüz bir sunucuda 1ms olarak gerçekleşti. Bu, isteklerin disk erişimi için yarışacağı yük altında daha yüksek olacaktır. İle staticsonrasÖ routero zamandan beri, diğer katman hakkında soru alakasız olur zorundadır yönlendirici üzerinde olması.
josh3736

2
Harika açıklama! Çok teşekkür ederim!
Kirn

3
app.routerolduğu kaldırılır olacak geçerli ana dalı, içinde ekspres-4,0 . Her rota ayrı bir ara katman yazılımı haline gelir.
yanychar

3
Ben bununla çalışırken bir açıklama daha. Ekspres 4'te bir yönlendiriciye birden fazla yol atanabilir ve daha sonra yönlendiriciyi kullanmak için yönlendiriciye bir kök yolu verilir ve app.use (yol, yönlendirici) aracılığıyla "ara katman" yığınına yerleştirilir. Bu, ilgili yolların her birinin kendi yönlendiricisini kullanmasına ve bir birim olarak temel yol atanmasına izin verir. Eğer daha iyi anlarsam, başka bir cevap göndermeyi öneririm. Yine, bunu scotch.io/tutorials/javascript/… adresinden
Joe Lapp

2

Yönlendirme, bir uygulamanın bir URI (veya yol) ve belirli bir HTTP istek yöntemi (GET, POST vb.) Olan belirli bir uç noktadaki istemci isteğine nasıl yanıt vereceğini belirleme anlamına gelir. Her rota, rota eşleştirildiğinde yürütülen bir veya daha fazla işleyici fonksiyonuna sahip olabilir.

Express 4.0 Router'da rotalarımızı tanımlarken her zamankinden daha fazla esneklik sağlıyoruz.

express.Router (), rota gruplarını tanımlamak için birden çok kez kullanılır.

istekleri işlemek için ara katman olarak kullanılan yol.

".param ()" kullanarak parametreleri doğrulamak için ara katman yazılımı olarak kullanılan yol.

Bir rotada birden çok istek tanımlamak için Yönlendiriciye kısayol olarak kullanılan app.route () yöntemi

app.route () kullandığımızda, uygulamamızı bu yönlendiriciye ekliyoruz.

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

Express Version 4'te rotaları aşağıdaki şekilde kolayca tanımlayabiliriz:

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;

Burada dosyanın server.jsyönlendirici nesnesini içe aktardık route.jsve aşağıdaki şekilde uyguladık server.js:

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

Artık tüm route.jstemel URL'lerde bulunan tüm yollar :

http: // localhost: 3000 / rota

Neden bu yaklaşım:

Bu yaklaşımı kullanmanın ana avantajı, şimdi uygulamamızın daha modüler olmasıdır . Belirli bir rota için tüm rota işleyicileri artık her şeyi daha sürdürülebilir ve daha kolay bulunmasını sağlayan farklı dosyalara yerleştirilebilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.