node.js의 module.exports 및 내보내기


725

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

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

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




6
'후손을 위해'링크 업데이트 : nodejs.org/docs/latest/api/modules.html#modules_module_exports
Zeke

8
참조에 관한 것입니다. 내보내기는 module.exports를 가리키는 로컬 변수 객체와 같습니다. 내보내기 값을 덮어 쓰면 module.exports에 대한 참조가 손실되고 module.exports는 공용 인터페이스로 노출됩니다.
Gabriel Llamas

14
: 빠른 요약 모두 exportsmodule.exports같은 개체를 가리킨하면 않는 한 재 할당 하나. 그리고 결국 module.exports반환됩니다. 따라서 exports함수에 다시 할당 하면 함수가 반환되지 않으므로 함수를 기대하지 마십시오. 그러나 이와 같은 함수를 할당하면 exports.func = function...결과물에 함수를 가진 func 속성이 값으로 표시됩니다. 을 ( exports를) 가리키는 객체에 속성을 추가했기 때문에 ..
Muhammad Umer

답변:


426

설정 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하면 문자 를 저장하고 혼동을 피할 수 있습니다.


8
@ajostergaard : OP의 예제를 가져온 라이브러리 의 이름 일뿐 입니다. 이 모듈에서는 작성자가 nano.version = '3.3'대신 을 쓰는 대신 module.exports.version = '3.3'좀 더 명확하게 읽을 수 있습니다. ( nano이것은 로컬 변수이며 모듈 내보내기가 설정되기 전에 약간 선언되었습니다 .)
josh3736

3
@lime-감사합니다-그것이 중요하지 않다면 모든 것을 완전히 잘못 이해했기 때문에 크게 관련이 없어서 기쁩니다. :-| :)
ostergaard

라임이, 이것은 꽤 오래된 답변이지만 당신이 무언가를 분명히 할 수 있기를 바랍니다. 설정 module.exports했지만 하지 않은 exports 경우 코드가 계속 작동합니까? 도움을 주셔서 감사합니다!
Asad Saeeduddin

1
@Asad 예 설정 한 경우 기능이 제대로 내보내집니다.module.exports
Lime

@Liam 귀중한 답변에 감사드립니다. 몇 가지 추가 쿼리-server.js 시작시 module.exports 및 exports의 값은 무엇입니까? .exports가 null이고 내보내기가 빈 객체로 설정되어 있습니까? 이 레거시 또는 내보내기 및 module.exports를 두 개의 다른 객체로 지정하는 유효한 사용 사례가 있습니까?
Sushil

504

질문이 오래 전에 받아 들여졌지만, 나는 단지 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가 참조로 전달됩니까?


2
멋진 설명하지만, 난 여전히 당신이 완전히 생략 할 수있는 방법을 이해하지 못하는 module.exports이 예를 들어, 모듈에서 npm패키지 github.com/tj/consolidate.js/blob/master/lib/consolidate.js을
CodyBugstein

4
@Imray 설명은 여기에 있습니다 : JavaScript는 참조로 전달됩니까? exports.a = function(){}; works, exports = function(){} doesn't work
cirpo

29
oooo 마지막 으로이 대답은 그것을 설명합니다. 기본적으로 내보내기는 속성을 추가 할 수있는 객체를 의미하지만 기능에 다시 할당 하면 더 이상 해당 속성을 원래 객체에 연결하지 않습니다. 이제 export.는 module.exports가 여전히 해당 객체를 가리키는 동안 반환 된 기능이므로 함수를 참조합니다. 수출이 기본적으로 가비지 수집되었다고 말할 수 있습니다.
Muhammad Umer 2016 년

5
그렇다면 사용의 요점은 무엇 exports입니까? module.exports변수 재 할당 인 경우 에만 항상 사용하지 않는 이유는 무엇 입니까? 혼란스러워 보인다.
jedd.ahyoung

1
@ jedd.ahyoung이 쓰기에 덜 복잡 exports.something대신module.exports.something
Srle

209

기본적으로 답은 모듈이 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의 일부로 아무것도 내보내거나 반환되지 않습니다.


