module.exports 대 Node.js의 내보내기
Node.js 모듈에서 다음 계약을 찾았습니다.
module.exports = exports = nano = function database_module(cfg) {...}
내가 무슨 일을 사이에 다른 궁금 module.exports하고 exports왜 모두 여기에 사용됩니다.
설정 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.js 는 exports현재 참조 하는 객체를 내 보내지 않지만 exports원래 참조 하는 속성을 내 보냅니다 . Node.js 는 객체 module.exports참조를 내보내 지만 함수처럼 호출 할 수 있습니다.
두 번째로 중요한 이유
그들은 둘을 설정 module.exports하고 exports확인하기 위해 exports사전에 수출 객체를 참조하지 않습니다. 두 가지 모두를 exports속기로 설정 하고 나중에 길을 따라 잠재적 인 버그를 피할 수 있습니다.
exports.prop = true대신 사용 module.exports.prop = true하면 문자 를 저장하고 혼동을 피할 수 있습니다.
질문에 대한 답변이 오래 전부터 받아 들여졌지만 2 센트를 공유하고 싶습니다.
파일의 맨 처음에 다음과 같은 내용이 있다고 상상할 수 있습니다.
var module = new Module(...);
var exports = module.exports;

따라서 무엇을하든 기억하고 다른 곳에서 해당 모듈을 요구할 때 모듈에서 반환 module.exports되지 않습니다 exports.
따라서 다음과 같이 할 때 :
exports.a = function() {
console.log("a");
}
exports.b = function() {
console.log("b");
}
module.exports가 가리키는 객체에 두 개의 함수 'a'와 'b'를 추가하므로 typeof반환 결과는 다음과 object같습니다.{ a: [Function], b: [Function] }
물론 이것은 module.exports대신이 예제에서 사용하는 경우 얻을 수있는 동일한 결과 입니다 exports.
module.exports가 내 보낸 값의 컨테이너처럼 동작하도록하려는 경우입니다. 반면 생성자 함수 만 내보내려면 module.exports또는 exports; (내보내기가 아닌 무언가가 필요할 때 module.exports가 반환된다는 것을 다시 기억하십시오) 사용에 대해 알아야 합니다.
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가리키는 객체를 '지키지' 않기 때문에와 사이 exports에 module.exports더 이상 관계가 없습니다. 이 경우 module.exports는 여전히 {}반환 될 빈 객체 를 가리 킵니다 .
다른 주제에서 수락 된 답변도 도움이 될 것입니다. Javascript가 참조로 전달됩니까?
기본적으로 대답은 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.
require의 다음 단계는 file1.js의 내용을 아래와 같은 익명 함수로 래핑하는 것입니다.
(function (exports, require, module, __filename, __dirname) {
//contents from file1.js
module.exports = '123;
});
그리고이 익명 함수는 다음과 같은 방식으로 호출됩니다. module여기서는 Module앞서 만든 Object를 참조합니다 .
(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의 일부로 내보내거나 반환되지 않습니다.
처음에는, module.exports=exports및 require함수가 module.exports참조 하는 객체를 반환합니다 .
예 를 들어 객체 에 속성 을 추가 하면 exports.a=1module.exports 및 exports는 여전히 동일한 객체를 참조합니다. 따라서 require를 호출하고 모듈을 변수에 할당하면 변수에는 속성 a가 있고 그 값은 1입니다.
우리는하지만 오버라이드 (override) 중 하나를 예를 들어 exports=function(){}, 그들은는 다른 지금 : 수출은 새로운 객체를 참조하고 module.exports 원본 객체를 참조하십시오. 그리고 파일이 필요한 경우 module.exports가 새 개체를 참조하지 않기 때문에 새 개체를 반환하지 않습니다.
나를 위해 새 속성을 계속 추가하거나 둘 다 새 개체에 재정의합니다. 그냥 무시하는 것은 옳지 않습니다. 그리고 그것이 module.exports진짜 보스 라는 것을 명심 하십시오.
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() { ... }
JavaScript는 참조 사본으로 객체를 전달합니다.
객체가 JavaScript에서 참조로 전달되는 방식과 관련하여 미묘한 차이가 있습니다.
exports와 module.exports같은 객체를 모두 가리 킵니다. exports변수이며 module.exports모듈 객체의 속성입니다.
다음과 같이 씁니다.
exports = {a:1};
module.exports = {b:12};
exports그리고 module.exports지금은 다른 개체를 가리 킵니다. 내보내기를 수정해도 더 이상 module.exports가 수정되지 않습니다.
가져 오기 기능이 검사 module.exports하면{b:12}
몇 가지 테스트를 해보면 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)
다음은 Manning 간행물의 액션 북에 있는 node.js의 노드 모듈에 대한 좋은 설명입니다 . 궁극적으로 애플리케이션에서 내보내는 것은 module.exports입니다. exports 는 단순히 module.exports에 대한 전역 참조로 설정 되며 , 처음에는 속성을 추가 할 수있는 빈 개체로 정의됩니다. 그래서 exports.myFunc 단지 속기 module.exports.myFunc . 결과적으로 exports 가 다른 것으로 설정 되면 module.exports 와 exports 간의 참조 가 끊어집니다 . module.exports 때문에
실제로 내보내지는 것이므로 내보내기 가 더 이상 예상대로 작동하지 않습니다 . 모듈 .exports를 더 이상 참조하지 않습니다 . 해당 링크를 유지하려면 다음과 같이 module.exports 참조 내보내기를 다시 만들 수 있습니다 .
module.exports = exports = db;
나는 몇 가지 테스트를 받았고 이것이 주제에 대해 약간의 빛을 비추어 줄 것이라고 생각합니다.
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 : {}, 사용자 : {}}"출력이 표시됩니다.
./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 : [Function : fn]}, ThisLoadedLast : {ThisLoadedLast : [Function : ThisLoadedLast]}}")
따라서 항상 module.exports모듈 정의에 사용하는 것이 좋습니다 .
Node 내부에서 무슨 일이 벌어지고 있는지 완전히 이해하지 못하지만 도움이 될 것이라고 확신하므로 더 이해가 되시면 의견을 보내주십시오.
-해피 코딩
이것은 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);
다음은 결과입니다.
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 사양에서는 공용 멤버를 노출하기 위해 exports 변수를 사용할 수만 있습니다. 따라서 명명 된 내보내기 패턴은 CommonJS 사양과 실제로 호환되는 유일한 패턴입니다. module.exports의 사용은 광범위한 모듈 정의 패턴을 지원하기 위해 Node.js에서 제공하는 확장입니다.
var a = {},md={};
// 첫째, exports 및 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); //{}
로부터 문서
exports 변수는 모듈의 파일 수준 범위 내에서 사용할 수 있으며 모듈이 평가되기 전에 module.exports 값이 할당됩니다.
바로 가기를 허용하므로 module.exports.f = ...는 exports.f = ...로 더 간결하게 작성할 수 있습니다. 그러나 다른 변수와 마찬가지로 새 값이 내보내기에 할당되면 더 이상 module.exports에 바인딩되지 않습니다.
module.exports를 가리키는 변수 일뿐입니다.
이 링크가 위의 질문에 답하는 데 유용하다는 것을 알았습니다.
http://timnew.me/blog/2012/04/20/exports-vs-module-exports-in-node-js/
다른 게시물에 추가하려면 노드의 모듈 시스템은
var exports = module.exports
코드를 실행하기 전에. 따라서 exports = foo를 원할 때 module.exports = exports = foo를 원할 수 있지만 exports.foo = foo 사용하는 것이 좋습니다.
"모듈 내보내기의 루트가 함수 (예 : 생성자)가되기를 원하거나 한 번에 하나의 속성을 빌드하는 대신 하나의 할당으로 전체 객체를 내보내려면 대신 module.exports에 할당하십시오. 수출. " - http://nodejs.org/api/modules.html
1. 내보내기-> 싱글 톤 유틸리티로 사용
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;
}
둘 다 여기서 사용되는 이유
나는 그들이 단지 명확하게 할 생각이 module.exports, exports그리고 nano동일한 기능을 가리키고 - 당신은 파일 내의 함수를 호출하거나 변수를 사용할 수 있도록. nano함수가 수행하는 작업에 대한 컨텍스트를 제공합니다.
exports수출되지 않을 것입니다 (유일 module.exports하게), 왜 그것을 덮어 쓰는가?
자세한 장단점 은 파일 내에서 exports대신 사용 하는 것과 같은 향후 버그의 위험을 제한 module.exports합니다. 또한 제공하고 설명 한다는 module.exports와 exports같은 값을 가리키는 사실에있다.
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
module.exports = () => console.log('hello world');
app2.js : let sayHello = require('./helloWorld2'); sayHello; // hello world
생성하는 각 파일은 모듈입니다. 모듈은 객체입니다. exports : {}기본적으로 빈 객체 인 속성이 있습니다 .
당신은 같은 객체 기능 / 미들웨어를 만들고이 빈 수출에 추가 할 수있는 exports.findById() => { ... }다음 require앱에서 사용 어디서나 ...
controllers / user.js
exports.findById = () => {
// do something
}
route.js 에서 다음 을 사용해야합니다.
const {findyId} = './controllers/user'
module.exports및 exports모듈 전과 동일한 개체에 두 점을 평가한다.
module.exports객체에 추가 한 모든 속성 은 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 웹 사이트는 이것에 대한 아주 좋은 설명을 가지고 있습니다.
노드 js에서 module.js 파일은 node.load system.every 매번 노드가 파일을 실행할 때 다음과 같이 js 파일 내용을 래핑하는 데 사용됩니다.
'(function (exports, require, module, __filename, __dirname) {',+
//your js file content
'\n});'
이 방법은 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
내보내기는 [object Object]입니다.
foo의 object.keys : name is function () {console.log ( 'function to module exports')} function to module exports
이제 a.js에서 주석 처리 된 줄을 제거하고 해당 줄 위의 줄을 주석 처리하고 b.js의 마지막 줄을 제거하고 실행합니다.
자바 스크립트 세계에서는 매개 변수로 전달 된 객체를 재 할당 할 수 없지만 해당 함수의 객체가 다른 함수에 매개 변수로 설정되면 함수의 공용 멤버를 변경할 수 있습니다.
기억하세요
module.exports를 사용하고 require 키워드를 사용할 때 함수를 얻으려는 경우에만 사용하십시오. 위의 예에서 우리는 var foo = require (a.js); foo를 함수로 호출 할 수 있습니다.
이것이 노드 문서에서 "모듈 시스템에 의해 내보내기 객체가 생성됩니다. 때로는 허용되지 않는 경우가 많으며, 많은 사람들이 모듈이 일부 클래스의 인스턴스가되기를 원합니다. 이렇게하려면 원하는 내보내기 객체를 module.exports에 할당합니다."
-
모두
module.exports와exports같은 가리킨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"b라인 3에서으로 변경할 수 있으며a출력은 반대입니다. 결론은 다음과 같습니다.a와b독립적이다. 따라서 다음
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')();In
moduls.js:exports대신 사용할 수 있습니다module.exports.
그래서, 당신은 두 경우 드리겠습니다 exports과 module.exports같은 일을 가리키는.
참고 URL : https://stackoverflow.com/questions/7137397/module-exports-vs-exports-in-node-js
'developer tip' 카테고리의 다른 글
| DataFrame 열의 순서를 변경하는 방법은 무엇입니까? (0) | 2020.09.30 |
|---|---|
| 개수 (*) 대 개수 (1)-SQL Server (0) | 2020.09.30 |
| 옵션 추가 (0) | 2020.09.30 |
| JavaScript에서 배열의 최소 / 최대 요소 찾기 (0) | 2020.09.30 |
| Python의 easy_install로 설치된 패키지를 제거하려면 어떻게해야합니까? (0) | 2020.09.30 |

