JavaScript는 세계에서 가장 많이 사용되는 프로그래밍 언어 중 하나이며 웹 세계의 보편적 언어이며 모든 브라우저에서 사용됩니다. 자바스크립트의 탄생은 넷스케이프 시대로 거슬러 올라간다. 그 핵심 콘텐츠는 당시 마이크로소프트와 경쟁하고 치열한 브라우저 전쟁에 참여하기 위해 급하게 개발됐다. 조기 출시로 인해 필연적으로 좋지 않은 기능이 발생했습니다.
짧은 개발 시간에도 불구하고 JavaScript에는 각 스크립트가 전역 네임스페이스를 공유한다는 점을 제외하면 여전히 많은 강력한 기능이 있습니다.
웹 페이지가 JavaScript 코드를 로드하면 전역 네임스페이스에 삽입되고 로드된 다른 모든 스크립트와 동일한 주소 공간을 공유하게 됩니다. 이로 인해 많은 보안 문제, 충돌 및 몇 가지 일반적인 문제가 발생합니다. 추적도 어렵고 해결도 어렵습니다.
그러나 고맙게도 Node는 서버 측 JavaScript에 대한 일부 사양을 설정하고 CommonJS 모듈 표준도 구현했습니다. 이 표준에서 각 모듈은 고유한 컨텍스트를 가지며 다른 모듈과 구별됩니다. 이는 전역 범위와 같은 것이 없고 모듈이 서로 간섭하지 않기 때문에 모듈이 전역 범위를 오염시키지 않는다는 것을 의미합니다.
이 장에서는 여러 가지 모듈과 이를 로드하는 방법에 대해 알아봅니다.
코드를 잘 정의된 일련의 모듈로 분할하면 애플리케이션을 제어하는 데 도움이 될 수 있습니다. 아래에서는 자신만의 모듈을 만들고 사용하는 방법을 알아봅니다.
Node에서 모듈을 로드하는 방법 알아보기
Node에서는 파일 경로나 모듈 이름을 통해 모듈을 참조할 수 있습니다. 핵심 모듈이 아닌 모듈을 이름으로 참조하면 Node는 결국 모듈 이름을 해당 모듈 파일 경로에 매핑합니다. 핵심 기능을 포함하는 핵심 모듈은 Node가 시작될 때 미리 로드됩니다.
비핵심 모듈에는 NPM(노드 패키지 관리자)을 사용하여 설치된 타사 모듈과 귀하 또는 동료가 만든 로컬 모듈이 포함됩니다.
현재 스크립트로 가져온 각 모듈은 프로그래머에게 공개 API 세트를 노출합니다. 모듈을 사용하기 전에 다음과 같이 require 함수를 사용하여 가져와야 합니다.
위 코드는 핵심 모듈이거나 NPM과 함께 설치된 모듈일 수 있는 module_name이라는 모듈을 가져옵니다. require 함수는 모듈의 모든 공개 API를 포함하는 객체를 반환합니다. 모듈에 따라 반환되는 개체는 JavaScript 값, 함수 또는 일련의 속성을 포함하는 개체(함수, 배열 또는 JavaScript 개체)일 수 있습니다.
모듈 내보내기
CommonJS 모듈 시스템은 Node.js 아래 파일 간에 개체와 기능을 공유할 수 있는 유일한 방법입니다. 매우 복잡한 프로그램의 경우 일부 클래스, 개체 또는 함수를 잘 정의된 재사용 가능한 일련의 모듈로 재구성해야 합니다. 모듈 사용자에게 모듈은 지정한 코드만 노출합니다.
다음 예에서는 Node에서 파일과 모듈 사이에 일대일 대응이 있음을 알 수 있습니다. Circle 생성자만 내보내는 Circle.js라는 파일을 만들었습니다.
함수 r_squared() {
Math.pow(r, 2)를 반환합니다.
}
기능 영역() {
Math.PI * r_squared()를 반환합니다.
}
{지역: 지역}을 반환합니다.
}
module.exports = 원;
코드에서 가장 중요한 줄은 모듈이 내보내는 내용을 정의하는 마지막 줄입니다. module은 현재 모듈 자체를 나타내는 특수 변수이며, module.exports는 모듈에서 내보낸 객체입니다. 이 예에서는 모듈 사용자가 사용할 수 있도록 Circle의 생성자를 내보냈습니다. 서클 인스턴스.
일부 복잡한 개체를 내보낼 수도 있습니다. module.exports는 빈 개체로 초기화됩니다. 외부에 노출하려는 콘텐츠를 module.exports 개체의 속성으로 내보낼 수 있습니다. 예를 들어, 일련의 기능을 노출하는 모듈을 설계합니다.
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 및 printB)와 숫자(pi)를 내보냅니다. 호출 코드는 다음과 같습니다.
myModule2.printA() // ->
myModule2.printB() // ->console.log(myModule2.pi) // -> 3.141592653589793
앞서 언급한 것처럼 require 함수를 사용하여 모듈을 로드할 수 있습니다. Node에는 전역 네임스페이스 개념이 없기 때문에 코드에서 require를 호출하면 전역 네임스페이스에 영향을 미칠까 걱정할 필요가 없습니다. 모듈이 존재하고 구문이나 초기화 오류가 없으면 require 함수는 모듈 개체를 반환하며 이 개체를 모든 지역 변수에 할당할 수 있습니다.
모듈에는 여러 가지 유형이 있는데, 크게 코어 모듈, 로컬 모듈, NPM을 통해 설치되는 타사 모듈로 나눌 수 있으며, 모듈을 참조하는 방법에는 여러 가지가 있습니다. 이러한 지식.
코어 모듈 로드노드에는 코어 모듈이라고 하는 바이너리 파일로 컴파일되는 일부 모듈이 있습니다. 이러한 모듈은 경로를 통해서는 참조할 수 없으며 모듈 이름만 참조할 수 있습니다. 코어 모듈은 동일한 이름을 가진 타사 모듈이 있더라도 가장 높은 로딩 우선순위를 갖습니다.
예를 들어 http 코어 모듈을 로드하고 사용하려는 경우 다음과 같이 할 수 있습니다.
절대 경로를 사용하여 파일 시스템에서 모듈을 로드할 수도 있습니다.
또한 디렉토리 경로를 사용하여 모듈을 로드할 수도 있습니다.
노드는 이 디렉토리가 모듈 패키지라고 가정하고 이 디렉토리에서 패키지 정의 파일 package.json을 검색하려고 시도합니다.
찾지 못하면 Node는 패키지의 진입점이 index.js 파일이라고 가정합니다. (역자 주: index.js 외에도 index.node도 검색합니다. .node 파일은 바이너리입니다. Node의 확장 패키지입니다. 자세한 내용은 공식 문서를 참조하세요.) 위 코드를 예로 들면 Node는 ./myModuleDir/index.js 파일을 찾으려고 시도합니다.
반대로 package.json 파일이 발견되면 Node는 이를 구문 분석하고 패키지 정의에서 기본 속성을 찾은 다음 기본 속성 값을 진입점의 상대 경로로 사용합니다. . 이 예에서 package.json이 다음과 같이 정의된 경우:
"이름": "myModule",
"메인": "./lib/myModule.js"
}
노드는 ./myModuleDir/lib/myModule.js 파일을 로드하려고 시도합니다
node_modules 디렉터리에서 로드
require 함수의 매개변수가 상대 경로나 핵심 모듈 이름이 아닌 경우 Node는 현재 디렉터리의 node_modules 하위 디렉터리에서 검색합니다. 예를 들어 다음 코드에서 Node는 파일을 찾으려고 시도합니다./ node_modules/myModule.js:
이 기능을 사용하여 node_modules 디렉터리의 내용이나 모듈을 관리할 수 있지만 모듈 관리 작업은 NPM에 맡기는 것이 가장 좋습니다(1장 참조). 로컬 node_modules 디렉터리는 NPM이 모듈을 설치하는 기본 위치입니다. . 이 디자인은 Node와 NPM이 서로 연결되어 있습니다. 일반적으로 개발자는 이 기능에 대해 크게 신경 쓸 필요가 없으며 NPM을 사용하여 패키지를 설치, 업데이트 및 삭제하면 node_modules 디렉터리가 자동으로 유지됩니다.
캐시 모듈
모듈은 첫 번째 성공적인 로드 후에 캐시됩니다. 즉, 모듈 이름이 동일한 파일 경로로 확인되면 require('myModule')를 호출할 때마다 정확히 동일한 모듈이 반환됩니다.
예를 들어, 다음 콘텐츠를 포함하는 my_module.js라는 모듈이 있습니다.
module.exports = function() {
console.log('안녕!');
};
console.log('my_module이 초기화되었습니다.');
그런 다음 다음 코드를 사용하여 이 모듈을 로드합니다.
다음과 같은 출력이 생성됩니다.
my_module이 초기화되었습니다
두 번 가져오는 경우:
var myModuleInstance2 = require('./my_module');
출력은 여전히 입니다:
my_module이 초기화되었습니다
즉, 모듈의 초기화 코드는 한 번만 실행됩니다. 자신만의 모듈을 빌드할 때 모듈의 초기화 코드에 부작용을 일으킬 수 있는 코드가 포함되어 있는 경우 이 기능에 특별한 주의를 기울이십시오.
요약
Node는 JavaScript의 기본 전역 범위를 취소하고 CommonJS 모듈 시스템을 채택하여 코드를 더 잘 구성하고 많은 보안 문제와 버그를 피할 수 있습니다. require 기능을 사용하여 핵심 모듈, 타사 모듈을 로드하거나 파일 및 디렉터리에서 자체 모듈을 로드할 수 있습니다
비핵심 모듈을 로드하기 위해 상대 경로나 절대 경로를 사용할 수도 있습니다. 모듈을 node_modules 디렉터리에 넣거나 NPM으로 설치된 모듈의 경우 모듈 이름을 직접 사용하여 로드할 수도 있습니다.
번역자 주:
독자들은 공식 문서의 모듈 장을 읽어보는 것이 좋습니다. 개인적으로는 저자보다 더 명확하고 명확하다고 느낍니다. 또한 매우 대표적인 예도 첨부되어 있어 Node 모듈 로딩을 이해하는 데 매우 도움이 될 것입니다. 그 예를 인용해 보겠습니다.
1. X가 핵심 모듈인 경우
a. 코어 모듈 로드 및 반환
b. 끝
2. X가 './', '/' 또는 '../'으로 시작하는 경우
LOAD_AS_FILE(Y X)
b.LOAD_AS_DIRECTORY(Y X)
3.LOAD_NODE_MODULES(X, 디렉터리 이름(Y))
4. 예외 발생: "찾을 수 없음"
LOAD_AS_FILE(X)
1. X가 파일인 경우 X를 자바스크립트 스크립트로 로드하고 로드 후 종료합니다
2. X.js가 파일인 경우 X.js를 자바스크립트 스크립트로 로딩하고 로딩 후 종료
3. X.node가 파일인 경우 X.node를 Node 바이너리 플러그인으로 로딩하고, 로딩이 완료된 후 종료합니다
LOAD_AS_DIRECTORY(X)
1. X/package.json 파일이 존재하는 경우
a. X/package.json을 구문 분석하고 "main" 필드를 찾습니다.
b. 또 다른 M = X(메인 필드의 값)
c.LOAD_AS_FILE(M)
2. X/index.js 파일이 존재한다면 X/index.js를 자바스크립트 스크립트로 로딩하고 로딩 후 종료합니다
3. X/index.node 파일이 존재하는 경우 X/index.node를 Node 바이너리 플러그인으로 로딩하고, 로딩이 완료된 후 종료합니다
LOAD_NODE_MODULES(X, START)
1. 또한 DIRS=NODE_MODULES_PATHS(START)
2. DIRS 아래의 각 디렉터리 DIR에 대해 다음 작업을 수행합니다.
LOAD_AS_FILE(DIR/X)
b.LOAD_AS_DIRECTORY(DIR/X)
NODE_MODULES_PATHS(시작)
1. 또 다른 부분 = 경로 분할(START)
2. 또 다른 ROOT = PARTS에서 "node_modules"의 첫 번째 인스턴스 인덱스 또는 0
3. I = 부품 수 - 1
4. 또 다른 DIRS = []
5. ROOT하는 동안
a. PARTS[I] = "node_modules"이면 후속 작업을 계속하고, 그렇지 않으면 다음에 반복됩니다.
c. DIR = 경로 조인(PARTS[0 .. I] "node_modules")
b. DIRS = DIRS 디렉토리
c. 또 다른 나 = 나 - 1
6. DIRS로 돌아가기