Node.js module.exports의 목적은 무엇이며 어떻게 사용합니까?


1432

Node.js module.exports의 목적은 무엇이며 어떻게 사용합니까?

나는 이것에 대한 정보를 찾을 수없는 것 같지만 소스 코드에서 종종 볼 때 Node.js의 중요한 부분 인 것처럼 보입니다.

Node.js 문서 에 따르면 :

구성 단위

현재에 대한 참조 module. 특히 module.exports 내보내기 개체와 동일합니다. 자세한 내용 src/node.js은 참조하십시오.

그러나 이것은 실제로 도움이되지 않습니다.

정확히 module.exports무엇을하며 간단한 예는 무엇입니까?

답변:


1590

module.exports실제로 require호출 결과로 반환되는 객체입니다 .

exports변수가 처음에 그 같은 객체로 설정되어 있으므로 모듈 코드 (즉, 그것이 속기 "별칭"입니다) 당신 것 같은 일반적으로 쓰기 뭔가 :

let myFunc1 = function() { ... };
let myFunc2 = function() { ... };
exports.myFunc1 = myFunc1;
exports.myFunc2 = myFunc2;

수출 (또는 "노출") 내부적으로 범위 기능을 myFunc1하고 myFunc2.

그리고 호출 코드에서 다음을 사용합니다.

const m = require('./mymodule');
m.myFunc1();

마지막 줄은 require속성에 접근 할 수있는 평범한 객체 의 결과를 보여줍니다 .

주의 : 덮어 쓰면 exports더 이상 참조하지 않습니다 module.exports. 따라서 새로운 객체 (또는 함수 참조)를 exports할당하려면 해당 새로운 객체를 할당해야합니다module.exports


exports객체에 추가 된 이름이 추가하려는 값에 대해 모듈의 내부 범위 이름과 같을 필요는 없으므로 다음을 수행 할 수 있습니다.

let myVeryLongInternalName = function() { ... };
exports.shortName = myVeryLongInternalName;
// add other objects, functions, as required

뒤에 :

const m = require('./mymodule');
m.shortName(); // invokes module.myVeryLongInternalName

119
좋은 대답은 - '노출하는'수출 '보다 용어의 더 나은 선택을했을 것이다 나에게 보인다
UpTheCreek

2
@ApopheniaOverload- "exports.func1, exports.func2 등"을 수행하여 하나의 파일에서 여러 노출 된 메소드를 가질 수 있습니다.
헬라 탄

73
필요한 모듈은 var m = require ( './ mymodule'); 점과 슬래시와 함께. 이런 식으로 Node.js는 로컬 모듈을 사용하고 있음을 알고 있습니다.
Gui Premonsa

7
require ( './ module_name') 구문을 사용해야합니다. 일부 이름을 가진 다른 node.js 모듈이있을 수 있고 자신의 모듈을 선택하는 대신 node.js와 함께 설치된 모듈을 선택합니다.
Sazid

3
@UpTheCreek은 모듈에 의해 노출 된 공개 심볼을 '내 보낸'것으로 간주하는 오랜 전통이 있으며, 이는 많은 프로그래밍 시스템과 수십 년 전으로 거슬러 올라갑니다. 이것은 노드 개발자가 발명 한 새로운 용어가 아닙니다.
Mark Reed

218

이것은 이미 답변되었지만 설명을 추가하고 싶었습니다 ...

둘 다 사용할 수 있습니다 exportsmodule.exports같은 응용 프로그램에 수입 코드를 :

var mycode = require('./path/to/mycode');

기본 사용 사례 (예 : ExpressJS 예제 코드)는 exports.js 파일에서 객체의 속성을 설정 한 다음 사용하여 가져 오는 것입니다.require()

간단한 계산 예에서 다음을 수행 할 수 있습니다.

(counter.js) :

var count = 1;

exports.increment = function() {
    count++;
};

exports.getCount = function() {
    return count;
};

... 응용 프로그램 (web.js 또는 다른 .js 파일)에서 :

var counting = require('./counter.js');

console.log(counting.getCount()); // 1
counting.increment();
console.log(counting.getCount()); // 2

간단히 말해서, 필요한 파일을 단일 객체를 반환하는 함수로 생각할 수 있으며, 속성을 설정하여 반환되는 객체에 속성 (문자열, 숫자, 배열, 함수 등)을 추가 할 수 있습니다 exports .

때로는 require()호출 에서 반환 된 객체가 속성이있는 객체가 아닌 호출 할 수있는 함수가 되기를 원할 것입니다. 이 경우에도 설정해야합니다module.exports 과 같이 .

(sayhello.js) :

module.exports = exports = function() {
    console.log("Hello World!");
};

(app.js) :

