요구할 인수 전달 (모듈을로드 할 때)


113

require를 사용하여 모듈을로드 할 때 인수를 전달할 수 있습니까?

로그인 기능을 제공하는 login.js 모듈이 있습니다. 데이터베이스 연결이 필요하며 모든 모듈에서 동일한 데이터베이스 연결을 사용하고 싶습니다. 이제 데이터베이스 연결을 지정할 수있는 login.setDatabase (...) 함수를 내 보내면 제대로 작동합니다. 그러나 모듈을로드 할 때 데이터베이스 및 기타 요구 사항을 전달하고 싶습니다.

var db = ...
var login = require("./login.js")(db);

저는 NodeJS를 처음 사용하고 일반적으로 Java와 Spring Framework를 사용하여 개발하므로 생성자 주입입니다. :) 위에서 제공 한 코드와 같은 작업을 수행 할 수 있습니까?


질문에 대한 답변을 살펴 보는 것도 좋습니다 . 내 대답에서 지적했듯이 일반적인 관용구는 app객체를 필요한 모듈 에 전달하는 것 입니다.
David Weldon

이 모든 인수를 db에 전달하는 대신 단일 구현을 사용하고 필요한 경우 db.getInstance ()를 호출 할 수 있습니다 .
wulfgarpro 2015

답변:


236

이 답변 에 대한 귀하의 의견에 따라 다음 과 같이하려는 작업을 수행합니다.

module.exports = function (app, db) {
    var module = {};

    module.auth = function (req, res) {
        // This will be available 'outside'.
        // Authy stuff that can be used outside...
    };

    // Other stuff...
    module.pickle = function(cucumber, herbs, vinegar) {
        // This will be available 'outside'.
        // Pickling stuff...
    };

    function jarThemPickles(pickle, jar) {
        // This will be NOT available 'outside'.
        // Pickling stuff...

        return pickleJar;
    };

    return module;
};

나는 거의 모든 모듈을 그렇게 구성합니다. 나를 위해 잘 작동하는 것 같습니다.


는 IS app인수가 필요하거나 나는 그것을 ommit 수 있습니까? 내 모듈은이 앱 인수를 명시 적으로 사용하지 않지만 node.js에서 내부적으로 필요한지 여부는 알 수 없습니다. 괜찮다면 내 모듈 선언은 다음과 같습니다.module.exports = function (db) {
Ulysses Alves

이는 Express 앱에만 해당되므로 꼭 필요하지 않습니다.
floatingLomas

@floatingLomas 파이썬의 직렬화 메커니즘은 pickle이라고합니다 : stackoverflow.com/questions/11218477/…
SadSeven

1
그렇다면 모듈을 여러 번 참조하면 어떻게 될까요? 첫 번째 require(mymodule)(myargs)는 작업 할 모듈을 제공합니다. 그러나 다른 모듈에서 다른 곳에서 참조하면 ?? 기본 시스템에서는 캐시가 관련된 것처럼 보이지만이 시스템에서는 캐시가에 대한 후속 호출에서 베어 생성기 메서드를 반환하고 require()args를 전달 require()(someargs)하면 다른 모듈을 다시 얻을 수 있습니다. 무언가
Tom H

2
@TomH이 경우 캐시를 원할 것입니다. 이를 위해서는 var module;exports 함수 외부에 있어야 하며,에 들어 오자마자 module이미 정의 되어 있는지 확인하고 , 정의되어 있다면 반환 (아니면 초기화)하면됩니다. 말이 돼?
floatingLomas

37

이것이 사람들에게 여전히 유용할지는 모르겠지만 ES6를 사용하면 깨끗하고 유용하다고 생각하는 방법이 있습니다.

class MyClass { 
  constructor ( arg1, arg2, arg3 )
  myFunction1 () {...}
  myFunction2 () {...}
  myFunction3 () {...}
}

module.exports = ( arg1, arg2, arg3 ) => { return new MyClass( arg1,arg2,arg3 ) }

그런 다음 예상되는 행동을 얻습니다.

var MyClass = require('/MyClass.js')( arg1, arg2, arg3 )

32

예. 당신의에서 login모듈, 단지 소요 하나의 함수 수출 db의 인수로합니다. 예를 들면 :

module.exports = function(db) {
  ...
};

1
나는 이것을 시도했다. login.js에서는 module.exports = function(app,db) { ... } module.exports.auth = function(req,res) { ... authentication stuff } "익명"함수를 호출하고 appdb변수를 설정 하지만이 작업을 수행하면 내 응용 프로그램이 auth함수를 찾지 못합니다 . 내가 뭘 잘못하고 있죠? 익명 함수를 제거하면 함수에 auth다시 액세스 할 수 있습니다.
Andreas Selenwall

자바 스크립트의 모든 것과 마찬가지로 exports객체입니다. 속성을 할당하거나 (여러 내보내기) 값에 할당 할 수 있습니다. 함수에 내보내기를 할당 한 것처럼 들리지만 내보내기에 할당 한 함수의 속성으로 인증을 할당했습니다. 따라서 var auth = require("./login.js").auth의도 한 바가 아닐 수도있는 작업을 수행해야합니다 . 원래 질문의 패턴을 사용하려면 단일 내보내기 값을 고수하는 것이 가장 좋습니다. 그래도 이해가되지 않는다면 요점을 게시하는 것이 좋습니다.
David Weldon

1
이것을 다시 읽은 후에 authexports객체 의 속성으로 할당 한 다음 나중에 exports함수에 할당 한 모듈 (따라서 이전 할당을 재정의 함) 에서 지정한 것처럼 들립니다 . 할당 순서를 반대로하면 auth예상대로 함수 에 액세스 할 수 있어야합니다 . 다시 말하지만 실제로 코드를 보지 않고는 말하기가 어렵습니다.
David Weldon

1
도와 주셔서 정말로 고맙습니다. 내가 몰랐던 것은 require ( 'login'). auth로 정확히 당신이 목표로했던 것입니다. var login = require('login')와 에는 차이가 없었지만 var login = require('login')(app)큰 차이가 있지만 반환 된 익명 함수에는 마법이 없으며 다른 함수 / 객체 일뿐입니다. 를 갖는 대신 module.exports.authanomymous 함수는 이제 auth 함수를 반환합니다 return { auth: authFunction, login: loginFunction}. 이제 작동합니다. 감사.
Andreas Selenwall 2010 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.