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

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

둘 다 사용할 수 있습니다 exports와 module.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.additionTwo 는 exports.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.