var sayHello = require('./sayhello.js');
sayHello(); // "Hello World!"

exports와 module.exports의 차이점은 이 답변에서 더 잘 설명 됩니다 .


어떻게 루트 폴더를 가지고 있지 않은 다른 폴더의 모듈이 필요합니까?
Igal

@ user301639는 상대 경로를 사용하여 파일 시스템 계층을 통과 할 수 있습니다. require당신이 실행 폴더를 기준으로 시작 node app.js한다. 나는 당신이 명확한 답을 얻기 위해 명시 적 코드 + 폴더 구조의 예제와 함께 새 질문을 게시하시기 바랍니다.
제드 왓슨

1
작동하도록 module.exports 예제를 조정해야했습니다. 파일 : var sayHello = require('./ex6_module.js'); console.log(sayHello());및 모듈 :module.exports = exports = function() { return "Hello World!"; }
Jason Lydon

1
증가 예제가 정말 좋았고 내보내기로 수행하는 작업에 과부하가 걸릴 때마다 마음을 새로 고치기 위해 이것을 사용했습니다.
munkee

module.exports = exports = function(){...}두 번째 exports는 변수 일 뿐입니 까? 다시 말해서module.exports = abc = function()
Jeb50

60

NodeJS 모듈 메커니즘은 RequireJS 와 같은 많은 다른 구현에서도 지원되는 CommonJS 모듈을 기반으로 하지만 SproutCore , CouchDB , Wakanda , OrientDB , ArangoDB , RingoJS , TeaJS , SilkJS , curl.js 또는 심지어 Adobe Photoshop ( PSLib 를 통해) ). 알려진 구현의 전체 목록은 여기에서 찾을 수 있습니다. .

모듈이 노드 특정 기능이나 모듈을 사용 exports하지 module.exports 않는 한 CommonJS 표준의 일부가 아닌 다른 구현에서 지원 하지 않는 대신 사용 하는 것이 좋습니다 .

또 다른 NodeJS 고유 기능은 exports이 스레드에서 Jed Watson이 제공 한 마지막 예에서와 같이 속성 및 메소드를 추가 하는 대신 새 오브젝트에 대한 참조를 지정할 때 입니다. CommonJS 모듈 메커니즘 의 순환 참조 지원위반 하므로이 방법을 개인적으로 권장하지 않습니다 . 그런 다음 모든 구현에서 지원되는 것은 아니며보다 보편적 인 모듈을 제공하기 위해 Jed 예제를 이런 식으로 작성해야합니다.

(sayhello.js) :

exports.run = function() {
    console.log("Hello World!");
}

(app.js) :

var sayHello = require('./sayhello');
sayHello.run(); // "Hello World!"

또는 ES6 기능 사용

(sayhello.js) :

Object.assign(exports, {
    // Put all your public API here
    sayhello() {
        console.log("Hello World!");
    }
});

(app.js) :

const { sayHello } = require('./sayhello');
sayHello(); // "Hello World!"

추신 : Appcelerator는 CommonJS 모듈도 구현하지만 순환 참조 지원은 없습니다 ( Appcelerator 및 CommonJS 모듈 (캐싱 및 순환 참조) 참조 )


35

새 객체에 대한 참조를 exports및 / 또는에 할당 할 경우주의해야 할 사항은 다음 과 modules.exports같습니다.

1. 원본에 이전에 첨부 exports되었거나 module.exports내 보낸 개체가 다른 새 개체를 참조하므로 손실되는 모든 속성 / 방법

이것은 명백하지만 기존 모듈의 시작 부분에 내 보낸 메소드를 추가하는 경우 내 보낸 내 보낸 오브젝트가 마지막에 다른 오브젝트를 참조하지 않는지 확인하십시오

exports.method1 = function () {}; // exposed to the original exported object
exports.method2 = function () {}; // exposed to the original exported object

module.exports.method3 = function () {}; // exposed with method1 & method2

var otherAPI = {
    // some properties and/or methods
}

exports = otherAPI; // replace the original API (works also with module.exports)

2. 새로운 값 중 하나를 참조 exports하거나 module.exports참조하는 경우 더 이상 동일한 객체를 참조하지 않습니다

exports = function AConstructor() {}; // override the original exported object
exports.method2 = function () {}; // exposed to the new exported object

// method added to the original exports object which not exposed any more
module.exports.method3 = function () {}; 

3. 까다로운 결과. exports와에 대한 참조를 변경하면 module.exports어떤 API가 노출되는지 말하기가 어렵습니다 ( module.exports승리 된 것처럼 보입니다 )

// override the original exported object
module.exports = function AConstructor() {};

// try to override the original exported object
// but module.exports will be exposed instead
exports = function AnotherConstructor() {}; 

29

