[javascript] node.js의 module.exports 및 내보내기

Node.js 모듈에서 다음 계약을 찾았습니다.

module.exports = exports = nano = function database_module(cfg) {...}

내가 무슨 일을 사이에 다른 궁금 module.exports하고 exports왜 모두 여기에 사용됩니다.



답변

설정 module.exports하면 database_module함수를 함수처럼 호출 할 수 있습니다 required. 간단히 설정 exports하면 노드가 객체 module.exports참조를 내보내므로 함수를 내보낼 수 없습니다 . 다음 코드는 사용자가 함수를 호출하도록 허용하지 않습니다.

module.js

다음은 작동하지 않습니다.

exports = nano = function database_module(cfg) {return;}

module.exports설정 하면 다음과 같이 작동합니다 .

module.exports = exports = nano = function database_module(cfg) {return;}

콘솔

var func = require('./module.js');
// the following line will **work** with module.exports
func();

기본적으로 node.jsexports현재 참조 하는 객체를 내 보내지 않지만 exports원래 참조 하는 속성을 내 보냅니다 . Node.js 는 객체 module.exports참조를 내보내 지만 함수처럼 호출 할 수 있습니다.


두 번째로 중요한 이유

그들은 둘을 설정 module.exports하고 exports확인하기 위해 exports사전에 수출 객체를 참조하지 않습니다. 둘 다 설정 exports하면 단축형으로 사용 하고 나중에 도로에서 잠재적 인 버그를 피할 수 있습니다.

exports.prop = true 대신에 사용 module.exports.prop = true하면 문자 를 저장하고 혼동을 피할 수 있습니다.


답변

질문이 오래 전에 받아 들여졌지만, 나는 단지 2 센트를 공유하고 싶습니다.

파일의 맨 처음에는 설명을 위해 다음과 같은 것이 있다고 상상할 수 있습니다.

var module = new Module(...);
var exports = module.exports;

여기에 이미지 설명을 입력하십시오

따라서 다른 곳에서 모듈을 요구하면 모듈에서 module.exportsNOT exports을 반환 하고 NOT 을 기억 하십시오.

따라서 다음과 같은 작업을 수행하면

exports.a = function() {
    console.log("a");
}
exports.b = function() {
    console.log("b");
}

2 개의 함수 a와 포인트 b가있는 객체에 추가 module.exports하므로 typeof반환 결과는 다음과 object같습니다.{ a: [Function], b: [Function] }

물론 module.exports이것은이 예제 대신을 사용하는 경우와 동일한 결과 입니다 exports.

이것은 module.exports내 보낸 값의 컨테이너처럼 행동 하기 를 원하는 경우 입니다. 반면, 생성자 함수 만 내보내려면 module.exportsor exports; 에 대해 알아야 module.exports할 것이 있습니다 export.

module.exports = function Something() {
    console.log('bla bla');
}

이제 typeof반환 결과는 'function'당신이 그것을 요구하고 즉시 호출 할 수 있습니다 :

var x = require('./file1.js')();반환 결과를 함수로 덮어 쓰기 때문입니다.

그러나 사용 exports하면 다음과 같은 것을 사용할 수 없습니다.

exports = function Something() {
    console.log('bla bla');
}
var x = require('./file1.js')(); //Error: require is not a function

와 때문에 exports, 상기 기준을 가리 키지 않는 개체에 이상 module.exports점 때문에 관계가없는 exportsmodule.exports이상. 이 경우 module.exports여전히 {}반환 될 빈 객체 를 가리 킵니다 .

다른 주제의 답변도 도움이 될 것입니다.
Javascript가 참조로 전달됩니까?


답변

기본적으로 답은 모듈이 require명령문을 통해 필요할 때 실제로 일어나는 일에 있습니다. 모듈이 처음 필요한 것으로 가정합니다.

예를 들면 다음과 같습니다.

var x = require('file1.js');

file1.js의 내용 :

module.exports = '123';

위의 문장이 실행되면 Module객체가 생성됩니다. 생성자 함수는 다음과 같습니다.

function Module(id, parent) {
    this.id = id;
    this.exports = {};
    this.parent = parent;
    if (parent && parent.children) {
        parent.children.push(this);
    }

    this.filename = null;
    this.loaded = false;
    this.children = [];
}

보시다시피 각 모듈 객체에는 name 속성이 exports있습니다. 이것은 결국의 일부로 반환되는 것입니다 require.

다음 단계는 file1.js의 내용을 아래와 같이 익명 함수로 감싸는 것입니다.

