모듈: CommonJS 모듈#
CommonJS 모듈은 Node.js용 JavaScript 코드를 패키징하는 원래 방법입니다. Node.js는 브라우저 및 기타 JavaScript 런타임에서 사용하는 ECMAScript 모듈 표준 도 지원합니다 .
Node.js에서 각 파일은 별도의 모듈로 취급됩니다. 예를 들어 다음과 같은 파일이 있다고 가정합니다 foo.js.
const circle = require('./circle.js');
console.log(`The area of a circle of radius 4 is ${circle.area(4)}`); 복사
첫 번째 줄에서 와 같은 디렉토리에 있는 foo.js모듈을 로드합니다 .circle.jsfoo.js
내용은 다음과 같습니다 circle.js.
const { PI } = Math;
exports.area = (r) => PI * r ** 2;
exports.circumference = (r) => 2 * PI * r; 복사
모듈이 circle.js함수 area()및 circumference(). 함수와 개체는 특수 개체에 추가 속성을 지정하여 모듈의 루트에 추가됩니다 exports.
모듈이 Node.js에 의해 함수로 래핑되기 때문에 모듈에 로컬인 변수는 비공개입니다( 모듈 래퍼 참조 ). 이 예에서 변수는 PI전용입니다 circle.js.
속성 module.exports에 새 값(예: 함수 또는 개체)을 할당할 수 있습니다.
아래에서는 Square 클래스를 내보내는 모듈을 bar.js사용합니다 .square
const Square = require('./square.js');
const mySquare = new Square(2);
console.log(`The area of mySquare is ${mySquare.area()}`); 복사
모듈 square은 다음에 정의됩니다 square.js.
// Assigning to exports will not modify module, must use module.exports
module.exports = class Square {
constructor(width) {
this.width = width;
}
area() {
return this.width ** 2;
}
}; 복사
CommonJS 모듈 시스템은 module코어 모듈 에서 구현됩니다 .
활성화#
Node.js에는 CommonJS 모듈과 ECMAScript 모듈의 두 가지 모듈 시스템이 있습니다 .
기본적으로 Node.js는 다음을 CommonJS 모듈로 취급합니다.
- .cjs확장자 가 있는 파일
- .js가장 가까운 상위 파일 에 값이 인 package.json최상위 필드가 포함된 경우 확장자가 있는 파일 ."type""commonjs"
- .js가장 가까운 상위 package.json파일에 최상위 필드가 포함되지 않은 경우 확장자가 있는 파일 "type". 패키지 작성자는 "type"모든 소스가 CommonJS인 패키지에도 필드를 포함해야 합니다. 패키지 에 대해 명시하면 type빌드 도구와 로더가 패키지의 파일을 해석하는 방법을 더 쉽게 결정할 수 있습니다.
- .mjs확장자가 , .cjs, .json, .node또는가 아닌 파일 .js (가장 가까운 상위 파일에 값이 있는 package.json최상위 필드가 포함된 경우 해당 파일은 를 통해 포함되는 경우에만 CommonJS 모듈로 인식되고 로 사용될 때는 인식되지 않음) 프로그램의 명령줄 진입점)."type""module"require()
자세한 내용은 모듈 시스템 결정을 참조하십시오 .
호출은 require()항상 CommonJS 모듈 로더를 사용합니다. 호출은 import() 항상 ECMAScript 모듈 로더를 사용합니다.
메인 모듈 접근#
파일이 Node.js에서 직접 실행될 때 require.main는 module. 즉, 테스트를 통해 파일이 직접 실행되었는지 여부를 확인할 수 있습니다 require.main === module.
파일의 경우 foo.js이것은 truevia를 통해 실행되는 경우 node foo.js이지만 falseby가 실행하는 경우 입니다 require('./foo').
진입점이 CommonJS 모듈이 아닌 경우 require.main이고 undefined메인 모듈이 도달할 수 없습니다.
패키지 관리자 팁
Node.js require()함수의 의미 체계는 합리적인 디렉터리 구조를 지원하기에 충분히 일반적이도록 설계되었습니다. dpkg, rpm및 와 같은 패키지 관리자 프로그램은 npm수정 없이 Node.js 모듈에서 기본 패키지를 빌드할 수 있기를 바랍니다.
아래에서 작동할 수 있는 제안된 디렉터리 구조를 제공합니다.
/usr/lib/node/<some-package>/<some-version>폴더 에 패키지의 특정 버전 내용을 보관하고 싶다고 가정해 보겠습니다 .
패키지는 서로 의존할 수 있습니다. 패키지를 설치하기 위해서는 foo특정 버전의 패키지를 설치해야 할 수도 있습니다 bar. 패키지 bar 자체에 종속성이 있을 수 있으며 경우에 따라 충돌하거나 순환 종속성을 형성할 수도 있습니다.
Node.js는 로드하는 모든 모듈을 조회한 다음 realpath(즉, symlink를 확인) 폴더 에서 해당 종속 항목을 조회하므로node_modules 다음 아키텍처로 이 상황을 해결할 수 있습니다.
- /usr/lib/node/foo/1.2.3/: 패키지 내용 foo, 버전 1.2.3.
- /usr/lib/node/bar/4.3.2/: 종속되는 bar패키지 의 내용입니다 foo.
- /usr/lib/node/foo/1.2.3/node_modules/bar: 에 대한 심볼릭 링크 /usr/lib/node/bar/4.3.2/.
- /usr/lib/node/bar/4.3.2/node_modules/*bar: 의존하는 패키지에 대한 심볼릭 링크 .
따라서 순환이 발생하거나 종속성 충돌이 있는 경우에도 모든 모듈은 사용할 수 있는 종속성의 버전을 가져올 수 있습니다.
패키지 의 코드가 foo수행되면 require('bar')에 심볼릭 링크된 버전을 가져옵니다 /usr/lib/node/foo/1.2.3/node_modules/bar. bar그런 다음 패키지 의 코드가 를 호출하면 에 require('quux')심볼릭 링크된 버전을 가져옵니다 /usr/lib/node/bar/4.3.2/node_modules/quux.
또한 모듈 조회 프로세스를 더욱 최적화하기 위해 패키지를 에 직접 넣지 않고 /usr/lib/node에 넣을 수 있습니다 /usr/lib/node_modules/<name>/<version>. /usr/node_modules그러면 Node.js는 또는 에서 누락된 종속성을 찾지 않습니다 /node_modules.
Node.js REPL에서 모듈을 사용할 수 있도록 하려면 /usr/lib/node_modules폴더를 환경 변수에 추가하는 것도 유용할 수 있습니다 $NODE_PATH. 폴더를 사용하는 모듈 조회는 node_modules모두 상대적이며 를 호출하는 파일의 실제 경로를 기반으로 하므로 require()패키지 자체는 어디에나 있을 수 있습니다.
확장 .mjs_
의 동기 특성으로 인해 require()ECMAScript 모듈 파일을 로드하는 데 사용할 수 없습니다. 이렇게 하면 ERR_REQUIRE_ESM오류가 발생합니다. 대신 사용 import()하십시오.
확장 은 를 통해 로드할 수 없는 ECMAScript 모듈.mjs 용으로 예약되어 있습니다 . ECMAScript 모듈로 구문 분석되는 파일에 대한 자세한 내용은 모듈 시스템 결정 섹션을 참조하세요 .require()