찾다
웹 프론트엔드JS 튜토리얼Node.js에서 require() 메서드가 어떻게 작동하는지 살펴보세요.

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

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

module.jsfunction Module(id, parent) {
  this.id = id;
  this.exports = {};
  this.parent = parent;
  // ...

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

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

Module._load

Module._load = function(request, parent, isMain) {
  // 1. Check Module._cache for the cached module. 
  // 2. Create a new Module instance if cache is empty.
  // 3. Save it to the cache.
  // 4. Call module.load() with your the given filename.
  //    This will call module.compile() after reading the file contents.
  // 5. If there was an error loading/parsing the file, 
  //    delete the bad module from the cache
  // 6. return module.exports
};

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

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

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

module._compile

Module.prototype._compile = function(content, filename) {  // 1. Create the standalone require function that calls module.require.  // 2. Attach other helper methods to require.  // 3. Wraps the JS code in a function that provides our require,  //    module, etc. variables locally to the module scope.  // 4. Run that function};

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

· require(): 외부 모듈 로드
· require.resolve(): 해결 절대 경로에 대한 모듈 이름
· require.main: 메인 모듈
· require.cache: 캐시된 모든 모듈
· require.extensions: 확장자에 따라 각 유효한 파일 형식에 사용할 수 있는 컴파일 방법
한 번 require가 준비되면 로드된 전체 소스 코드는 require, 모듈, 내보내기 및 기타 노출된 모든 변수를 매개변수로 받아들일 수 있는 새로운 함수로 캡슐화됩니다. Node.js 환경과의 충돌을 방지하기 위해 모듈을 캡슐화하기 위해서만 만들어진 기능입니다.

(function (exports, require, module, __filename, __dirname) {
  // YOUR CODE INJECTED HERE!
});

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

결론

그래서 우리는 require의 전체 코드를 보았고 그것이 어떻게 작동하는지에 대한 사전 이해를 가졌습니다.

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

자세한 내용을 알고 싶으시면 module.js 소스코드를 직접 확인해보세요. 한동안 머리를 아프게 할 일들이 충분히 있습니다. NODE_MODULE_CONTEXTS가 무엇인지, 왜 추가되었는지 먼저 알려주는 사람이 보너스 포인트를 받게 됩니다. :)

[1] module._compile 메소드는 JavaScript 파일을 실행하는 데만 사용되며 JSON.parse( ) 및

[2]을 반환합니다. 그러나 두 모듈 모두 Module._resolveLookupPaths 및 Module._findPath와 같은 비공개 모듈 메서드를 기반으로 구축되었습니다. 이는 그다지 좋지 않다고 생각할 수 있습니다...

几乎所有的Node.js开发人员可以告诉你require()函数做什么,但我们又有多少人真正知道它是如何工作的?我们每天都使用它来加载库和模块,但它的行为,对于我们来说反而是一个谜。

出于好奇,我钻研了node的核心代码来找出在引擎下发生了什么事。但这并不是一个单一的功能,我在node的模块系统的找到了module.js。该文件包含一个令人惊讶的强大的且相对陌生的核心模块,控制每个文件的加载,编译和缓存。require() 它的横空出世,只是冰山的一角。

module.jsfunction Module(id, parent) {
  this.id = id;
  this.exports = {};
  this.parent = parent;
  // ...

在module.js在Node.js内部主要承担两个角色。首先,它为所有的Node.js模块提供了一个基础。每个文件是基本模块new出的一个新实例,即使在该文件已经运行之后,仍然存在。这就是为什么我们能够性为module.exports附加属并在需要时返回它们。

该模块的第二大任务是处理node的模块加载机制。我们使用的独立操作的“require”函数实际上是一个抽象概念的module.require,这本身就是只是一个简单的关于Module._load功能的封装。此load方法处理每个文件的实际加载,并在那里开始我们的旅程。

Module._load

Module._load = function(request, parent, isMain) {
  // 1. Check Module._cache for the cached module. 
  // 2. Create a new Module instance if cache is empty.
  // 3. Save it to the cache.
  // 4. Call module.load() with your the given filename.
  //    This will call module.compile() after reading the file contents.
  // 5. If there was an error loading/parsing the file, 
  //    delete the bad module from the cache
  // 6. return module.exports
};

Module._load负责加载新的模块和管理模块的缓存。缓存加载的每个模块减少冗余文件的读取次数,并可以显著地加快您应用程序的速度。此外,共享模块实例允许单例特性的模块,保持在项目中的状态。

如果某个模块没有在缓存中存在,Module._load将创建该文件的一个新的基本模块。然后,它会告诉模块在将它们发送到module._compile之前阅读新文件的内容。[1]

如果您注意到上面的步骤#6,你会看到module.exports已被返回给用户。这就是为什么当你在定义公共接口使用时,你使用exports和module.exports,因为Module._load将接下来返回require的内容。我很惊讶,这里没有更多的功能,但如果有的话那更好。

module._compile

Module.prototype._compile = function(content, filename) {  // 1. Create the standalone require function that calls module.require.  // 2. Attach other helper methods to require.  // 3. Wraps the JS code in a function that provides our require,  //    module, etc. variables locally to the module scope.  // 4. Run that function};

这是真正的奇迹发生的地方。首先,一个特殊的独立操作的require函数是为该模块创建的。这是我们需要的并且都熟悉的功能。而函数本身只是一个在Module.require的封装,它也包含了一些便于我们使用的鲜为人知的辅助方法:

· require():加载一个外部模块  
· require.resolve():解析一个模块名到它的绝对路径  
· require.main:主模块  
· require.cache:所有缓存好的模块
· require.extensions:根据其扩展名,对于每个有效的文件类型可使用的编制方法
一旦require准备好了,整个加载的源代码就会被封装在一个新的函数里,可以接受require,module,exports和所有其他暴露的变量作为参数。这是一个仅仅为封装模块的而创建的函数,以便于在防止与Node.js的环境产生冲突。

(function (exports, require, module, __filename, __dirname) {
  // YOUR CODE INJECTED HERE!
});

该Module._compile方法是同步执行的,所以对Module._load的调用只能等到这段代码运行结束,并将module.exprts返回给用户。

结论

因此,我们已经了解了require的全部代码,并已经初步了解它是如何工作的。

如果你已经按照这一切的方式做了,那么你已经为最后的秘密做好准备:require(‘module’)。这是正确的,该模块系统本身可以通过模块系统被加载。盗梦空间。这可能听起来很奇怪,但它可以让用户空间同模块加载系统互动起来,并不需要钻研Node.js核心。受欢迎的模块都像这样被建立。[2]

如果您想了解更多,请自己查看module.js源代码。还有很多东西足够你头痛一段时间了。第一个可以告诉我什么是NODE_MODULE_CONTEXTS“以及它为什么被添加的人可以得到加分奖励 :)

[1] module._compile方法只用于运行JavaScript文件。 JSON文件需通过JSON.parse() 解析并返回

[2]然而,这两个模块都建立在私有模块的方法,如Module._resolveLookupPaths和Module._findPath。你可以认为这并没有好多了…

위 내용은 Node.js에서 require() 메서드가 어떻게 작동하는지 살펴보세요.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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

개발 환경에서 Python과 JavaScript의 선택이 모두 중요합니다. 1) Python의 개발 환경에는 Pycharm, Jupyternotebook 및 Anaconda가 포함되어 있으며 데이터 과학 및 빠른 프로토 타이핑에 적합합니다. 2) JavaScript의 개발 환경에는 Node.js, VScode 및 Webpack이 포함되어 있으며 프론트 엔드 및 백엔드 개발에 적합합니다. 프로젝트 요구에 따라 올바른 도구를 선택하면 개발 효율성과 프로젝트 성공률이 향상 될 수 있습니다.

