Antes de perguntar app.router
, acho que devo explicar pelo menos o que acho que acontece quando se trabalha com middleware. Para usar o middleware, a função a ser usada é app.use()
. Quando o middleware estiver sendo executado, ele chamará o próximo middleware usando next()
ou fará com que ele não seja mais chamado. Isso significa que a ordem na qual eu faço minhas chamadas de middleware é importante, porque alguns middlewares dependem de outros middlewares, e alguns middlewares próximos ao final podem nem ser chamados.
Hoje eu estava trabalhando no meu aplicativo e meu servidor estava sendo executado em segundo plano. Eu queria fazer algumas alterações, atualizar minha página e ver as alterações imediatamente. Especificamente, eu estava fazendo alterações no meu layout. Não consegui fazê-lo funcionar, então procurei a Stack Overflow e encontrei esta pergunta . Diz para garantir que express.static()
está embaixo require('stylus')
. Mas quando eu estava olhando para o código do OP, vi que ele recebeu sua app.router
ligação no final de suas chamadas de middleware e tentei descobrir por que isso acontecia.
Quando criei meu aplicativo Express.js (versão 3.0.0rc4), usei o comando express app --sessions --css stylus
e, no meu arquivo app.js, o código veio configurado com app.router
as chamadas acima express.static()
e acima require('stylus')
. Então parece que, se já vem configurado dessa maneira, deve permanecer assim.
Depois de reorganizar meu código para que eu pudesse ver minhas alterações no Stylus, fica assim:
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');
});
Então, decidi que o primeiro passo seria descobrir por que é importante ter app.router
no meu código. Então, comentei, iniciei meu aplicativo e naveguei para /
. Ele exibiu minha página de índice muito bem. Hmm, talvez tenha funcionado porque eu estava exportando o roteamento do meu arquivo de rotas (routes.index). Então, em seguida, naveguei /test
e exibi Teste na tela. Haha, ok, eu não tenho ideia do que app.router
faz. Esteja ou não incluído no meu código, meu roteamento está correto. Então, definitivamente estou perdendo alguma coisa.
Então aqui está a minha pergunta:
Alguém poderia explicar o que app.router
faz, a importância e onde devo colocá-lo nas minhas chamadas de middleware? Também seria bom se eu tivesse uma breve explicação sobre express.static()
. Pelo que sei, express.static()
há um cache de minhas informações e, se o aplicativo não conseguir encontrar a página solicitada, ele verificará o cache para verificar se existe.
fonte
Respostas:
Nota: Isso descreve como o Express funcionou nas versões 2 e 3. Consulte o final desta postagem para obter informações sobre o Express 4.
static
simplesmente serve arquivos ( recursos estáticos ) do disco. Você indica um caminho (às vezes chamado de ponto de montagem) e ele serve os arquivos nessa pasta.Por exemplo,
express.static('/var/www')
serviria os arquivos nessa pasta. Portanto, uma solicitação para o servidor Nodehttp://server/file.html
seria veiculada/var/www/file.html
.router
é um código que executa suas rotas. Quando você fazapp.get('/user', function(req, res) { ... });
isso, é orouter
que realmente chama a função de retorno de chamada para processar a solicitação.A ordem em que você passa as coisas
app.use
determina a ordem na qual cada middleware tem a oportunidade de processar uma solicitação. Por exemplo, se você tiver um arquivo chamadotest.html
na sua pasta estática e uma rota:Qual deles é enviado para um cliente solicitando
http://server/test.html
? Qualquer que seja o middleware fornecidouse
primeiro.Se você fizer isto:
Em seguida, o arquivo no disco é servido.
Se você fizer o contrário,
Em seguida, o manipulador de rotas recebe a solicitação e "Olá do manipulador de rotas" é enviado ao navegador.
Geralmente, você deseja colocar o roteador acima do middleware estático para que um arquivo chamado acidentalmente não possa substituir uma das suas rotas.
Note que se você não fizer isso explicitamente
use
orouter
, ele é implicitamente adicionado por expresso no ponto em que definir uma rota (que é por isso que suas rotas ainda funcionava mesmo que você comentadoapp.use(app.router)
).Um comentarista levantou outro ponto sobre a ordem
static
erouter
que eu não havia abordado: o impacto no desempenho geral do seu aplicativo.Outro motivo
use
router
acimastatic
é otimizar o desempenho. Se você colocarstatic
primeiro, você acessará o disco rígido em cada solicitação para verificar se existe ou não um arquivo. Em um teste rápido , descobri que essa sobrecarga era de ~ 1ms em um servidor descarregado. (É muito provável que esse número seja maior sob carga, onde as solicitações competirão pelo acesso ao disco.)Com o
router
primeiro, uma solicitação correspondente a uma rota nunca precisa atingir o disco, economizando milissegundos preciosos.Obviamente, existem maneiras de atenuar
static
a sobrecarga.A melhor opção é colocar todos os seus recursos estáticos em uma pasta específica. (IE
/static
) Você pode montarstatic
nesse caminho para que ele seja executado somente quando o caminho iniciar com/static
:Nesta situação, você colocaria isso acima
router
. Isso evita o processamento de outro middleware / roteador se houver um arquivo, mas, para ser sincero, duvido que você ganhe muito.Você também pode usar
staticCache
, que armazena em cache recursos estáticos na memória para que você não precise atingir o disco para obter os arquivos solicitados com mais freqüência. ( Aviso:staticCache
aparentemente será removido no futuro.)No entanto, não creio que
staticCache
oculte respostas negativas (quando um arquivo não existe), portanto, não ajuda se você colocoustaticCache
acimarouter
sem montá-lo em um caminho.Como em todas as perguntas sobre desempenho, meça e avalie seu aplicativo do mundo real (sob carga) para ver onde realmente estão os gargalos.
Express 4
O Express 4.0 é removido
app.router
. Todos os middlewares (app.use
) e rotas (app.get
et al) agora são processados exatamente na ordem em que são adicionados.Em outras palavras:
Leia mais sobre alterações no Express 4.
fonte
router
vai em um só lugar. Se, na primeira vez em que você ligarapp.get
(ou empost
outros), ainda não tiveruse
dapp.router
, o Express o adicionará para você.static
depoisrouter
, a pergunta sobre o outro middleware se torna irrelevante, pois deve estar acima do roteador.app.router
é removido no ramo mestre atual, que será express-4.0 . Cada rota se torna um middleware separado.fonte
Na versão expressa 4, podemos facilmente definir rotas da seguinte maneira:
server.js:
route.js:
Em
server.js
nós importamos o objeto roteador doroute.js
arquivo e o aplicamos da seguinte maneira emserver.js
:Agora, todas as rotas no
route.js
têm o seguinte URL base:http: // localhost: 3000 / route
Por que essa abordagem:
A principal vantagem de adotar essa abordagem é que agora nosso aplicativo é mais modular . Todos os manipuladores de rota para uma determinada rota agora podem ser colocados em arquivos diferentes, o que torna tudo mais sustentável e fácil de encontrar.
fonte