module.exports 속성 또는 exports 객체를 사용하면 모듈이 응용 프로그램과 공유 할 항목을 선택할 수 있습니다

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

여기 에 module_export에 대한 비디오가 있습니다 .


18

프로그램 코드를 여러 파일로 나눌 때 module.exports변수 및 함수를 모듈 소비자에게 공개하는 데 사용됩니다. require()소스 파일 의 호출 module.exports은 모듈에서로드 된 해당 것으로 바뀝니다 .

모듈을 작성할 때 기억하십시오

  • 모듈로드는 캐시되며 초기 호출 만 JavaScript를 평가합니다.
  • 모듈 내에서 로컬 변수와 함수를 사용할 수 있지만 모든 것을 내보낼 필요는 없습니다.
  • module.exports개체는 exports속기 로도 사용할 수 있습니다 . 그러나 유일한 함수를 반환 할 때는 항상을 사용하십시오 module.exports.

모듈 내보내기 다이어그램

"모듈 2-쓰기 모듈" 에 따르면 .


9

참조 링크는 다음과 같습니다 :

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

함수 또는 변수와 같은 exports또는 의 속성은 module.exports외부에 노출됩니다.

더주의를 기울여야 할 것이 있습니다 : override수출 하지 마십시오 .

왜 ?

export는 module.exports의 참조 만 내보내므로 내보내기에 속성을 추가 할 수 있지만 내보내기를 재정의하면 참조 링크가 끊어집니다.

좋은 예 :

exports.name = 'william';

exports.getName = function(){
   console.log(this.name);
}

나쁜 예 :

exports = 'william';

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

다음과 같이 하나의 함수 또는 변수 만 노출하려는 경우 :

// test.js
var name = 'william';

module.exports = function(){
    console.log(name);
}   

// index.js
var test = require('./test');
test();

이 모듈은 하나의 기능 만 노출했으며 name 속성은 외부 전용입니다.


6

http, sys 등과 같은 node.js를 다운로드하고 설치할 때 node.js에 기본 또는 기존 모듈이 있습니다 .

그것들은 이미 node.js에 있기 때문에, 우리가이 모듈들을 사용하고 싶을 때는 기본적으로 import 모듈을 좋아 합니다 하지만 왜 그럴까요? 그것들은 이미 node.js에 있기 때문에. 가져 오기는 node.js에서 가져 와서 프로그램에 넣는 것과 같습니다. 그런 다음 사용합니다.

반면 수출 가 정반대 인 , 원하는 모듈을 만들고 있습니다. 모듈 addition.js를 말하고 해당 모듈을 node.js에 넣고 내 보내면됩니다.

여기에 아무것도 쓰지 않기 전에 module.exports.additionTwoexports.additionTwo 와 동일합니다 .

허, 그게 이유야 우린 좋아해

exports.additionTwo = function(x)
{return x+2;};

경로에주의하십시오

addition.js 모듈을 만들었다 고 가정 해 보겠습니다.

exports.additionTwo = function(x){
return x + 2;
};

NODE.JS 명령 프롬프트에서이를 실행할 때 :

node
var run = require('addition.js');

이것은 말하기 오류

오류 : 모듈 addition.js를 찾을 수 없습니다

우리가 경로를 언급하지 않았기 때문에 node.js 프로세스가 addition.js를 사용할 수 없기 때문입니다. 따라서 NODE_PATH를 사용하여 경로를 설정할 수 있습니다

set NODE_PATH = path/to/your/additon.js

이제 오류없이 성공적으로 실행됩니다 !!

한 가지 더, NODE_PATH를 설정하지 않고 addition.js 파일을 nodejs 명령 프롬프트로 다시 실행할 수도 있습니다.

node
var run = require('./addition.js');

현재 디렉토리에 있다고 말함으로써 여기에 경로를 제공하고 있으므로 ./성공적으로 실행해야합니다.


1
수출입니까?
rudrasiva86

도움을 주셔서 감사합니다 :)
JumpMan

3

모듈은 관련 코드를 단일 코드 단위로 캡슐화합니다. 모듈을 만들 때 모든 관련 기능을 파일로 이동하는 것으로 해석 할 수 있습니다.

두 개의 함수를 포함하는 Hello.js 파일이 있다고 가정하십시오.

sayHelloInEnglish = function() {
  return "Hello";
};
sayHelloInSpanish = function() {
  return "Hola";
};

코드의 유틸리티가 둘 이상의 호출 인 경우에만 함수를 작성합니다.

함수의 유틸리티를 World.js와 같은 다른 파일로 늘리고 싶다고 가정 해 봅시다.이 경우 파일을 내 보내면 module.exports에서 얻을 수 있습니다.