8
나를 잃어 exports = module.exports = {};
자이언트 엘크

2
이것이 최선의 대답이어야한다고 생각합니다. 왜 func()@William의 대답에서 실패 하는지 설명합니다 !
turtledove

2
exports = module.exports = app;코드의 마지막 줄에 추가 할 이점이 없습니다 . module.exports는 수출 되는 것처럼 보이고 우리는 결코 exports코드의 마지막 줄에 있기 때문에 결코 사용하지 않을 것 입니다. 그럼, 왜 우리는 단지 추가하지 마십시오module.exports = app;
lvarayut

79

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

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

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

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


1
예, 이것은 실제로 실제 답변입니다. 간결하고 명확합니다. 다른 사람들은 옳지 만 멋진 용어로 가득 차있을 수 있으며이 질문에 대한 답변에 정확하게 초점을 맞추지 않습니다.
코아

이것은 가장 명확한 대답입니다! 당신이 그것을 북마크하고 싶을 경우에, 이것은 정확한 링크입니다 : stackoverflow.com/questions/7137397/…
lambdarookie

56

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() { ... }

9
이것은 모든 답을 이해하는 가장 쉬운 방법이었습니다!
Adarsh ​​Konchady

2
멋지고 간단
피 보노

1
이 기능을 이해하는 간단하고 쉬운 방법입니다.
FilipeCanatto

27

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

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

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

다음과 같이 씁니다.

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

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

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


6
최고의 답변 imho!
Mr. AJ

1
"자바 스크립트 참조로 전달"– 번호
xehpuk

13

방금 테스트를했는데 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)

라이먼, 그래서 module.exports그 노드의 소등하지만 어느 시점에서 모든를 추가해야합니다 정렬 '실제 거래'입니다 당신 exports에게 module.exports당신이 사용하지 않는 exports.namespace경우에 같은 것 같다 (경우 2 위), 노드는 실행 한 extends(module.exports, exports);모든 '네임 스페이스'의 추가 exports받는 module.exports객체? 다른 말로, 당신이 사용하고 있다면 exports아마도 당신이 그것에 속성을 설정하고 싶습니까?
Cody

11

다음은 Manning 서적의 action book에 있는 node.js의 노드 모듈에 대한 좋은 설명입니다 . 궁극적으로 응용 프로그램에서 내보내는 것은 module.exports입니다. 내보내기 는 단순히 module.exports에 대한 전역 참조로 설정 되며 처음에는 속성을 추가 할 수있는 빈 객체로 정의됩니다. 그래서 exports.myFunc 단지 속기 module.exports.myFunc . 결과적으로 exports 가 다른 것으로 설정 되면 module.exportsexports 사이 의 참조끊어집니다 . module.exports 때문에



실제로 내보내는 것이므로 내보내기 가 더 이상 예상대로 작동하지 않습니다 . 더 이상 모듈 .exports를 참조하지 않습니다 . 해당 링크를 유지하려면 다음과 같이 module.exports가 내보내기를 다시 참조 하도록 할 수 있습니다 .

module.exports = exports = db;

8

나는 몇 가지 테스트를 겪었으며 이것이 주제에 약간의 빛을 비출 수 있다고 생각합니다 ...

app.js:

var ...
  , routes = require('./routes')
  ...;
...
console.log('@routes', routes);
...

버전 /routes/index.js:

exports = function fn(){}; // outputs "@routes {}"

exports.fn = function fn(){};  // outputs "@routes { fn: [Function: fn] }"

module.exports = function fn(){};  // outputs "@routes function fn(){}"

module.exports.fn = function fn(){};  // outputs "@routes { fn: [Function: fn] }"

새 파일도 추가했습니다.

./routes/index.js:

module.exports = require('./not-index.js');
module.exports = require('./user.js');

./routes/not-index.js:

exports = function fn(){};

./routes/user.js:

exports = function user(){};

"@routes {}"출력을 얻습니다


./routes/index.js:

module.exports.fn = require('./not-index.js');
module.exports.user = require('./user.js');

./routes/not-index.js:

exports = function fn(){};

./routes/user.js:

