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
답변
이것은 이미 답변되었지만 설명을 추가하고 싶었습니다 …
둘 다 사용할 수 있습니다 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!"
답변
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.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 속성은 외부 전용입니다.