>  기사  >  웹 프론트엔드  >  Node.js_node.js의 require 작동 원리에 대한 간략한 분석

Node.js_node.js의 require 작동 원리에 대한 간략한 분석

WBOY
WBOY원래의
2016-05-16 16:43:121362검색

거의 모든 Node.js 개발자가 require() 함수의 기능을 알려줄 수 있지만 실제로 작동 방식을 아는 사람은 몇 명이나 될까요? 우리는 라이브러리와 모듈을 로드하기 위해 매일 이를 사용하지만 그 동작은 우리에게 미스터리입니다.

호기심에서 내부적으로 무슨 일이 벌어지고 있는지 알아보기 위해 node의 핵심 코드를 파헤쳐봤습니다. 하지만 이것은 단일 기능이 아닙니다. node의 모듈 시스템에서 module.js를 찾았습니다. 이 파일에는 각 파일의 로드, 컴파일 및 캐싱을 제어하는 ​​놀랍도록 강력하고 상대적으로 익숙하지 않은 핵심 모듈이 포함되어 있습니다. `require()`의 출현은 빙산의 일각에 불과합니다.

module.js

코드 복사 코드는 다음과 같습니다.

함수 모듈(id, parent) {
this.id = id;
this.exports = {};
This.parent = 부모;
// ...

Module.js는 Node.js 내에서 주로 두 가지 역할을 합니다. 첫째, 모든 Node.js 모듈의 기초를 제공합니다. 각 파일은 파일이 실행된 후에도 지속되는 기본 모듈의 새 인스턴스입니다. 이것이 바로 우리가 module.exports에 속성을 첨부하고 필요할 때 이를 반환할 수 있는 이유입니다.

이 모듈의 두 번째 주요 작업은 노드의 모듈 로딩 메커니즘을 처리하는 것입니다. 우리가 사용하는 독립적인 작업 "require" 함수는 실제로 module.require의 추상 개념이며, 그 자체는 단지 Module._load 함수의 간단한 캡슐화일 뿐입니다. 이 로드 메소드는 각 파일의 실제 로드를 처리하고 그곳에서 여정을 시작합니다.

모듈._로드

코드 복사 코드는 다음과 같습니다.

Module._load = 함수(요청, 상위, isMain) {
// 1. 캐시된 모듈이 있는지 Module._cache를 확인하세요.
// 2. 캐시가 비어 있으면 새 모듈 인스턴스를 생성합니다.
// 3. 캐시에 저장합니다.
// 4. 주어진 파일 이름으로 module.load()를 호출합니다.
// 파일 내용을 읽은 후 module.compile()을 호출합니다.
// 5. 파일 로딩/파싱에 오류가 발생한 경우
// 캐시에서 잘못된 모듈을 삭제합니다
// 6. module.exports 반환
};

Module._load는 새 모듈을 로드하고 모듈 캐시를 관리하는 역할을 담당합니다. 로드된 각 모듈을 캐싱하면 중복된 파일 읽기 수가 줄어들고 애플리케이션 속도가 크게 향상될 수 있습니다. 또한 공유 모듈 인스턴스를 사용하면 모듈의 싱글톤 기능을 프로젝트 상태로 유지할 수 있습니다.

캐시에 모듈이 없으면 Module._load는 해당 파일의 새 기본 모듈을 생성합니다. 그런 다음 새 파일의 내용을 module._compile로 보내기 전에 읽도록 ​​모듈에 지시합니다. [1]

위의 6단계를 확인하면 module.exports가 사용자에게 반환된 것을 볼 수 있습니다. 이것이 사용할 공용 인터페이스를 정의할 때 내보내기 및 module.exports를 사용하는 이유입니다. 그 이유는 Module._load가 다음에 필요한 콘텐츠를 반환하기 때문입니다. 여기에 더 많은 기능이 없다는 것에 놀랐습니다. 그러나 있었다면 좋을 것입니다.

module._compile

코드 복사 코드는 다음과 같습니다.

Module.prototype._compile = 함수(내용, 파일명) {
// 1. module.require를 호출하는 독립형 require 함수를 생성합니다.
// 2. require에 다른 도우미 메서드를 연결합니다.
// 3. 요구사항을 제공하는 함수에 JS 코드를 래핑합니다.
// 모듈 등의 변수를 모듈 범위에 로컬로 지정합니다.
// 4. 해당 함수 실행
};

· 여기가 진짜 마법이 일어나는 곳입니다. 먼저, 이 모듈에 대해 특별한 독립형 require 함수가 생성됩니다. 이는 우리 모두에게 필요하고 친숙한 기능입니다. 함수 자체는 단지 Module.require의 패키지일 뿐이며 사용하기 쉬운 잘 알려지지 않은 몇 가지 보조 메서드도 포함되어 있습니다.

· require(): 외부 모듈 로드
· require.resolve(): 모듈 이름을 절대 경로로 확인합니다.
· require.main:메인 모듈
· require.cache: 캐시된 모든 모듈
· ·require.extensions: 확장자에 따라 유효한 각 파일 유형에 대해 사용 가능한 컴파일 방법

require가 준비되면 로드된 전체 소스 코드는 require, 모듈, 내보내기 및 기타 모든 노출된 변수를 매개변수로 받아들일 수 있는 새로운 함수로 캡슐화됩니다. Node.js 환경과의 충돌을 방지하기 위해 모듈을 캡슐화하기 위해서만 만들어진 기능입니다.

코드 복사 코드는 다음과 같습니다.

(함수(내보내기, 요구, 모듈, __filename, __dirname) {
// 여기에 코드가 삽입되었습니다!
});

Module._compile 메서드는 동기식으로 실행되므로 Module._load에 대한 호출은 이 코드가 끝날 때까지만 기다렸다가 module.exprts를 사용자에게 반환할 수 있습니다.

결론

그래서 우리는 require의 전체 코드를 이해했고 그것이 어떻게 작동하는지 미리 이해했습니다.

이 모든 내용을 따랐다면 마지막 비밀인 require('모듈')을 사용할 준비가 된 것입니다. 맞습니다. 모듈 시스템 자체는 모듈 시스템을 통해서 로딩이 가능합니다. 처음. 이상하게 들릴 수도 있지만 이를 통해 사용자 공간은 Node.js 코어를 자세히 조사하지 않고도 모듈 로딩 시스템과 상호 작용할 수 있습니다. 인기 있는 모듈은 이렇게 만들어졌습니다. [2]

자세한 내용은 module.js 소스코드를 직접 확인해보세요. 한동안 머리를 아프게 할 일들이 충분히 있습니다. 첫 번째 사람은 NODE_MODULE_CONTEXTS"가 무엇인지, 왜 추가되었는지, 추가하는 사람은 보너스 포인트를 얻을 수 있는지 알려줄 수 있나요?

[1] module._compile 메소드는 JavaScript 파일을 실행하는 데에만 사용됩니다. JSON 파일은 JSON.parse()를 통해 구문 분석하고 반환해야 합니다.

[2] 그러나 두 모듈 모두 Module._resolveLookupPaths 및 Module._findPath와 같은 비공개 모듈 메서드를 기반으로 구축되었습니다. 별로 좋지 않다고 생각하시면 됩니다...

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.