É possível passar argumentos ao carregar um módulo usando require?
Eu tenho o módulo, login.js, que fornece funcionalidade de login. Ele requer uma conexão de banco de dados e eu quero que a mesma conexão de banco de dados seja usada em todos os meus módulos. Agora exporto uma função login.setDatabase (...) que me permite especificar uma conexão de banco de dados e que funciona perfeitamente. Mas prefiro passar o banco de dados e quaisquer outros requisitos ao carregar o módulo.
var db = ...
var login = require("./login.js")(db);
Eu sou muito novo com NodeJS e normalmente desenvolvo usando Java e o Spring Framework, então sim ... esta é uma injeção de construtor :) É possível fazer algo como o código que forneci acima?
app
objeto para os módulos necessários.Respostas:
Com base em seus comentários nesta resposta , faço o que você está tentando fazer assim:
Eu estruturo praticamente todos os meus módulos assim. Parece funcionar bem para mim.
fonte
app
argumento é necessário ou posso omiti-lo? Meu módulo não fará uso explícito desse argumento do app, mas não sei se ele é exigido pelo node.js para alguma coisa interna. Se estiver tudo bem, minha declaração de módulo ficaria assim:module.exports = function (db) {
require(mymodule)(myargs)
forneceria um módulo para trabalhar. No entanto, se você referenciá-lo em outro lugar de outro módulo ?? no sistema básico parece haver um cache envolvido, mas neste sistema, o cache retornaria o método do gerador vazio nas chamadas subsequentes pararequire()
, e se você passasse args pararequire()(someargs)
você receberia um módulo diferente de volta ... talvez eu não esteja algovar module;
sair da função de exportação e, assim que entrar na, verificar semodule
já está definido e, em caso afirmativo, basta retorná-lo (e se não, inicializá-lo). Isso faz sentido?Não tenho certeza se isso ainda será útil para as pessoas, mas com ES6 eu tenho uma maneira de fazer isso que considero limpa e útil.
E então você obtém o comportamento esperado.
fonte
Sim. Em seu
login
módulo, apenas exporte uma única função que tenha odb
como seu argumento. Por exemplo:fonte
module.exports = function(app,db) { ... } module.exports.auth = function(req,res) { ... authentication stuff }
ele chama a função "anônima" e define as variáveisapp
edb
, mas, ao fazer isso, meu aplicativo não encontrará aauth
função. O que estou fazendo de errado? Se eu remover a função anônima, aauth
função ficará acessível novamente.exports
é um objeto. Você pode atribuir propriedades a ele (várias exportações) ou pode atribuí-lo a um valor. Parece que você atribuiu exportações a uma função, mas então atribuiu auth como uma propriedade da função que atribuiu às exportações. Portanto, você precisa fazer ovar auth = require("./login.js").auth
que pode não ser o que você pretendia. Se você quiser usar o padrão da pergunta original, provavelmente é melhor manter um único valor de exportação. Se isso ainda não fizer sentido, recomendo postar uma ideia geral para eu dar uma olhada.auth
como uma propriedade doexports
objeto e, posteriormente, no módulo que atribuiuexports
a uma função (substituindo assim a atribuição anterior). Se você inverter a ordem da atribuição, poderá acessar aauth
função conforme o esperado. Novamente, é difícil saber sem realmente ver o código.var login = require('login')
evar login = require('login')(app)
, mas há uma enorme diferença, não há mágica na função anônima retornada, é apenas outra função / objeto. Em vez de ter ummodule.exports.auth
, a função retorna anomymous agora a função de autenticação (amongs outros), ou sejareturn { auth: authFunction, login: loginFunction}
. Então agora funciona. Obrigado.