JavaScript는 세계에서 가장 자주 사용되는 프로그래밍 언어 중 하나입니다. 웹 세계의 일반적인 언어이며 모든 브라우저에서 사용됩니다. JavaScript의 탄생은 Netscape 시대로 거슬러 올라가며, 그 핵심 콘텐츠는 Microsoft와 싸우고 당시 치열한 브라우저 전쟁에 참여하기 위해 급히 개발되었습니다. 조기 릴리스로 인해 일부 열악한 기능 중 일부는 필연적으로 발생했습니다.
개발 시간이 짧지 만 JavaScript에는 각 스크립트에 대한 글로벌 네임 스페이스를 공유하는 기능을 제외하고는 여전히 많은 강력한 기능이 있습니다.
웹 페이지에 JavaScript 코드가로드되면 글로벌 네임 스페이스에 주입되며 다른 모든로드 된 스크립트와 동일한 주소 공간을 공유하므로 많은 보안 문제, 충돌 및 몇 가지 일반적인 문제로 이어지고 버그를 추적하기가 어렵고 해결하기가 어렵습니다.
그러나 고맙게도 Node는 서버 측 JavaScript에 대한 일부 사양을 설정했으며 CommonJS 모듈 표준도 구현합니다. 이 표준에서 각 모듈에는 고유 한 컨텍스트가 있으며 다른 모듈과 구별됩니다. 이는 소위 글로벌 범위가 전혀 없기 때문에 모듈이 글로벌 범위를 오염시키지 않으며 모듈은 서로 방해하지 않기 때문입니다.
이 장에서는 여러 가지 다른 모듈과로드하는 방법에 대해 배울 것입니다.
코드를 잘 정의 된 일련의 모듈로 분할하면 응용 프로그램을 제어 할 수 있습니다. 아래에서 우리는 자신의 모듈을 만들고 사용하는 방법을 배웁니다.
노드가 모듈을로드하는 방법에 대해 알아보십시오
노드에서 모듈은 파일 경로 또는 모듈 이름을 통해 참조 할 수 있습니다. 비 코어 모듈이 이름으로 참조되면 노드는 결국 모듈 이름을 해당 모듈 파일 경로에 암시합니다. 코어 함수를 포함하는 코어 모듈은 노드가 시작될 때 사전로드됩니다.
비 코어 모듈에는 NPM (Node Package Manager)을 사용하여 설치된 타사 모듈과 귀하 또는 동료가 작성한 로컬 모듈이 포함됩니다.
현재 스크립트로 가져온 각 모듈은 노출 된 API 세트를 프로그래머에게 노출시킵니다. 모듈을 사용하기 전에 요구 기능을 사용하여 다음과 같이 가져와야합니다.
코드 사본은 다음과 같습니다.
var module = require ( 'module_name')
위의 코드는 module_name이라는 모듈을 가져옵니다. 코어 모듈 또는 NPM과 함께 설치된 모듈 일 수 있습니다. 요구 함수는 모듈의 모든 공개 API를 포함하는 객체를 반환합니다. 모듈에 따라 반환 된 객체는 JavaScript 값 일 수 있으며, 함수 또는 일련의 속성 (함수, 배열 또는 JavaScript 객체)을 포함하는 객체 일 수 있습니다.
내보내기 모듈
CommonJS 모듈 시스템은 노드 아래 파일간에 개체와 함수를 공유하는 유일한 방법입니다. 매우 복잡한 프로그램의 경우 일부 클래스, 객체 또는 기능을 일련의 잘 정의 된 재사용 가능한 모듈로 재구성해야합니다. 모듈 사용자의 경우 모듈은 외부 세계에 지정한 코드 만 노출됩니다.
다음 예에서는 노드에서 파일과 모듈이 하나씩 일치한다는 것을 이해합니다. Circle.js라는 파일을 만들었습니다.이 파일은 Circle 생성자 만 외부로 내보내는 파일을 만들었습니다.
코드 사본은 다음과 같습니다.
함수 원 (x, y, r) {
함수 r_squared () {
return math.pow (r, 2);
}
기능 영역 () {
return math.pi * r_squared ();
}
반환 {영역 : 영역};
}
module.exports = circle;
코드에서 가장 중요한 것은 마지막 줄입니다.이 줄은 모듈이 외부로 내보내는 것을 정의합니다. 모듈은 현재 모듈 자체를 나타내는 특수 변수이며 Module.Exports는 모듈에서 내보낸 객체입니다. 그것은 어떤 대상이 될 수 있습니다. 이 예에서는 모듈 사용자 가이 모듈을 사용하여 원 인스턴스를 생성 할 수 있도록 서클 생성자를 내 보냅니다.
또한 복잡한 개체 인 Module.exports는 빈 객체로 초기화되며 Module.exports 객체의 속성으로 외부 세계에 노출하려는 모든 것을 내보낼 수 있습니다. 예를 들어, 기능 세트를 외부에 노출시키는 모듈을 설계했습니다.
코드 사본은 다음과 같습니다.
함수 printa () {
Console.log ( 'a');
}
함수 printb () {
Console.log ( 'B');
}
함수 printc () {
Console.log ( 'C');
}
module.exports.printa = printa;
module.exports.printb = printb;
module.exports.pi = math.pi;
이 모듈은 두 가지 함수 (printa and printb)와 숫자 (PI)를 내보내며 호출 코드는 다음과 같습니다.
코드 사본은 다음과 같습니다.
var myModule2 = require ( './ myModule2');
myModule2.printa (); //-> a
myModule2.printb (); //-> b
Console.log (MyModule2.pi); //-> 3.141592653589793
로드 모듈
앞에서 언급했듯이 요구 함수를 사용하여 모듈을로드 할 수 있으며 코드에서 요구가 전역 네임 스페이스에 영향을 미칠 것이라고 걱정하지 마십시오. 노드에는 글로벌 네임 스페이스 개념이 없기 때문입니다. 모듈이 구문 또는 초기화 오류없이 존재하는 경우 요구 함수는 모듈 객체를 반환 하며이 객체를 로컬 변수에 할당 할 수도 있습니다.
NPM을 통해 설치된 코어 모듈, 로컬 모듈 및 타사 모듈로 대략 분할 할 수있는 여러 가지 유형의 모듈이 있습니다. 모듈 유형에 따르면 모듈을 참조하는 몇 가지 방법이 있습니다. 아래 지식에 대해 배우겠습니다.
코어 모듈로드
노드에는 코어 모듈이라고하는 이진 파일로 컴파일 된 일부 모듈이 있습니다. 그들은 경로로 참조 할 수 없으며 모듈 이름으로 만 사용할 수 있습니다. 코어 모듈은로드 우선 순위가 가장 높으며 이미 동일한 이름의 타사 모듈이 있더라도 핵심 모듈이 먼저로드됩니다.
예를 들어, HTTP 코어 모듈을로드하고 사용하려면 다음을 수행 할 수 있습니다.
코드 사본은 다음과 같습니다.
var http = 요구 ( 'http');
이것은 노드 API 문서에 정의 된 HTTP 모듈의 API를 포함하는 HTTP 모듈을 포함하는 객체를 반환합니다.
파일 모듈로드
절대 경로를 사용하여 파일 시스템에서 모듈을로드 할 수도 있습니다.
코드 사본은 다음과 같습니다.
var myModule = require ( '/home/pedro/my_modules/my_module');
현재 파일을 기반으로 상대 경로를 사용할 수도 있습니다.
코드 사본은 다음과 같습니다.
var myModule = require ( '../ my_modules/my_module');
var myModule2 = require ( './ lib/my_module_2');
위의 코드에주의하십시오. 파일 이름의 확장을 생략 할 수 있습니다. 노드 에서이 파일을 찾을 수없는 경우 파일 이름 (Translator의 참고 : 실제로 JS 외에도 JSON 및 NODE도 찾을 수 있습니다. 자세한 내용은 공식 웹 사이트 문서를 볼 수 있습니다). 따라서 현재 디렉토리에 my_module.js라는 파일이 존재하는 경우 두 가지 로딩 방법이 있습니다.
코드 사본은 다음과 같습니다.
var myModule = require ( './ my_module');
var myModule = require ( './ my_module.js');
디렉토리 모듈로드
디렉토리 경로를 사용하여 모듈을로드 할 수도 있습니다.
코드 사본은 다음과 같습니다.
var myModule = require ( './ myModuledir');
노드는이 디렉토리가 모듈 패키지라고 가정 하고이 디렉토리에서 패키지 정의 파일 package.json을 검색하려고합니다.
찾을 수없는 경우, 노드는 패키지의 진입 점이 index.js 파일이라고 가정합니다 (번역기 주 : index.js 외에도 index.node도 찾을 수 있으며 .Node 파일은 Node의 이진 확장 패키지입니다. 자세한 내용은 공식 문서를 참조하십시오). 위의 코드는 예입니다. 노드는 ./mymoduledir/index.js 파일을 찾으려고합니다.
반대로, package.json 파일을 찾으면 노드는 그것을 구문 분석하고 패키지 정의에서 기본 속성을 찾은 다음 기본 속성의 값을 진입 점의 상대 경로로 사용합니다. 이 예에서는 package.json이 다음과 같이 정의 된 경우.
코드 사본은 다음과 같습니다.
{
"이름": "myModule",
"메인": "./lib/mymodule.js"
}
노드는 ./mymoduledir/lib/mymodule.js 파일을로드하려고합니다
node_modules 디렉토리에서로드하십시오
요구 함수의 매개 변수가 상대 경로 또는 코어 모듈 이름이 아닌 경우 현재 디렉토리의 Node_Modules 하위 디렉토리에서 노드가 검색됩니다. 예를 들어, 다음 코드에서 노드는 파일을 찾으려고합니다 ./node_modules/mymodule.js :
코드 사본은 다음과 같습니다.
var myModule = require ( 'myModule.js');
찾을 수 없으면 노드는 상단 디렉토리의 node_modules 폴더에서 계속 검색됩니다. 찾을 수없는 경우 해당 모듈이 발견되거나 루트 디렉토리에 도달 할 때까지 상단 디렉토리에서 계속 검색하십시오.
이 기능을 사용하여 Node_Modules 디렉토리의 컨텐츠 또는 모듈을 관리 할 수 있지만 모듈 관리 작업을 NPM에 양도하는 것이 가장 좋습니다 (1 장 참조). 로컬 node_modules 디렉토리는 NPM 설치 모듈의 기본 위치입니다. 이 디자인은 노드와 NPM을 함께 연관시킵니다. 일반적으로 개발자 로서이 기능에 대해 너무 신경 쓰지 않아도됩니다. NPM을 사용하여 패키지를 설치, 업데이트 및 삭제하면 NODE_MODULES 디렉토리를 유지하는 데 도움이됩니다.
캐시 모듈
첫 번째 성공적인로드 후 모듈이 캐시됩니다. 즉, 모듈 이름이 동일한 파일 경로로 해결되면 모든 호출을 요구하는 경우 ( 'myModule')는 정확히 동일한 모듈을 반환합니다.
예를 들어 다음 내용이 포함 된 My_Module.js라는 모듈이 있습니다.
코드 사본은 다음과 같습니다.
console.log ( 'module my_module 초기화 ...');
module.exports = function () {
Console.log ( 'Hi!');
};
console.log ( 'my_module 초기화.');
그런 다음 다음 코드를 사용하여 모듈을로드하십시오.
코드 사본은 다음과 같습니다.
var myModuleInstance1 = require ( './ my_module');
다음 출력을 생성합니다.
코드 사본은 다음과 같습니다.
모듈 my_module 초기화 ...
my_module 초기화
두 번 가져 오면 :
코드 사본은 다음과 같습니다.
var myModuleInstance1 = require ( './ my_module');
var myModuleInstance2 = require ( './ my_module');
출력은 여전히 다음과 같습니다.
코드 사본은 다음과 같습니다.
모듈 my_module 초기화 ...
my_module 초기화
즉, 모듈의 초기화 코드는 한 번만 실행됩니다. 고유 한 모듈을 빌드 할 때 모듈의 초기화 코드에 부작용이있는 코드가 포함 된 경우이 기능에 특별한주의를 기울여야합니다.
요약
Node는 JavaScript의 기본 글로벌 범위를 취소하고 대신 CommonJS 모듈 시스템을 채택하여 코드를 더 잘 구성하고 많은 보안 문제와 버그를 피할 수 있습니다. 요구 기능을 사용하여 코어 모듈, 타사 모듈을로드하거나 파일 및 디렉토리에서 고유 한 모듈을로드 할 수 있습니다.
상대적 또는 절대 경로를 사용하여 비 코어 모듈을로드 할 수도 있습니다. 모듈을 node_modules 디렉토리에 넣거나 npm으로 설치된 모듈에 대해 모듈 이름을 직접 사용하여로드 할 수도 있습니다.
번역가 노트 :
독자는 공식 문서의 모듈 장을 읽는 것이 좋습니다. 나는 개인적으로 저자보다 더 명확하다고 생각합니다. 매우 대표적인 예제가 첨부되어 노드 모듈로드를 이해하는 데 큰 도움이 될 것입니다. 다음은 인용됩니다.
코드 사본은 다음과 같습니다.
경로 y 아래에 모듈을로드하려면 (x)를 사용하십시오
1. X가 핵심 모듈 인 경우
에이. 코어 모듈을로드하고 반환하십시오
비. 끝
2. X가 './'또는 '/'또는 '../부터 시작하면
에이. load_as_file (y + x)
비. load_as_directory (y + x)
3. load_node_modules (x, dirname (y))
4. 예외를 던져 : "찾지 못함"
load_as_file (x)
1. X가 파일 인 경우 X를 JavaScript 스크립트로로드하고로드 후 끝납니다.
2. X.JS가 파일 인 경우 X.JS를 JavaScript 스크립트로로드하고로드 후 끝납니다.
3. x.node가 파일 인 경우 x.node가 노드 바이너리 플러그인으로로드하고로드 후 끝납니다.
load_as_directory (x)
1. x/package.json 파일이 존재하면
에이. x/package.json을 구문 분석하고 "메인"필드를 찾으십시오.
비. 또한 m = x + (메인 필드 값)
기음. load_as_file (m)
2. x/index.js 파일이 존재하면 x/index.js를 JavaScript 스크립트로로드하고로드 후 종료하십시오.
3. x/index.node 파일이 존재하면 x/index.node를 노드 바이너리 플러그인으로로드하고로드 후 끝납니다.
load_node_modules (x, start)
1. 또한 dirs = node_modules_paths (시작)
2. DIRS 아래의 각 디렉토리에 대한 다음 작업을 수행하십시오.
에이. load_as_file (dir/x)
비. load_as_directory (dir/x)
node_modules_paths (시작)
1. 또한 부품 = 경로 분할 (시작)
2. 또한 루트 = 부분에서 "node_modules"의 첫 번째 인스턴스 또는 0
3. 또한 i = 부품 카운트 -1
4. 또한 dirs = []
5. 내가 뿌리를 내리는 동안
에이. 부품 [i] = "node_modules"인 경우 후속 조작이 계속됩니다. 그렇지 않으면 다음 루프가
기음. dir = Path Join (part [0 .. i] + "node_modules")
비. dirs = dirs + dir
기음. 또한 i = i -1
6. Dirs로 돌아갑니다