exports = function user(){};

출력은 "@routes {fn : {}, user : {}}"입니다.


./routes/index.js:

module.exports.fn = require('./not-index.js');
module.exports.user = require('./user.js');

./routes/not-index.js:

exports.fn = function fn(){};

./routes/user.js:

exports.user = function user(){};

"@routes {user : [Function : user]}" 출력을 얻습니다.로 변경 user.js하면 { ThisLoadedLast: [Function: ThisLoadedLast] }"@routes {ThisLoadedLast : [Function : ThisLoadedLast]}"출력이 표시됩니다.


그러나 우리가 수정하면 ./routes/index.js...

./routes/index.js:

module.exports.fn = require('./not-index.js');
module.exports.ThisLoadedLast = require('./user.js');

./routes/not-index.js:

exports.fn = function fn(){};

./routes/user.js:

exports.ThisLoadedLast = function ThisLoadedLast(){};

... "@routes {fn : {fn : [함수 : fn]}, ThisLoadedLast : {ThisLoadedLast : [함수 : ThisLoadedLast]}}"

따라서 항상 module.exports모듈 정의에 사용하는 것이 좋습니다 .

Node에서 내부적으로 무슨 일이 일어나고 있는지 완전히 이해하지 못하지만 도움이 될 것으로 확신 할 수 있다면 의견을 말하십시오.

-행복한 코딩


나는 그들이 불필요하게 복잡하고 혼란 스럽다고 생각합니다. 투명하고 직관적이어야합니다.
ngungo

동의한다. 네임 스페이스는 상황에 따라 유용하지만 일반적으로 어떤 것도 만들거나 깨뜨리지 않습니다.
Cody

4

이것은 Eloquent JavaScriptrequire() 에서 발췌 한 가장 간단한 형태로 작동 하는 방법을 보여줍니다.

문제 모듈이 함수와 같은 내보내기 개체 이외의 값을 직접 내보내는 것은 불가능합니다. 예를 들어, 모듈은 정의한 객체 유형의 생성자 만 내보내려고 할 수 있습니다. require는 항상 exports생성 된 객체를 내 보낸 값으로 사용하기 때문에 지금은 그렇게 할 수 없습니다 .

해결 방법module 속성이있는 객체 인 다른 변수를 모듈에 제공하십시오 exports. 이 속성은 초기에 require에 의해 생성 된 빈 객체를 가리 키지 만 다른 것을 내보내기 위해 다른 값으로 덮어 쓸 수 있습니다.

function require(name) {
  if (name in require.cache)
    return require.cache[name];
  var code = new Function("exports, module", readFile(name));
  var exports = {}, module = {exports: exports};
  code(exports, module);
  require.cache[name] = module.exports;
  return module.exports;
}
require.cache = Object.create(null);

Node에서 이것을 다시 만들고 내가 얻을 때까지 몇 가지를 테스트해야했습니다. 기본적으로 모듈에 대해 작성된 내부 함수는 내보내기 개체를 반환하지 않습니다. 따라서 "exports"객체는 실제로 모듈에 재 할당되지 않습니다. 예를 들어 exports = "이것은 이제 문자열입니다"를 쓰려고하는 경우입니다. 개체는 참조로만 존재합니다. 이것은 내가 지금까지 제대로 선택했다고 생각하지 않는 행동입니다.
danielgormly 2012

4

결과는 다음과 같습니다

console.log("module:");
console.log(module);

console.log("exports:");
console.log(exports);

console.log("module.exports:");
console.log(module.exports);

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

또한:

if(module.exports === exports){
    console.log("YES");
}else{
    console.log("NO");
}

//YES

참고 : CommonJS 스펙에서는 내보내기 변수를 사용하여 공용 멤버를 노출 할 수 있습니다. 따라서 명명 된 내보내기 패턴은 CommonJS 스펙과 실제로 호환되는 유일한 패턴입니다. module.exports의 사용은 광범위한 모듈 정의 패턴을 지원하기 위해 Node.js에서 제공하는 확장입니다.


4
var a = {},md={};