아래 코드를 사용하여 두 기능을 모두 내보낼 수 있습니다.

var anyVariable={
 sayHelloInEnglish = function() {
      return "Hello";
    };
  sayHelloInSpanish = function() {
      return "Hola";
    }; 
}
module.export=anyVariable;

이제 이러한 함수를 사용하려면 파일 이름을 World.js에 입력하면됩니다.

var world= require("./hello.js");

감사합니다 그것이 도움이된다면 내 대답을 받아주십시오 :)
Shantanu Madane

1
파티 친구에게 조금 늦게 :)
Ben Taliadoros

@ BenTaliadoros 나도 그가 늦었다 고 생각하고 또한 그의 anyVariable 객체에 많은 오류가 있다고 생각합니다. sayHelloInSpanish 메소드 위의 행은 세미콜론 (;)으로 끝나서는 안되며 sayHelloInSpanish = 함수가 잘못되었습니다. 이 물건에는 모든 것이 잘못되었습니다. 나는 그의 답변을 편집 할 것입니다
신성한

1
편집이 비활성화되었습니다. 이 답변에서 alphadogg가 편집 한 것은 무엇입니까 ??
신성한

서식 만 지정하면됩니다. 내가 본 적이없는 미친 es6가 아니라면 확신 할 수 없다면 전혀 유효한 JS가 아닙니다
Ben Taliadoros

2

의도는 다음과 같습니다.

모듈 식 프로그래밍은 프로그램 기능을 독립적이고 상호 교환 가능한 모듈로 분리하는 것을 강조하는 소프트웨어 설계 기법으로, 각 모듈에는 원하는 기능의 한 측면 만 실행하는 데 필요한 모든 것이 포함되어 있습니다.

위키 백과

모듈 식 / 재사용 가능한 코드없이 큰 프로그램을 작성하는 것이 어려워 진다고 생각합니다. nodejs에서 우리는 프로그램을 module.exports노출하고 구성하는 것을 정의 하여 모듈 형 프로그램을 만들 수 있습니다 require.

이 예를보십시오 :

fileLog.js

function log(string) { require('fs').appendFileSync('log.txt',string); }

module.exports = log;

stdoutLog.js

function log(string) { console.log(string); }

module.exports = log;

program.js

const log = require('./stdoutLog.js')

log('hello world!');

실행하다

$ 노드 program.js

안녕 세상!

이제 ./stdoutLog.js./fileLog.js로 바꾸십시오 .


1

모듈 시스템의 목적은 무엇입니까?

다음과 같은 일을 수행합니다.

  1. 파일이 부풀어 오르는 것을 방지합니다. 예를 들어 5000 줄의 코드가 포함 된 파일을 갖는 것은 일반적으로 개발 과정에서 다루기가 매우 어렵습니다.
  2. 우려의 분리를 시행합니다. 코드를 여러 파일로 나누면 모든 파일에 대해 적절한 파일 이름을 가질 수 있습니다. 이 방법으로 모든 모듈의 기능과 위치를 쉽게 식별 할 수 있습니다 (여전히 사용자의 책임 인 논리적 디렉토리 구조를 만들었다 고 가정).

모듈을 사용하면 코드의 특정 부분을 쉽게 찾을 수있어 코드를 유지 관리하기가 더 쉽습니다.

어떻게 작동합니까?

NodejS 다음과 같은 방식으로 작동하는 CommomJS 모듈 시스템을 사용합니다.

  1. 파일이 무언가를 내보내려면 module.export구문 을 사용하여 선언해야 합니다.
  2. 파일에서 무언가를 가져 오려면 require('file')구문 을 사용하여 선언해야 합니다.

예:

test1.js

const test2 = require('./test2');    // returns the module.exports object of a file

test2.Func1(); // logs func1
test2.Func2(); // logs func2

test2.js

module.exports.Func1 = () => {console.log('func1')};

exports.Func2 = () => {console.log('func2')};

알아야 할 다른 유용한 것들 :

  1. 모듈이 캐시 됩니다. 동일한 모듈을 2 개의 다른 파일로로드 할 때 모듈은 한 번만로드하면됩니다. 두 번째로 a require()가 동일한 모듈에서 호출되면 캐시에서 가져옵니다.
  2. 모듈은 동기식으로로드됩니다 . 이 동작은 비동기식 일 경우 필요합니다. 우리는 require()즉시 검색된 객체에 접근 할 수 없습니다 .

-3
let test = function() {
    return "Hello world"
};
exports.test = test;

4
이것은 수락 된 답변의 첫 번째 스 니펫과 비슷한 예 return "Hello world"이지만 아무런 차이가 없습니다. 답변하기 전에 답변이 주제에 무언가를 추가하는지 확인하십시오.
barbsan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.