CommonJs 사양이 제안되기 전에는 Javascript에 모듈 시스템이 없었기 때문에 코드 구성이 더 어려워지기 때문에 대규모 응용 프로그램을 개발하기가 어려웠습니다.
우선 CommonJS는 Node에만 있는 것이 아닙니다. CommonJS는 모듈을 참조하고 내보내는 방법을 정의하는 모듈 사양입니다. Nodejs는 이 사양만 구현합니다. CommonJS 모듈 사양은 주로 모듈 참조, 모듈 정의 및 모듈 식별의 세 부분으로 나뉩니다. .
모듈 참조
모듈 참조는 require
통해 다른 모듈을 도입할 수 있음을 의미합니다.
const { 추가 } = require('./add'); const result = add(1,2);
모듈은
파일을 모듈로 정의하며 모듈은 모듈과 내보내기라는 두 가지 변수를 제공합니다. module은 현재 모듈 자체이고,exports는 내보낼 콘텐츠이며,exports는 모듈의 속성입니다. 즉,exports는 module.exports입니다. require를 통해 다른 모듈에서 가져온 콘텐츠는 module.exports의 콘텐츠입니다.
// add.js 수출.추가 = (a, b) => { a + b를 반환합니다. }
모듈 식별
모듈 식별은 require의 내용입니다. 예를 들어 require('./add')
이면 모듈 식별은 ./add
입니다.
CommonJS를 통해 구축된 모듈 가져오기 및 내보내기 메커니즘을 통해 사용자는 다양한 오염을 고려하지 않고도 대규모 애플리케이션을 쉽게 구축할 수 있습니다.
노드 모듈 구현
Node는 CommonJs 사양을 구현하고 필요한 일부 기능을 추가합니다. Node는 CommonJs 사양을 구현하기 위해 주로 다음 세 가지 작업을 수행합니다.
경로 분석
컴파일
및
실행
require()가 실행되면 require로 전달되는 매개변수는 모듈 식별자이며, 노드는 모듈 식별자를 통해 경로 분석을 수행합니다. 경로 분석의 목적은 모듈 식별자를 통해 이 모듈이 위치한 경로를 찾는 것입니다. 우선, 노드 모듈은 코어 모듈과 파일 모듈이라는 두 가지 범주로 나뉩니다. 코어 모듈은 노드와 함께 제공되는 모듈이고, 파일 모듈은 사용자가 작성한 모듈입니다. 동시에 파일 모듈은 상대 경로 형태의 파일 모듈, 절대 경로 형태의 파일 모듈, 비경로 형태의 파일 모듈(예: Express)로 구분됩니다.
노드가 파일 모듈을 찾으면 모듈을 컴파일, 실행 및 캐시합니다. 일반적인 원칙은 모듈의 전체 경로를 키로 사용하고 컴파일된 콘텐츠를 값으로 사용하는 것입니다. 그런 다음 이러한 단계의 경로 분석, 파일 위치, 컴파일 및 실행을 수행합니다. 컴파일된 콘텐츠는 캐시에서 직접 읽을 수 있습니다.
//캐시 모듈 다이어그램: const 캐시모듈 = { '/Usr/file/src/add.js': 'add.js의 컴파일된 내용', 'http': 'Node와 함께 제공되는 http 모듈의 컴파일된 콘텐츠', 'express': '경로가 아닌 사용자 정의 파일 모듈 express의 컴파일된 콘텐츠' // ... }
require로 가져온 모듈을 찾으려면 모듈을 검색하는 순서로 먼저 해당 모듈이 캐시에 있는지 확인하고, 캐시에 없으면 코어 모듈을 확인한 후 찾습니다. 파일 모듈. 그 중에서 경로 형태의 파일 모듈은 상대 경로나 절대 경로를 기반으로 전체 파일 경로를 얻을 수 있어 찾기가 더 쉽습니다. 경로가 아닌 형식의 사용자 정의 파일 모듈을 찾는 것은 상대적으로 번거롭습니다. Node는 node_modules 폴더에서 파일을 검색합니다.
node_modules 디렉터리는 어디에 있나요? 예를 들어 현재 실행 중인 파일은 /Usr/file/index.js입니다
. * /Usr/file/index.js; */ const { 추가 } = require('추가'); const result = add(1, 2);
이 모듈에서는 add 모듈을 소개했는데, 이 add는 핵심 모듈도 아니고 경로 형태의 파일 모듈도 아닙니다.
모듈에는 경로 속성이 있습니다. 추가 모듈을 찾는 경로는 경로 속성에 있습니다.
/** * /Usr/file/index.js; */ console.log(module.paths);
파일 디렉터리에서 node index.js를 실행하여 경로 값을 출력할 수 있습니다. paths의 값은 다음과 같은 배열입니다
. '/Usr/파일/노드_모듈', '/Usr/node_modules', '/노드_모듈', ]
즉, Node는 위 디렉터리부터 순차적으로 검색하여 추가 모듈이 포함되어 있는지 확인합니다. 원리는 프로토타입 체인과 유사합니다. 먼저, 현재 실행 중인 파일과 같은 계층의 node_modules 폴더에서 검색을 시작합니다. node_modules 디렉터리가 없거나 존재하지 않으면 상위 수준까지 검색을 계속합니다.
파일 위치
경로 분석과 파일 위치는 접미사 없이 파일 식별자를 사용하거나 경로 분석을 통해 디렉터리나 패키지를 찾을 수 있습니다.
파일 확장자 분석
const { add } = require('./add');
예를 들어 위 코드에서 파일 식별자에는 확장자가 없습니다. 이때 노드는 .js, .json이 있는지 검색합니다. , 및 .node가 차례로 문서에 표시됩니다.
디렉토리 및 패키지 분석은
위의 코드와 동일합니다. ./add
통해 알아낸 것은 파일이 아닐 수도 있지만 디렉토리나 패키지일 수도 있습니다(패키지가 있는지 판단하여 디렉토리인지 패키지인지 판단합니다. add 폴더에 json 파일이 있음). 이때 파일 위치 지정 단계는 다음과 같습니다.
package.json에 기본 필드가 없으면 index도 파일로 사용되며 확장 분석을 수행하여 해당 접미사가 붙은 파일을 찾습니다. .
모듈 컴파일
개발 중에 만나는 주요 모듈은 json 모듈과 js 모듈입니다.
json 모듈 컴파일
json 모듈이 필요할 때 Node는 실제로 fs.readFilcSync를 사용하여 해당 json 파일을 읽고, json 문자열을 가져온 다음 JSON.parse를 호출하여 json 객체를 가져오고 이를 할당하도록 도와줍니다. 모듈을 내보낸 다음 require로 제공합니다.
js 모듈 컴파일
// index.js
와 같은 js 모듈이 필요한 경우
const { add } = require('./add');
// add.js 수출.추가 = (a, b) => { a + b를 반환합니다. }
이때 무슨 일이 일어났나요? 모듈에서 직접 변수 모듈, 내보내기, 요구 사항을 사용할 수 있는 이유는 무엇입니까? 이는 Node가 js 모듈을 컴파일할 때 모듈의 내용을 처음과 마지막으로 래핑하기 때문입니다.
예를 들어 add.js 모듈은 실제로 컴파일될 때 다음과유사한
구조로 패키징됩니다.
수출.추가 = (a, b) => { a + b를 반환합니다. } module.exports를 반환합니다. })(require, module.exports, module)
즉, 우리가 작성하는 js 파일은 함수로 패키징됩니다. 우리가 작성하는 것은 이 함수의 내용일 뿐이며 Node의 후속 패키징 프로세스는 우리에게 숨겨집니다. 이 함수는 필수, 내보내기 및 모듈을 포함한 일부 매개변수 전달을 지원합니다.
js 파일이 컴파일된 후 파일이 실행됩니다. Node는 해당 매개변수를 이 함수에 전달한 후 실행하고 module.exports 값을 require 함수에 반환합니다.
위는 Node가 CommonJs 사양을 구현하는 기본 프로세스입니다.