>  기사  >  웹 프론트엔드  >  Node의 모듈 메커니즘에 대해 자세히 알아보고 모듈 구현 프로세스에 대해 이야기해 보세요.

Node의 모듈 메커니즘에 대해 자세히 알아보고 모듈 구현 프로세스에 대해 이야기해 보세요.

青灯夜游
青灯夜游앞으로
2022-05-25 21:12:502052검색

이 글은 여러분에게 CommonJs 사양과 Node의 모듈 메커니즘을 이해하고, CommonJs 사양을 구현하는 Node의 기본 프로세스를 소개할 것입니다. 모두에게 도움이 되기를 바랍니다.

Node의 모듈 메커니즘에 대해 자세히 알아보고 모듈 구현 프로세스에 대해 이야기해 보세요.

CommonJs 사양이 제안되기 전에는 Javascript에 모듈 시스템이 없었기 때문에 코드 구성이 더 어려워지기 때문에 대규모 응용 프로그램을 개발하기가 어려웠습니다.

CommonJs 사양이란


먼저 CommonJS는 Node에만 있는 것이 아닙니다. CommonJs는 모듈을 참조하고 내보내는 방법을 정의하는 모듈 사양입니다. Nodejs는 CommonJS 모듈 사양을 크게 나누어서 구현한 것입니다. 모듈 참조, 모듈 정의 및 모듈 식별의 세 부분이 있습니다.

모듈 참조

모듈 참조는 require를 통해 다른 모듈을 도입할 수 있다는 의미입니다. require引入其它的模块。

const { add } = require('./add');
const result = add(1 ,2);

模块定义

一个文件就是一个模块,模块里会提供两个变量,分别为module和exports。module为当前模块本身,exports为要导出的内容,同时exports为module的一个属性,即exports为module.exports。其他模块通过require导入的内容即为module.exports的内容。

// add.js
exports.add = (a, b) => {
    return a + b;
}

模块标识

模块标识即为require里面的内容,比如require('./add'),则模块标识为./add

// 缓存的模块示意:
const cachedModule = {
    '/Usr/file/src/add.js': 'add.js编译后的内容',
    'http': 'Node自带的http模块编译后的内容',
    'express': '非路径形式自定义文件模块express编译后的内容'
    // ...
}

모듈 정의

파일은 모듈이며 모듈은 모듈과 내보내기라는 두 가지 변수를 제공합니다. module은 현재 모듈 자체이고,exports는 내보낼 콘텐츠이며,exports는 모듈의 속성입니다. 즉,exports는 module.exports입니다. require를 통해 다른 모듈에서 가져온 콘텐츠는 module.exports의 콘텐츠입니다.

/** 
* /Usr/file/index.js;
*/

const { add } = require('add');
const result = add(1, 2);


모듈 식별

  • 모듈 식별은 require('./add')와 같이 require의 콘텐츠이고, 모듈 식별은 ./add. <p></p>CommonJS를 통해 구축된 모듈 가져오기 및 내보내기 메커니즘을 통해 사용자는 다양한 오염을 고려하지 않고도 대규모 애플리케이션을 쉽게 구축할 수 있습니다.
  • Node의 모듈 구현
  • Node는 CommonJs 사양을 구현하고 필요한 일부 기능을 추가합니다. Node는 CommonJs 사양을 구현하기 위해 주로 다음 세 가지 작업을 수행합니다. ( ) 이때 require로 전달받은 파라미터는 모듈식별자이며, 노드는 모듈식별자를 이용하여 경로분석을 수행한다. 경로 분석의 목적은 모듈 식별자를 통해 이 모듈이 위치한 경로를 찾는 것입니다. 우선, 노드 모듈은 코어 모듈과 파일 모듈이라는 두 가지 범주로 나뉩니다. 코어 모듈은 노드와 함께 제공되는 모듈이고, 파일 모듈은 사용자가 작성한 모듈입니다. 동시에 파일 모듈은 상대 경로 형태의 파일 모듈, 절대 경로 형태의 파일 모듈, 비경로 형태의 파일 모듈(예: Express)로 구분됩니다.

노드가 파일 모듈을 찾으면 모듈을 컴파일, 실행 및 캐시합니다. 일반적인 원칙은 모듈의 전체 경로를 키로 사용하고 컴파일된 콘텐츠를 값으로 사용한 다음 모듈을 도입하는 것입니다. 두 번째로 이러한 단계의 경로 분석, 파일 위치, 컴파일 및 실행을 수행할 필요가 없습니다. 컴파일된 콘텐츠는 캐시에서 직접 읽을 수 있습니다.

/** 
* /Usr/file/index.js;
*/