// 먼저 내보내기와 module.exports는 동일한 빈 객체를 가리 킵니다.

exp = a;//exports =a;
md.exp = a;//module.exports = a;

exp.attr = "change";

console.log(md.exp);//{attr:"change"}

// exp 대신 다른 객체를 가리키면 다른 객체의 속성입니다. md.exp는 비어 있습니다 Object {}

var a ={},md={};
exp =a;
md.exp =a;

exp = function(){ console.log('Do nothing...'); };

console.log(md.exp); //{}

4

로부터 문서

내보내기 변수는 모듈의 파일 레벨 범위 내에서 사용 가능하며 모듈을 평가하기 전에 module.exports 값이 지정됩니다.

바로 가기를 허용하므로 module.exports.f = ...를 exports.f = ...로 더 간결하게 작성할 수 있습니다. 그러나 변수와 마찬가지로 새 값이 내보내기에 할당되면 다음과 같습니다. 더 이상 module.exports에 바인딩되지 않습니다.

module.exports를 가리키는 변수 일뿐입니다.


4

이 링크가 위의 질문에 대답하는 데 유용하다는 것을 알았습니다.

http://timnew.me/blog/2012/04/20/exports-vs-module-exports-in-node-js/

다른 게시물에 추가하려면 노드의 모듈 시스템은

var exports = module.exports 

코드를 실행하기 전에 따라서 export = foo를 내보내려면 module.exports = exports = foo을 수행하고 싶지만 exports.foo = foo 사용하면 좋습니다.


자식 링크가 끊어짐
Jesse Hattabaugh

링크가 수정되었습니다.
Paweł Gościcki

3

"모듈 내보내기의 루트를 생성자 등의 함수로 만들거나 한 번에 하나의 속성을 작성하는 대신 하나의 할당으로 전체 객체를 내보내려면 해당 속성을 module.exports 대신에 할당하십시오. 수출. " - http://nodejs.org/api/modules.html


3

module.exportsexports모듈 전과 동일한 개체에 두 점을 평가한다.

module.exports 모듈이 다른 모듈 using require문 에서 사용될 때 객체에 추가 한 모든 속성을 사용할 수 있습니다 . exports같은 것을 위해 사용할 수있는 지름길입니다. 예를 들어 :

module.exports.add = (a, b) => a+b

다음과 같이 작성합니다.

exports.add = (a, b) => a+b

exports변수에 새로운 값을 할당하지 않는 한 괜찮습니다 . 이런 식으로하면 :

exports = (a, b) => a+b 

새 값을 할당 exports하면 더 이상 내 보낸 객체에 대한 참조가 없으므로 모듈에 로컬로 유지됩니다.

새 값을 할당하려는 경우 module.exports사용 가능한 초기 오브젝트에 새 특성을 추가하지 않고 아래에 제공된대로 수행하는 것이 좋습니다.

module.exports = exports = (a, b) => a+b

Node.js 웹 사이트에 이것에 대한 아주 좋은 설명이 있습니다.


2

1. exports-> singleton 유틸리티로 사용
2. module- exports-> service, model 등과 같은 논리적 객체로 사용


2

두 가지 방법으로 하나의 모듈을 만들어 봅시다 :

일방 통행

var aa = {
    a: () => {return 'a'},
    b: () => {return 'b'}
}

module.exports = aa;

두 번째 방법

exports.a = () => {return 'a';}
exports.b = () => {return 'b';}

이것이 require () 가 모듈을 통합 하는 방법 입니다.

첫 번째 방법 :

function require(){
    module.exports = {};
    var exports = module.exports;

    var aa = {
        a: () => {return 'a'},
        b: () => {return 'b'}
    }
    module.exports = aa;

    return module.exports;
}

두 번째 방법

function require(){
    module.exports = {};
    var exports = module.exports;

    exports.a = () => {return 'a';}
    exports.b = () => {return 'b';}

    return module.exports;
}

2

왜 둘 다 여기에 사용됩니까?

나는 그들이 단지 명확하게 할 생각이 module.exports, exports그리고 nano동일한 기능을 가리키고 - 당신은 파일 내의 함수를 호출하거나 변수를 사용할 수 있도록. nano함수의 기능에 대한 컨텍스트를 제공합니다.

