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

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

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

Node.js 문서 에 따르면 :

구성 단위

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

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

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



답변

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


답변

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

둘 다 사용할 수 있습니다 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의 차이점은 이 답변에서 더 잘 설명 됩니다 .


답변

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 모듈 (캐싱 및 순환 참조) 참조 )


답변

새 객체에 대한 참조를 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() {}; 


답변

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

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

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


답변

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

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

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

모듈 내보내기 다이어그램

“모듈 2-쓰기 모듈” 에 따르면 .


답변

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

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 속성은 외부 전용입니다.