JavaScript가 C로 작성 되었습니까? 증거를 검토합니다JavaScript가 C로 작성 되었습니까? 증거를 검토합니다Apr 25, 2025 am 12:15 AM

예, JavaScript의 엔진 코어는 C로 작성되었습니다. 1) C 언어는 효율적인 성능과 기본 제어를 제공하며, 이는 JavaScript 엔진 개발에 적합합니다. 2) V8 엔진을 예를 들어, 핵심은 C로 작성되며 C의 효율성 및 객체 지향적 특성을 결합하여 C로 작성됩니다.

JavaScript의 역할 : 웹 대화식 및 역동적 인 웹JavaScript의 역할 : 웹 대화식 및 역동적 인 웹Apr 24, 2025 am 12:12 AM

JavaScript는 웹 페이지의 상호 작용과 역학을 향상시키기 때문에 현대 웹 사이트의 핵심입니다. 1) 페이지를 새로 고치지 않고 콘텐츠를 변경할 수 있습니다. 2) Domapi를 통해 웹 페이지 조작, 3) 애니메이션 및 드래그 앤 드롭과 같은 복잡한 대화식 효과를 지원합니다. 4) 성능 및 모범 사례를 최적화하여 사용자 경험을 향상시킵니다.

C 및 JavaScript : 연결이 설명되었습니다C 및 JavaScript : 연결이 설명되었습니다Apr 23, 2025 am 12:07 AM