exports수출되지 않습니다 ( module.exports의지 만 ). 왜 덮어 쓰지 않아도됩니까?

자세한 상충 관계 는 파일 내에서 exports대신 사용 하는 등 향후 버그의 위험을 제한 module.exports합니다. 또한 제공하고 설명 한다는 module.exportsexports같은 값을 가리키는 사실에있다.


module.exports vs exports

재할 당하지 module.exports않거나 exports(그리고 둘 다 참조하는 객체에 값을 추가 하지 않는 한 ) 문제 exports가 없으며보다 간결하게 사용할 수 있습니다.

비 객체에 할당 할 때 의도적으로 module.exports특정 기능 (예 : 기능)이 되기를 원하지 않는 한 혼란을 줄 수있는 다른 장소를 가리키고 있습니다 .

설정 exports이 아닌 객체로하면 설정해야 겠지만 많은 이해가되지 않습니다 module.exports = exports다른 파일에서 사용할 수 있도록 말을.

let module = { exports: {} };
let exports = module.exports;

exports.msg = 'hi';
console.log(module.exports === exports); // true

exports = 'yo';
console.log(module.exports === exports); // false

exports = module.exports;
console.log(module.exports === exports); // true

module.exports = 'hello';
console.log(module.exports === exports); // false

module.exports = exports;
console.log(module.exports === exports); // true

module.exports기능에 할당 합니까?

더 간결한! 두 번째 예제가 얼마나 짧은 지 비교하십시오.

helloWorld1.js : module.exports.hello = () => console.log('hello world');

app1.js : let sayHello = require('./helloWorld1'); sayHello.hello; // hello world

helloWorld2.js : module.exports = () => console.log('hello world');

app2.js : let sayHello = require('./helloWorld2'); sayHello; // hello world


2

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

작성하는 각 파일은 모듈입니다. 모듈은 객체입니다. exports : {}기본적으로 비어있는 객체 라는 속성이 있습니다 .

당신은 같은 객체 기능 / 미들웨어를 만들고이 빈 수출에 추가 할 수있는 exports.findById() => { ... } 다음 require앱에서 사용 어디서나 ...

controllers / user.js

exports.findById = () => {
    //  do something
}

에 필요 routes.js 사용에 :

const {findyId} = './controllers/user'

2

차이점을 이해하려면 먼저 런타임 동안 Node.js가 모든 모듈에 대해 수행하는 작업을 이해해야합니다. Node.js는 모든 모듈에 대한 래퍼 함수를 ​​만듭니다.

 (function(exports, require, module, __filename, __dirname) {

 })()

첫 번째 매개 변수 exports는 빈 개체이고 세 번째 매개 변수 module는 많은 속성을 가진 개체이며 속성 중 하나의 이름은 exports입니다. 이것이 exports유래와 module.exports유래입니다. 전자는 가변 객체이고 후자는 module객체 의 속성입니다 .

모듈 내에서 Node.js는 시작 부분에서 자동으로이 작업을 수행 module.exports = exports하고 궁극적으로를 반환합니다 module.exports.

따라서 값을에 다시 할당하면에 exports아무런 영향을 미치지 않습니다 module.exports. (단순히 exports다른 새 객체를 가리 키지 만 module.exports여전히 오래된 객체를 보유하고 있기 때문에 exports)

let exports = {};
const module = {};
module.exports = exports;

exports = { a: 1 }
console.log(module.exports) // {}

그러나의 속성을 업데이트하면에 exports영향을 미칩니다 module.exports. 둘 다 같은 객체를 가리 키기 때문입니다.

let exports = {};
const module = {};
module.exports = exports;

exports.a = 1;
module.exports.b = 2;
console.log(module.exports) // { a: 1, b: 2 }

또한 다른 값을에 다시 할당하면 업데이트에 module.exports의미가없는 것으로 보입니다 exports. 다른 객체를 가리 키 exports므로 모든 업데이트 가 무시 module.exports됩니다.

let exports = {};
const module = {};
module.exports = exports;