console.log(module.paths);

require로 가져온 모듈을 찾으려면 먼저 모듈이 캐시에 있는지 확인하고, 캐시에 없으면 코어 모듈을 확인한 후 찾아보세요. 파일 모듈의 경우. 그 중에서 경로 형태의 파일 모듈은 상대 경로 또는 절대 경로를 기반으로 전체 파일 경로를 얻을 수 있기 때문에 더 쉽게 찾을 수 있습니다. 경로가 아닌 형식의 사용자 정의 파일 모듈을 찾는 것은 상대적으로 번거롭습니다. Node는 node_modules 폴더에서 파일을 검색합니다.

node_modules 디렉터리는 어디에 있나요? 예를 들어 현재 실행 중인 파일은 /Usr/file/index.js입니다.

[
&#39;/Usr/file/node_modules&#39;,
&#39;/Usr/node_modules&#39;,
&#39;/node_modules&#39;,
]
Node의 모듈 메커니즘에 대해 자세히 알아보고 모듈 구현 프로세스에 대해 이야기해 보세요.이 모듈에서는 추가 모듈을 도입했습니다. 이 추가는 핵심 모듈도 아니고 경로도 아닙니다. .파일 모듈을 양식에 추가한 다음 현재 이 추가 모듈을 찾는 방법입니다.

module에는 paths 속성이 있습니다. 추가 모듈을 찾는 경로는 paths 속성에 있습니다. 이 속성을 입력하면 다음을 확인할 수 있습니다.

const { add } = require(&#39;./add&#39;);

파일 디렉터리에서 node index.js를 실행하여 경로 값을 인쇄할 수 있습니다. . paths의 값은 다음과 같은 배열입니다.

// index.js
const { add } = require(&#39;./add&#39;);

즉, Node는 위 디렉터리에서 순차적으로 검색하여 추가 모듈이 포함되어 있는지 확인합니다. 원리는 프로토타입 체인과 유사합니다. 먼저, 현재 실행 중인 파일과 같은 계층의 node_modules 폴더에서 검색을 시작합니다. node_modules 디렉터리가 없거나 존재하지 않으면 상위 수준까지 검색을 계속합니다.

파일 위치 지정

파일 식별자는 접미사가 없을 수도 있고, 경로 분석을 통해 찾은 디렉터리나 패키지일 수도 있습니다. 특정 파일에는 몇 가지 추가 처리가 필요합니다.

파일 확장자 분석

const { add } = require(&#39;./add&#39;);

比如上面这段代码,文件标识符是不带扩展名的,这个时候node会依次查找是否存在.js、.json、.node文件。

目录和包分析

同样是上面这段代码,通过./add查找到的可能不是一个文件,可能是一个目录或者包(通过判断add文件夹下是否有package.json文件来判断是目录还是包)。这个时候文件定位的步骤是这样的:

  • 查看是否有package.json文件
      • 读取package.json里的main字段的值作为文件
    • 没有
      • 寻找目录下的index作为文件(依次查找index.js、index.json、index.node)

如果package.json里没有main字段,那么也会将index作为文件,然后进行扩展名分析找到对应后缀的文件。

模块编译

我们开发中主要遇到的模块为json模块和js模块。

json模块编译

当我们require一个json模块的时候,实际上Node会帮我们使用fs.readFilcSync去读取对应的json文件,得到json字符串,然后调用JSON.parse解析得到json对象,再赋值给module.exports,然后给到require。

js模块编译

当我们require一个js模块的时候,比如

// index.js
const { add } = require(&#39;./add&#39;);
// add.js
exports.add = (a, b) => {
    return a + b;
}

这个时候发生了什么呢,为什么我们可以直接在模块里使用module、exports、require这些变量。这是因为Node在编译js模块的时候对模块的内容进行了首尾的包装。

比如add.js这个模块,实际编译的时候是会被包装成类似这样的结构:

(function(require, exports, module) {
  exports.add = (a, b) => {
    return a + b;
  }
  return module.exports;
})(require, module.exports, module)

即我们编写的js文件是会被包装成一个函数,我们编写的只是这个函数里的内容,Node后续的包装的过程对我们隐藏了。这个函数支持传入一些参数,其中就包括require、exports和module。

当编译完js文件后,就会执行这个文件,node会将对应的参数传给这个函数然后执行,并且返回module.exports值给到require函数。

以上就是Node实现CommonJs规范的基本流程。

更多node相关知识,请访问:nodejs 教程

위 내용은 Node의 모듈 메커니즘에 대해 자세히 알아보고 모듈 구현 프로세스에 대해 이야기해 보세요.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제