javascript - 모듈이란 - node.js 변수
Node.js module.exports의 목적은 무엇이며 어떻게 사용합니까? (8)
모듈 시스템의 목적은 무엇입니까?
다음과 같은 작업을 수행합니다.
- 우리의 파일 을 정말 큰 크기로 유지 합니다. 예를 들어 5000 줄의 코드가있는 파일을 개발하는 동안 대개 다루기가 정말 어렵습니다.
- 우려의 분리를 강요합니다. 코드를 여러 파일로 분리하면 모든 파일에 대해 적절한 파일 이름을 가질 수 있습니다. 이렇게하면 모든 모듈이 무엇을하는지, 어디에서 찾을 수 있는지 쉽게 식별 할 수 있습니다 (우리는 여전히 당신의 책임하에 논리적 디렉토리 구조를 만들었다 고 가정).
모듈을 사용하면 코드의 특정 부분을 쉽게 찾을 수 있으므로 코드를 유지 관리 할 수 있습니다.
어떻게 작동합니까?
NodejS
는 다음과 같은 방식으로 작동하는 CommomJS 모듈 시스템을 사용합니다.
- 파일이 뭔가를 내보내
module.export
하면module.export
구문을 사용하여 선언해야합니다. - 파일이 뭔가를 가져오고 싶다면
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')};
알아두면 유용한 다른 것들 :
- 모듈이 캐싱되고 있습니다. 동일한 모듈을 2 개의 다른 파일에로드 할 때 모듈은 한 번만로드하면됩니다. 두 번째로
require()
가 캐시에서 가져온 동일한 모듈에서 호출됩니다. - 모듈은 동기식으로로드됩니다 . 비동기 적으로
require()
에서 검색 한 객체에 즉시 액세스 할 수없는 경우이 동작이 필요합니다.
Node.js module.exports의 목적은 무엇이며 어떻게 사용합니까?
이것에 대한 정보를 찾을 수없는 것 같지만 Node.js에서 오히려 중요한 부분 인 것처럼 보입니다. 종종 소스 코드에서 볼 수 있습니다.
Node.js 문서 에 따르면 :
기준 치수
현재
module
대한 참조입니다. 특히module.exports
는 내보내기 객체와 동일합니다. 자세한 내용은src/node.js
를 참조하십시오.
그러나 이것은 실제로 도움이되지 않습니다.
module.exports
는 정확히 무엇을합니까? 간단한 예제는 무엇입니까?
NodeJS 모듈 메커니즘은 RequireJS 뿐만 아니라 SproutCore , CouchDB , Wakanda , OrientDB , ArangoDB , RingoJS , TeaJS , SilkJS , curl.js 또는 Adobe Photoshop ( PSLib 통해)과 같은 많은 다른 구현에서 지원되는 CommonJS 모듈을 기반으로합니다. ). here 에는 알려진 구현의 전체 목록이 here .
모듈에서 노드 특정 기능 또는 모듈을 사용 하지 않는 한, CommonJS 표준의 일부가 아닌 module.exports
대신 exports
를 사용하고 다른 구현에서는 대부분 지원되지 않습니다.
또 다른 NodeJS 고유 기능은이 스레드에서 Jed Watson이 제공 한 마지막 예제 에서처럼 속성 및 메서드를 추가하는 대신 exports
할 새 객체에 대한 참조를 할당하는 경우입니다. 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 모듈 (캐싱 및 순환 참조) ).
모듈은 관련 코드를 단일 코드 단위로 캡슐화합니다. 모듈을 생성 할 때 이것은 관련된 모든 함수를 하나의 파일로 옮기는 것으로 해석 될 수 있습니다.
두 개의 함수를 포함하는 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 inorder에 파일 이름을 사용하여 해당 기능을 사용하면됩니다.
var world= require("./hello.js");
새 객체에 대한 참조를 modules.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
를 모두 사용하여 응용 프로그램에 코드를 가져올 수 있습니다.
var mycode = require('./path/to/mycode');
ExpressJS 예제 코드에서 볼 수있는 기본 사용 사례는 .js 파일의 exports
객체에 대한 속성을 설정 한 다음 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
간단히 말해, 필요한 파일을 단일 객체를 반환하는 함수로 생각할 수 있으며, 내보낼 때 반환되는 객체에 속성 (문자열, 숫자, 배열, 함수 등)을 추가 할 수 있습니다.
때로는 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 = function(){
//....
}
함수 또는 변수와 같은 exports
또는 module.exports
의 속성이 외부에 노출됩니다.
좀 더주의를 기울여야하는 것이 override
: 수출을 override
하지 마십시오.
왜 ?
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();
이 모듈은 오직 하나의 함수 만 노출 시켰고 이름의 속성은 외부에 대해 private입니다.
module.exports
는 require
호출의 결과로 실제로 반환되는 객체입니다.
exports
변수는 처음에는 같은 객체로 설정됩니다 (즉, "별칭"). 모듈 코드에서 다음과 같이 작성합니다.
var myFunc1 = function() { ... };
var myFunc2 = function() { ... };
exports.myFunc1 = myFunc1;
exports.myFunc2 = myFunc2;
내부적으로 범위가 지정된 함수 myFunc1
및 myFunc2
를 내보내거나 "노출"합니다.
그리고 호출 코드에서 다음을 사용합니다.
var m = require('./mymodule');
m.myFunc1();
마지막 행은 require
의 결과가 (일반적으로) 속성에 액세스 할 수있는 일반 객체 인 방법을 보여줍니다.
주의 : exports
를 덮어 쓰면 더 이상 module.exports
참조하지 않습니다. 따라서 새 객체 (또는 함수 참조)를 module.exports
객체를 module.exports
할당해야합니다.
exports
객체에 추가 된 이름이 모듈의 내부 범위 이름과 같을 필요가 없다는 점에 유의해야합니다. 따라서 다음과 같이 할 수 있습니다.
var myVeryLongInternalName = function() { ... };
exports.shortName = myVeryLongInternalName;
// add other objects, functions, as required
뒤에 :
var m = require('./mymodule');
m.shortName(); // invokes module.myVeryLongInternalName
http, sys 등의 node.js를 다운로드하여 설치할 때 node.js에 기본 또는 기존 모듈이 있습니다.
그들은 이미 node.js에 있기 때문에 우리는이 모듈을 사용하기 위해 기본적으로 import 모듈 을 사용합니다. 왜 그런가? 노드 .js에 이미 있기 때문입니다. 가져 오기는 node.js에서 가져 와서 프로그램에 넣는 것과 같습니다. 그리고 그들을 사용합니다.
내보내기 가 정반대인데 원하는 모듈을 만들고, 모듈 addition.js를 말하고 그 모듈을 node.js에 넣으면 내보내는 것입니다.
여기에 아무것도 쓰지 않기 전에, module.exports.additionTwo 는 exports.additionTwo 와 같습니다.
허, 그게 이유야, 우리는 좋아해.
exports.additionTwo = function(x)
{return x+2;};
경로에주의하십시오.
additional.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를 설정하지 않고 nodejs 명령 프롬프트로 돌아가서 addition.js 파일을 실행할 수도 있습니다.
node
var run = require('./addition.js');
현재 디렉토리에 있다고 말하면서 경로를 제공하기 때문에 ./
이것은 또한 성공적으로 실행되어야합니다.