exports.a = 1;
module.exports = {
  hello: () => console.log('hello')
}
console.log(module.exports) // { hello: () => console.log('hello')}

0

node js의 module.js 파일은 node.s 파일을 실행할 때마다 다음과 같이 js 파일 내용을 래핑합니다.

'(function (exports, require, module, __filename, __dirname) {',+
     //your js file content
 '\n});'

ur js 소스 코드 안에 래핑되어 있기 때문에 내보내기, 요구 사항, 모듈 등에 액세스 할 수 있습니다.이 방법은 js 파일에 다른 기능을 작성하는 다른 방법이 없기 때문에 사용됩니다.

그런 다음 노드는 C ++을 사용하여이 랩핑 된 함수를 실행합니다. 그 순간이 함수로 전달 된 내보내기 객체가 채워집니다.

이 함수 매개 변수 내보내기 및 모듈 내부를 볼 수 있습니다. 실제로 exports는 모듈 생성자 함수의 공용 멤버입니다.

다음 코드를보십시오

이 코드를 b.js로 복사

console.log("module is "+Object.prototype.toString.call(module));
console.log("object.keys "+Object.keys(module));
console.log(module.exports);
console.log(exports === module.exports);
console.log("exports is "+Object.prototype.toString.call(exports));
console.log('----------------------------------------------');
var foo = require('a.js');
console.log("object.keys of foo: "+Object.keys(foo));
console.log('name is '+ foo);
foo();

이 코드를 a.js에 복사

exports.name = 'hello';
module.exports.name = 'hi';
module.exports.age = 23;
module.exports = function(){console.log('function to module exports')};
//exports = function(){console.log('function to export');}

이제 노드를 사용하여 실행

이것은 출력입니다

module is [object Object]
object.keys id,exports,parent,filename,loaded,children,paths
{}
true

내보내기는 [객체 객체]입니다.

foo의 object.keys : name은 function () {console.log ( 'function to module exports')} function to module exports입니다.

이제 a.js에서 주석 처리 된 행을 제거하고 해당 행 위에있는 행을 주석 처리하고 b.js의 마지막 행을 제거하고 실행하십시오.

자바 스크립트 세계에서는 매개 변수로 전달 된 객체를 다시 할당 할 수 없지만 해당 함수의 객체가 다른 함수의 매개 변수로 설정되면 함수의 공개 멤버를 변경할 수 있습니다

기억해

require keyword를 사용할 때 함수를 얻으려는 경우에만 module.exports를 사용하십시오. 위 예제에서 우리는 var foo = require (a.js); foo를 함수로 호출 할 수 있습니다.

이것은 노드 문서가 설명하는 방법입니다. "내보내기 객체는 모듈 시스템에 의해 생성됩니다. 때로는 받아 들일 수없는 경우가 많습니다. 많은 사람들은 모듈이 어떤 클래스의 인스턴스가되기를 원합니다. 이렇게하려면 원하는 내보내기 객체를 module.exports에 할당하십시오."


0
  1. 모두 module.exportsexports같은 가리킨 function database_module(cfg) {...}.

    1| var a, b;
    2| a = b = function() { console.log("Old"); };
    3|     b = function() { console.log("New"); };
    4|
    5| a(); // "Old"
    6| b(); // "New"

    b3 행에서으로 변경할 수 있으며 a출력이 반전됩니다. 결론은 다음과 같습니다.

    ab독립적이다.

  2. 따라서 다음 module.exports = exports = nano = function database_module(cfg) {...}과 같습니다.

    var f = function database_module(cfg) {...};
    module.exports = f;
    exports = f;

    위의가 module.js필요하다고 가정합니다 foo.js. 장점은 module.exports = exports = nano = function database_module(cfg) {...}다음과 같습니다.

    • 에서 foo.js, 이후는 module.exports것입니다 require('./module.js'):

      var output = require('./modules.js')();
    • 에서 moduls.js: exports대신 사용할 수 있습니다 module.exports.

그래서, 당신은 두 경우 드리겠습니다 exportsmodule.exports같은 일을 가리키는.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.