C 및 JavaScript는 WebAssembly를 통한 상호 운용성을 달성합니다. 1) C 코드는 WebAssembly 모듈로 컴파일되어 컴퓨팅 전력을 향상시키기 위해 JavaScript 환경에 도입됩니다. 2) 게임 개발에서 C는 물리 엔진 및 그래픽 렌더링을 처리하며 JavaScript는 게임 로직 및 사용자 인터페이스를 담당합니다.

웹 사이트에서 앱으로 : 다양한 JavaScript 애플리케이션웹 사이트에서 앱으로 : 다양한 JavaScript 애플리케이션Apr 22, 2025 am 12:02 AM

JavaScript는 웹 사이트, 모바일 응용 프로그램, 데스크탑 응용 프로그램 및 서버 측 프로그래밍에서 널리 사용됩니다. 1) 웹 사이트 개발에서 JavaScript는 HTML 및 CSS와 함께 DOM을 운영하여 동적 효과를 달성하고 jQuery 및 React와 같은 프레임 워크를 지원합니다. 2) 반응 및 이온 성을 통해 JavaScript는 크로스 플랫폼 모바일 애플리케이션을 개발하는 데 사용됩니다. 3) 전자 프레임 워크를 사용하면 JavaScript가 데스크탑 애플리케이션을 구축 할 수 있습니다. 4) node.js는 JavaScript가 서버 측에서 실행되도록하고 동시 요청이 높은 높은 요청을 지원합니다.

Python vs. JavaScript : 사용 사례 및 응용 프로그램 비교Python vs. JavaScript : 사용 사례 및 응용 프로그램 비교Apr 21, 2025 am 12:01 AM

Python은 데이터 과학 및 자동화에 더 적합한 반면 JavaScript는 프론트 엔드 및 풀 스택 개발에 더 적합합니다. 1. Python은 데이터 처리 및 모델링을 위해 Numpy 및 Pandas와 같은 라이브러리를 사용하여 데이터 과학 및 기계 학습에서 잘 수행됩니다. 2. 파이썬은 간결하고 자동화 및 스크립팅이 효율적입니다. 3. JavaScript는 프론트 엔드 개발에 없어서는 안될 것이며 동적 웹 페이지 및 단일 페이지 응용 프로그램을 구축하는 데 사용됩니다. 4. JavaScript는 Node.js를 통해 백엔드 개발에 역할을하며 전체 스택 개발을 지원합니다.

JavaScript 통역사 및 컴파일러에서 C/C의 역할JavaScript 통역사 및 컴파일러에서 C/C의 역할Apr 20, 2025 am 12:01 AM

C와 C는 주로 통역사와 JIT 컴파일러를 구현하는 데 사용되는 JavaScript 엔진에서 중요한 역할을합니다. 1) C는 JavaScript 소스 코드를 구문 분석하고 추상 구문 트리를 생성하는 데 사용됩니다. 2) C는 바이트 코드 생성 및 실행을 담당합니다. 3) C는 JIT 컴파일러를 구현하고 런타임에 핫스팟 코드를 최적화하고 컴파일하며 JavaScript의 실행 효율을 크게 향상시킵니다.

자바 스크립트 행동 : 실제 예제 및 프로젝트자바 스크립트 행동 : 실제 예제 및 프로젝트Apr 19, 2025 am 12:13 AM

실제 세계에서 JavaScript의 응용 프로그램에는 프론트 엔드 및 백엔드 개발이 포함됩니다. 1) DOM 운영 및 이벤트 처리와 관련된 TODO 목록 응용 프로그램을 구축하여 프론트 엔드 애플리케이션을 표시합니다. 2) Node.js를 통해 RESTFULAPI를 구축하고 Express를 통해 백엔드 응용 프로그램을 시연하십시오.

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

에디트플러스 중국어 크랙 버전

에디트플러스 중국어 크랙 버전

작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음

Atom Editor Mac 버전 다운로드

Atom Editor Mac 버전 다운로드

가장 인기 있는 오픈 소스 편집기

MinGW - Windows용 미니멀리스트 GNU

MinGW - Windows용 미니멀리스트 GNU

이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SecList

SecList

SecLists는 최고의 보안 테스터의 동반자입니다. 보안 평가 시 자주 사용되는 다양한 유형의 목록을 한 곳에 모아 놓은 것입니다. SecLists는 보안 테스터에게 필요할 수 있는 모든 목록을 편리하게 제공하여 보안 테스트를 더욱 효율적이고 생산적으로 만드는 데 도움이 됩니다. 목록 유형에는 사용자 이름, 비밀번호, URL, 퍼징 페이로드, 민감한 데이터 패턴, 웹 셸 등이 포함됩니다. 테스터는 이 저장소를 새로운 테스트 시스템으로 간단히 가져올 수 있으며 필요한 모든 유형의 목록에 액세스할 수 있습니다.