Como faço para definir uma variável app.jse tê-la disponível em todas as rotas, pelo menos no index.jsarquivo localizado nas rotas. usando a estrutura expressa enode.js
O objeto app.locals possui propriedades que são variáveis locais dentro do aplicativo. Em seu arquivo de rota, faça referência a ele com req.app.locals.
Ronnie Royston
Respostas:
63
Para fazer uma variável global, basta declará-la sem a varpalavra - chave. (De modo geral, essa não é a prática recomendada, mas em alguns casos pode ser útil - apenas tome cuidado, pois isso tornará a variável disponível em todos os lugares.)
//we can now access 'app' without redeclaring it or passing it in.../*
* GET home page.
*/
app.get('/',function(req, res, next){
res.render('index');});//...
Como uma observação, geralmente é melhor ser explícito sobre passar variáveis e instanciá-las, para que você não anule acidentalmente o ref em algum outro lugar do aplicativo, ou o que quer que seja.
Paul
3
Isso é realmente péssimo, como Paul observou. Eu sugeriria o padrão de injeção mencionado abaixo. Sim, mais código padrão para que não pareça "bonito", mas garante que seu código seja modular ... algo que você vai gostar se este não for seu último projeto;)
srquinn
Depende das circunstâncias IMHO. Sim, vars globais geralmente não são uma boa prática (como afirmei em minha resposta) e, ao começar do zero, diria que organize tudo em módulos separados. Mas se você estiver integrando com o código existente, muitas vezes há outras considerações - esta é uma solução (fácil, mas perigosa).
Jesse Fulton
2
Alguém poderia explicar por que isso funciona em referência à semântica do Javascript? A qual escopo é appassociado?
Ali
Não acho que essa resposta deva ser marcada como correctuma.
Code Cooker
91
Na verdade, é muito fácil fazer isso usando os métodos "set" e "get" disponíveis em um objeto expresso.
Exemplo a seguir, digamos que você tenha uma variável chamada config com as coisas relacionadas à configuração que deseja disponibilizar em outros lugares:
Em app.js:
var config = require('./config');
app.configure(function(){...
app.set('config', config);...}
Em routes / index.js
exports.index =function(req, res){var config = req.app.get('config');// config is now available...}
Definir 'app' global? Sim. Mas este método é o melhor para nos salvar de problemas e caos.
diproart
52
para quem chega atrasado: app.configure é removido no expresso 4.x
zamil
Legal, req.app.get('name')funciona como um encanto. Esta propriedade contém uma referência à instância do aplicativo Express que está usando o middleware. expressjs.com/pt-br/api.html#req.app
Lazaro Fernandes Lima Suleiman
57
Uma maneira interessante de fazer isso é usar o app.localspróprio Express.
Aqui está a documentação.
// In app.js:
app.locals.variable_you_need =42;// In index.js
exports.route =function(req, res){var variable_i_needed = req.app.locals.variable_you_need;}
Usei esse método para localizar serviços http e substituí-los facilmente em testes de unidade.
Alex
28
Para declarar uma variável global, você precisa usar objeto global . Como global.yourVariableName. Mas não é um caminho verdadeiro. Para compartilhar variáveis entre módulos, tente usar o estilo de injeção como
Então, você está trabalhando com um conjunto de módulos Node, talvez uma estrutura como Express.js, e de repente sente a necessidade de tornar algumas variáveis globais. Como você torna as variáveis globais no Node.js?
O conselho mais comum para este é "declarar a variável sem a palavra-chave var" ou "adicionar a variável ao objeto global" ou "adicionar a variável ao objeto GLOBAL". Qual destes você usa?
Primeiro, vamos analisar o objeto global. Abra um terminal, inicie um Node REPL (prompt).
No Express - ao usar jshint ou linting, em geral - isso se torna um problema.
Steven Ventimiglia
5
Esta foi uma pergunta útil, mas poderia ser ainda mais fornecendo exemplos de código reais. Mesmo o artigo vinculado não mostra realmente uma implementação. Eu, portanto, humildemente submeto:
No seu app.jsarquivo, a parte superior do arquivo:
var express = require('express'), http = require('http'), path = require('path');
app = express();//IMPORTANT! define the global app variable prior to requiring routes!var routes = require('./routes');
app.js não terá nenhuma referência ao app.get()método. Deixe-os para serem definidos nos arquivos de rotas individuais.
routes/index.js:
require('./main');
require('./users');
e, finalmente, um arquivo de rotas real routes/main.js:
function index (request, response){
response.render('index',{ title:'Express'});}
app.get('/',index);// <-- define the routes here now, thanks to the global app variable
Minha maneira preferida é usar dependências circulares *, cujo nó suporta
em app.js define var app = module.exports = express();como sua primeira ordem de negócios
Agora, qualquer módulo necessário após o fato pode var app = require('./app')acessá-lo
app.js
var express = require('express');var app = module.exports = express();//now app.js can be required to bring app into any file//some app/middleware, config, setup, etc, including app.use(app.router)
require('./routes');//module.exports must be defined before this line
rotas / index.js
var app = require('./app');
app.get('/',function(req, res, next){
res.render('index');});//require in some other route files...each of which requires app independently
require('./user');
require('./blog');
Ótima dica. Acabei de mudar do método require ('./ myroutes') (app) para fazer isso e bati minha cabeça contra a parede por 10 minutos tentando descobrir por que nenhuma de minhas rotas funcionou. Não se esqueça de retirar especificações de rota em myroutes.js de um bloco de funções. Doh!
Greg
2
Como outros já compartilharam, app.set('config', config)é ótimo para isso. Eu só queria acrescentar algo que não vi nas respostas existentes que é muito importante. Uma instância do Node.js é compartilhada entre todas as solicitações, portanto, embora possa ser muito prático compartilhar alguns configou routerobjetos globalmente, o armazenamento de dados de tempo de execução globalmente estará disponível nas solicitações e usuários . Considere este exemplo muito simples:
var express = require('express');var app = express();
app.get('/foo',function(req, res){
app.set('message',"Welcome to foo!");
res.send(app.get('message'));});
app.get('/bar',function(req, res){
app.set('message',"Welcome to bar!");// some long running async functionvar foo =function(){
res.send(app.get('message'));};
setTimeout(foo,1000);});
app.listen(3000);
Se você visitar /bare outro pedido /fooaparecer, sua mensagem será "Bem-vindo ao foo!". Este é um exemplo bobo, mas mostra o que quero dizer.
Resolvi o mesmo problema, mas tive que escrever mais código. Criei um server.jsarquivo, que usa expresso para cadastrar rotas. Ele expõe uma função,, registerque pode ser usada por outros módulos para registrar suas próprias rotas. Ele também expõe uma função startServer, para começar a escutar uma porta
server.js
const express = require('express');const app = express();constregister=(path,method,callback)=> methodCalled(path, method, callback)const methodCalled =(path, method, cb)=>{switch(method){case'get':
app.get(path,(req, res)=> cb(req, res))break;......default:
console.log("there has been an error");}}const startServer =(port)=> app.listen(port,()=>{console.log(`successfully started at ${port}`)})
module.exports ={register,
startServer
}
Em outro módulo, use este arquivo para criar uma rota.
help.js
const app = require('../server');const registerHelp =()=>{
app.register('/help','get',(req, res)=>{
res.send("This is the help section")}),
app.register('/help','post',(req, res)=>{
res.send("This is the help section")})}
module.exports ={
registerHelp
}
A resposta de John Gordon foi a primeira de dezenas de respostas meio explicadas / documentadas que tentei, em muitos, muitos sites, que realmente funcionaram. Obrigado, Sr. Gordon. Desculpe, não tenho pontos para aumentar sua resposta.
Eu gostaria de adicionar, para outros novatos em node-route-file-splitting, que o uso da função anônima para 'índice' é o que se verá com mais frequência, portanto, usando o exemplo de John para main.js, o funcionalmente código equivalente que normalmente encontraria é:
isso é muito fácil, mas as respostas das pessoas são confusas e complexas ao mesmo tempo.
deixe-me mostrar como você pode definir uma variável global em seu expressaplicativo. Assim, você pode acessá-lo de qualquer rota, conforme necessário.
Digamos que você queira definir uma variável global de sua /rota principal
router.get('/',(req, res, next)=>{
req.app.locals.somethingNew ="Hi setting new global var";});
Portanto, você obterá req.app de todas as rotas. e então você terá que usar o localspara definir os dados globais em. como mostrado acima, você está pronto. agora
vou mostrar como usar esses dados
req.app.locals
.Respostas:
Para fazer uma variável global, basta declará-la sem a
var
palavra - chave. (De modo geral, essa não é a prática recomendada, mas em alguns casos pode ser útil - apenas tome cuidado, pois isso tornará a variável disponível em todos os lugares.)Aqui está um exemplo de visionmedia / screenshot-app
arquivo app.js :
arquivo rotas / main.js
fonte
app
associado?correct
uma.Na verdade, é muito fácil fazer isso usando os métodos "set" e "get" disponíveis em um objeto expresso.
Exemplo a seguir, digamos que você tenha uma variável chamada config com as coisas relacionadas à configuração que deseja disponibilizar em outros lugares:
Em app.js:
Em routes / index.js
fonte
req.app.get('name')
funciona como um encanto. Esta propriedade contém uma referência à instância do aplicativo Express que está usando o middleware. expressjs.com/pt-br/api.html#req.appUma maneira interessante de fazer isso é usar o
app.locals
próprio Express. Aqui está a documentação.fonte
Para declarar uma variável global, você precisa usar objeto global . Como global.yourVariableName. Mas não é um caminho verdadeiro. Para compartilhar variáveis entre módulos, tente usar o estilo de injeção como
someModule.js:
app.js
Ou você pode usar um objeto substituto para fazer isso. Como hub .
someModule.js:
app.js
fonte
Aqui estão uma explicação bem, em suma:
http://www.hacksparrow.com/global-variables-in-node-js.html
Então, você está trabalhando com um conjunto de módulos Node, talvez uma estrutura como Express.js, e de repente sente a necessidade de tornar algumas variáveis globais. Como você torna as variáveis globais no Node.js?
O conselho mais comum para este é "declarar a variável sem a palavra-chave var" ou "adicionar a variável ao objeto global" ou "adicionar a variável ao objeto GLOBAL". Qual destes você usa?
Primeiro, vamos analisar o objeto global. Abra um terminal, inicie um Node REPL (prompt).
fonte
a maneira mais fácil é declarar uma variável global em seu app.js, desde o início:
então, em qualquer rota, você pode obtê-lo:
fonte
Esta foi uma pergunta útil, mas poderia ser ainda mais fornecendo exemplos de código reais. Mesmo o artigo vinculado não mostra realmente uma implementação. Eu, portanto, humildemente submeto:
No seu
app.js
arquivo, a parte superior do arquivo:app.js não terá nenhuma referência ao
app.get()
método. Deixe-os para serem definidos nos arquivos de rotas individuais.routes/index.js
:e, finalmente, um arquivo de rotas real
routes/main.js
:fonte
Minha maneira preferida é usar dependências circulares *, cujo nó suporta
var app = module.exports = express();
como sua primeira ordem de negóciosvar app = require('./app')
acessá-loapp.js
rotas / index.js
fonte
Como outros já compartilharam,
app.set('config', config)
é ótimo para isso. Eu só queria acrescentar algo que não vi nas respostas existentes que é muito importante. Uma instância do Node.js é compartilhada entre todas as solicitações, portanto, embora possa ser muito prático compartilhar algunsconfig
ourouter
objetos globalmente, o armazenamento de dados de tempo de execução globalmente estará disponível nas solicitações e usuários . Considere este exemplo muito simples:Se você visitar
/bar
e outro pedido/foo
aparecer, sua mensagem será "Bem-vindo ao foo!". Este é um exemplo bobo, mas mostra o que quero dizer.Existem alguns pontos interessantes sobre isso em Por que diferentes sessões de node.js compartilham variáveis? .
fonte
Resolvi o mesmo problema, mas tive que escrever mais código. Criei um
server.js
arquivo, que usa expresso para cadastrar rotas. Ele expõe uma função,,register
que pode ser usada por outros módulos para registrar suas próprias rotas. Ele também expõe uma funçãostartServer
, para começar a escutar uma portaEm outro módulo, use este arquivo para criar uma rota.
No arquivo principal, inicialize ambos.
fonte
A resposta de John Gordon foi a primeira de dezenas de respostas meio explicadas / documentadas que tentei, em muitos, muitos sites, que realmente funcionaram. Obrigado, Sr. Gordon. Desculpe, não tenho pontos para aumentar sua resposta.
Eu gostaria de adicionar, para outros novatos em node-route-file-splitting, que o uso da função anônima para 'índice' é o que se verá com mais frequência, portanto, usando o exemplo de John para main.js, o funcionalmente código equivalente que normalmente encontraria é:
fonte
Eu usei app.all
No meu caso, estou usando confit para gerenciamento de configuração,
Nas rotas, você simplesmente faz
req.app.get('config').get('cookie');
fonte
isso é muito fácil, mas as respostas das pessoas são confusas e complexas ao mesmo tempo.
deixe-me mostrar como você pode definir uma variável global em seu
express
aplicativo. Assim, você pode acessá-lo de qualquer rota, conforme necessário.Digamos que você queira definir uma variável global de sua
/
rota principalPortanto, você obterá req.app de todas as rotas. e então você terá que usar o
locals
para definir os dados globais em. como mostrado acima, você está pronto. agora vou mostrar como usar esses dadosComo acima, da
register
rota que você está acessando, os dados foram configurados anteriormente.É assim que você pode fazer isso funcionar!
fonte