(function (exports, require, module, __filename, __dirname) {
    //contents from file1.js
    module.exports = '123;
});

그리고이 익명 함수는 다음과 같은 방식으로 호출됩니다. module여기서는 Module이전에 생성 된 개체를 나타냅니다 .

(function (exports, require, module, __filename, __dirname) {
    //contents from file1.js
    module.exports = '123;
}) (module.exports,require, module, "path_to_file1.js","directory of the file1.js");

함수 내부에서 볼 수 있듯이 exports형식 인수는을 참조합니다 module.exports. 본질적으로 그것은 모듈 프로그래머에게 제공되는 편의성입니다.

그러나 이러한 편의는 신중하게 수행해야합니다. 어쨌든 내보내기에 새 객체를 할당하려고하면이 방법으로 수행해야합니다.

exports = module.exports = {};

우리가 방법 다음을 수행하면 잘못된 방법을 , module.exports여전히 모듈 인스턴스의 일부로 생성 된 객체를 가리키는 것입니다.

exports = {};

결과적으로 위의 exports 객체에 아무것도 추가해도 module.exports 객체에는 영향을 미치지 않으며 require의 일부로 아무것도 내보내거나 반환되지 않습니다.


답변

처음에 module.exports=exports, require함수는 객체가 module.exports참조하는 것을 반환합니다 .

예 를 들어 객체 에 속성추가 하면 exports.a=1module.exports 및 exports는 여전히 동일한 객체를 참조합니다. 따라서 require를 호출하고 모듈을 변수에 할당하면 변수에 속성 ​​a가 있고 그 값은 1입니다.

그러나 예를 들어, 우리 그중 하나를 재정의 하면 현재 exports=function(){}다릅니다 . exports는 새 객체를 나타내고 module.exports는 원래 객체를 나타냅니다. 그리고 파일이 필요한 경우 module.exports가 새 객체를 참조하지 않기 때문에 새 객체를 반환하지 않습니다.

나를 위해 새로운 속성을 계속 추가하거나 두 속성을 모두 새 객체로 재정의합니다. 하나만 재정의하는 것이 옳지 않습니다. 그리고 그것이 module.exports진정한 보스 라는 것을 명심 하십시오.


답변

exports그리고 module.exports다시 할당하지 않는 한 동일한 exports모듈 내에서.

그것에 대해 생각하는 가장 쉬운 방법은이 줄이 모든 모듈의 최상위에 있다고 생각하는 것입니다.

var exports = module.exports = {};

모듈 내에서을 다시 할당하면 모듈 내에서 해당 모듈을 다시 할당 exports하면 더 이상 같지 않습니다 module.exports. 따라서 함수를 내보내려면 다음을 수행해야합니다.

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

당신은 단순히 당신의 할당 한 경우 function() { ... }에을 exports, 당신은 재 할당 될 것이다 exports에 더 이상 점 module.exports.

module.exports매번 기능을 참조하지 않으려면 다음을 수행하십시오.

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

그것이 module.exports가장 왼쪽에있는 논쟁입니다.

속성을 exports다시 할당하지 않기 때문에 속성을 연결하는 것은 다릅니다. 이것이 작동하는 이유입니다

exports.foo = function() { ... }


답변

JavaScript는 참조 사본으로 객체를 전달합니다.

JavaScript에서 객체가 참조로 전달되는 방식과는 미묘한 차이가 있습니다.

exportsmodule.exports같은 객체를 모두 가리 킵니다. exports변수이며 module.exports모듈 객체의 속성입니다.

다음과 같이 씁니다.

exports = {a:1};
module.exports = {b:12};

exports그리고 module.exports지금은 다른 개체를 가리 킵니다. 내보내기를 수정해도 더 이상 module.exports가 수정되지 않습니다.

가져 오기 기능이 검사 module.exports되면{b:12}


답변

방금 테스트를했는데 nodejs의 모듈 코드 내부에서 다음과 같이 나타납니다.

var module.exports = {};
var exports = module.exports;

그래서:

1:

exports = function(){}; // this will not work! as it make the exports to some other pointer
module.exports = function(){}; // it works! cause finally nodejs make the module.exports to export.

2 :

exports.abc = function(){}; // works!
exports.efg = function(){}; // works!

3 : 그러나이 경우

module.exports = function(){}; // from now on we have to using module.exports to attach more stuff to exports.
module.exports.a = 'value a'; // works
exports.b = 'value b'; // the b will nerver be seen cause of the first line of code we have do it before (or later)