목차
CommonJS概述
CommonJS的模块规范
Node的模块实现
CommonJS 개요
CommonJS의 모듈 사양
Node의 모듈 구현
使用ES-Module
总结
요약
웹 프론트엔드 JS 튜토리얼 CommonJS 모듈 사양은 무엇입니까? Nodejs 모듈 메커니즘에 대한 간략한 분석

CommonJS 모듈 사양은 무엇입니까? Nodejs 모듈 메커니즘에 대한 간략한 분석

Aug 16, 2021 am 10:12 AM
nodejs

CommonJS 모듈 사양은 무엇입니까? Nodejs 모듈 메커니즘에 대한 간략한 분석

Node 애플리케이션은 모듈로 구성됩니다. 모듈 시스템은 CommonJS 모듈 사양을 따르지만 사양에 따라 완전히 구현되지는 않지만 일부를 추가합니다. 자체 필요에 따른 기능을 제공하며 CommonJS 모듈 사양의 변형으로 간주됩니다. Node应用由模块组成,其模块系统借鉴了CommonJS模块规范,但是并未完全按照规范实现,而是根据自身需求增加了一些特性,算是CommonJS模块规范的一个变种。

CommonJS概述

CommonJS是社区提出的一种JavaScript模块化规范,可以说是JS模块化历程中最重要的一块里程碑,它构造了一个美好的愿景——JS能够在任何地方运行,但其实由于它的模块是同步加载的,只适合在服务端等其他本地环境,并不适合浏览器端等需要异步加载资源的地方。

为了能让JS能够在任何地方运行,CommonJS制定了一些接口规范,这些接口覆盖了模块、二进制、Buffer、字符集编码、I/O流、进程环境、文件系统、socket、单元测试、web服务器、网关、包管理等等,虽然大部分都处于草案阶段,但是其深深影响了Node的发展。

下图表示了Node与浏览器、W3CCommonJS以及ECMAScript之间的关系,摘自 《深入浅出NodeJS》

CommonJS 모듈 사양은 무엇입니까? Nodejs 모듈 메커니즘에 대한 간략한 분석

CommonJS的模块规范

CommonJS的模块主要由模块引用模块定义模块标识三部分组成。

模块标识

模块标识对于每个模块来说是唯一的,是它被引用时的依据,它必须是符合小驼峰命名的字符串,或者是文件的相对路径或绝对路径。

require('fs')// fs是内建模块,执行时会被直接载入内存,无须路径标识
require('./moduleA')//导入当前目录的moduleA
require('../moduleB')// 导入上一个目录的moduleB
require('C://moduleC')// 绝对路径导入moduleC
로그인 후 복사

模块引用

使用require()来引用一个模块,这个方法接受一个模块标识作为参数,以此引入一个模块的API到当前上下文中。

const fs = require('fs')// 引入内建的fs模块
로그인 후 복사

模块定义

有导入自然也有导出,要将当前上下文中的方法或变量作为模块导出,需要使用内建的module.exports对象,它是模块导出的唯一出口。

CommonJS规范规定,每个模块内部,module变量代表当前模块。这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。加载某个模块,其实是加载该模块的module.exports属性。

// moduleA.js模块
let moduleA = {
    name:"moduleA"
}
module.exports = {
    moduleA
}

// moduleB.js模块
// 导入moduleA
const {moduleA} = require('./moduleA')
로그인 후 복사

CommonJS模块的特点如下:

  • 每个模块具有独立的上下文,模块内的代码独立执行,不会污染全局作用域。
  • 模块可以被多次加载,但是只会在第一次加载时运行,运行结果会被缓存,后续再加载相同模块会直接读取缓存结果,缓存存储在module.cache
  • 模块的加载按代码顺序执行。

Node的模块实现

Node导入模块需要经历3个步骤:路径分析 -> 文件定位 -> 编译执行:

  • 路径分析:根据模块标识分析模块类型。

  • 文件定位:根据模块类型和模块标识符找到模块所处位置。

  • 编译执行:将文件编译成机器码执行,中间需要经过一系列转化。

【推荐学习:《nodejs 教程》】

模块类型分为内建模块和用户模块:

  • 内建模块:内建模块由Node提供,已经被编译成二进制执行文件,在node执行时,内建模块会被直接载入内存,因此我们可以直接引入,它的加载速度很快,因为它不需要经过文件定位和编译执行这2个步骤。

  • 文件模块:使用jsC++等编写的扩展模块,执行时需要先被编译成二进制机器码。需要经过上述三大步骤。

模块缓存

不管是内建模块还是文件模块,node

CommonJS 개요

CommonJS는 커뮤니티에서 제안한 JavaScript 모듈입니다. 표준화는 JS의 모듈화 프로세스에서 가장 중요한 이정표라고 할 수 있습니다. 이는 아름다운 비전을 구성합니다. JS는 어디에서나 실행될 수 있지만 실제로는 모듈이 로드되어 있기 때문입니다. 동기식이며 서버 측과 같은 다른 로컬 환경에만 적합하며 리소스를 비동기식으로 로드해야 하는 브라우저 및 기타 장소에는 적합하지 않습니다. 🎜🎜JS가 어디서나 실행될 수 있도록 CommonJS는 모듈, 바이너리, 버퍼, 문자 집합 인코딩을 포함하는 몇 가지 인터페이스 사양을 공식화했습니다. , I/O 스트림, 프로세스 환경, 파일 시스템, 소켓, 단위 테스트, 웹 서버, 게이트웨이, 패키지 관리 등. 대부분이 초안 단계에 있습니다. 이지만 Node 개발에 큰 영향을 미쳤습니다. 🎜🎜다음 그림은 Node와 브라우저, W3C, CommonJSECMAScript 사이의 관계를 보여줍니다. "NodeJS에 대한 심층 설명"🎜🎜1 .png🎜

CommonJS의 모듈 사양

🎜CommonJS의 모듈은 주로 < Strong>모듈, 모듈 정의모듈 ID. 🎜🎜모듈 ID🎜🎜모듈 ID는 각 모듈마다 고유하며 참조되는 기반이 되어야 합니다. camelCase 문자열이거나 파일에 대한 상대 또는 절대 경로여야 합니다. 🎜
// package.json
{ 
    "name": "esm-project", 
    "version": "1.0.0", 
    "main": "index.js", 
    "type": "module", 
    ... 
}
로그인 후 복사
로그인 후 복사
🎜모듈 참조🎜🎜모듈을 참조하려면 require()를 사용하세요. 모듈 식별자가 인수로 전달되어 모듈의 API를 현재 컨텍스트에 도입합니다. 🎜rrreee🎜모듈 정의🎜🎜현재 컨텍스트의 메서드나 변수를 모듈로 내보내려면 가져오기와 내보내기가 있습니다. 모듈에서 내보낸 유일한 내보내기인 내장 module.exports 개체를 사용해야 합니다. 🎜🎜CommonJS 사양에서는 각 모듈 내부에서 module 변수가 현재 모듈을 나타냅니다. 이 변수는 개체이며 해당 exports 속성(예: module.exports)은 외부 인터페이스입니다. 모듈을 로드하면 실제로 모듈의 module.exports 속성이 로드됩니다. 🎜rrreee🎜CommonJS 모듈의 특징은 다음과 같습니다. 🎜
  • 각 모듈은 독립적인 컨텍스트를 가지며, 모듈 내의 코드는 전역 범위를 오염시키지 않고 독립적으로 실행됩니다.
  • 모듈은 여러 번 로드될 수 있지만 처음 로드될 때만 실행됩니다. 이후에 동일한 모듈을 로드하면 캐시된 결과가 직접 읽혀집니다. module .cache에 저장됩니다.
  • 모듈은 코드 순서대로 로드됩니다.

Node의 모듈 구현

🎜Node 가져오기 모듈을 거쳐야 합니다. 3 단계: 경로 분석 -> 파일 위치 -> 컴파일 및 실행:🎜
  • 🎜경로 분석: 모듈 식별에 따라 모듈 유형을 분석합니다. 🎜
  • 🎜파일 위치: 모듈 유형 및 모듈 식별자를 기반으로 모듈 위치를 찾습니다. 🎜
  • 🎜컴파일 및 실행: 일련의 변환이 필요한 실행을 위해 파일을 기계어 코드로 컴파일합니다. 🎜
🎜【추천 학습: " nodejs 튜토리얼》】🎜🎜모듈 유형은 내장 모듈과 사용자 모듈로 구분됩니다:🎜
  • 🎜내장 모듈: 내장- 모듈은 <코드에서 제공하는>노드로 구성되어 있으며, 바이너리 실행 파일로 컴파일되었습니다. 노드가 실행되면 내장 모듈이 메모리에 직접 로드됩니다. , 그래서 우리가 직접 소개할 수 있습니다. 이 2 단계를 수행하기 위해 파일 위치와 컴파일을 거칠 필요가 없기 때문에 로딩 속도가 매우 빠릅니다. 🎜
  • 🎜파일 모듈: js 또는 C++를 사용하여 작성된 확장 모듈은 실행 시 먼저 바이너리 기계어 코드로 컴파일되어야 합니다. 위의 3단계를 거쳐야 합니다. 🎜
🎜모듈 캐시🎜🎜내장 모듈인지 파일 모듈인지 , 노드는 첫 번째 로드 후 결과를 캐시합니다. 다음에 동일한 모듈이 로드되면 캐시에서 먼저 검색됩니다. 발견되면 캐시에서 직접 읽습니다. 캐시된 결과는 모듈 컴파일이며, 실행된 개체는 모든 모듈 중에서 가장 빠르게 로드됩니다. 🎜

路径分析

路径分析依据的是模块标识符,模块标识符有以下几种类型:

  • 内建模块标识,例如fspath等,不需要编译,node运行时被直接载入内存等待导入。
  • 相对路径模块标识:使用相对路径描述的文件模块
  • 绝对路径模块标识:使用绝对路径描述的文件模块
  • 自定义模块标识:通常是node_modules中的包,引入时也不需要写路径描述,node有一套算法来寻找,是所有模块标识中分析速度最慢的。

文件定位

文件定位主要包括文件扩展名分析、目录和包的处理。如果文件定位结束时都没找到任何文件,则会抛出文件查找失败的异常。

文件扩展名分析

由于模块标识可以不添加文件扩展名,因此Node会按.js.json.node的次序依次补足扩展名来尝试加载,尝试加载的过程需要调用fs模块同步阻塞式地判断文件是否存在,因此为了提高性能,可以在使用require()导入模块时,参数带上文件扩展名,这样会加快文件定位速度。

目录、包的处理

在分析文件扩展名时,可能得到的是一个目录,此时Node会将其作为一个包处理,用查找包的规则来查找:在当前目录下查找package.json,获得其中定义的main属性指定的文件名,以它来作为查找的入口,如果没有package.json,则默认将目录下的index当前默认文件名,然后依次查找index.jsindex.jsonindex.node

编译执行

编译和执行是模块导入的最后一个步骤,node会先创建一个Module实例,代表当前模块。它有以下属性:

  • module.id 模块的识别符,通常是带有绝对路径的模块文件名。
  • module.filename 模块的文件名,带有绝对路径。
  • module.loaded 返回一个布尔值,表示模块是否已经完成加载。
  • module.parent 返回一个对象,表示调用该模块的模块。
  • module.children 返回一个数组,表示该模块要用到的其他模块。
  • module.exports 表示模块对外输出的值。

通过文件定位得到的信息,Node再载入文件并编译。对于不同的文件扩展名,其载入方法也有所不同:

  • .js文件:通过fs模块同步读取文件后编译执行。
  • .node文件:这是C/C++编写的扩展文件,通过dlopen()方法加载。
  • .json文件:通过fs模块读取后,用JSON.parse()解析返回结果。
  • 其余扩展名一律当.js文件载入

每一个载入的模块都会被缓存,可以通过require.cache来查看。

使用ES-Module

目前,在node中使用ES-Module属于实验性功能,从8.5开始支持,执行时需要加上--experimental-modules参数。从12.17.0 LTS开始,去掉了--experimental-modules ,现在可以通过使用.mjs文件代替.js文件或在package.json中指定 typemodule 两种方式使用。

// package.json
{ 
    "name": "esm-project", 
    "version": "1.0.0", 
    "main": "index.js", 
    "type": "module", 
    ... 
}
로그인 후 복사
로그인 후 복사

ES-Module相比于CommonJSModule机制,最大不同是ES-Module对导出模块的变量、对象是动态引用,而且是在编译阶段暴露模块的导入接口,因此可以进行静态分析;而CommonJS-Module是运行时同步加载,且输出的是导出模块的浅拷贝。除此之外,ES-Module支持加载CommonJS-Module,而反过来则不行。

其次,Node 规定 ES6 模块之中不能使用 CommonJS 模块的特有的一些内部变量,这是因为ES-Module顶层this指向undefinedCommonJS模块的顶层this指向当前模块,而这些内部变量作为顶层变量能被直接使用。

CommonJS的内部变量有:

  • 인수arguments
  • require
  • module
  • exportsm
  • __filename
  • __dirname

总结

  • Node模块的加载是同步的,只有加载完成,才能执行后面的操作。

  • 每一个文件就是一个模块,有自己的作用域。每个模块内部,module对象代表了当前模块,它的exports

    require
  • 모듈

    내보내기m
__filename

__dirname

요약

    🎜🎜노드 모듈은 동기적으로 로드됩니다. 로드가 완료된 후에만 후속 작업을 수행할 수 있습니다. 🎜🎜🎜🎜각 파일은 모듈이며 자체 범위를 갖습니다. 각 모듈 내에서 module 개체는 현재 모듈을 나타내며 해당 exports 속성은 현재 모듈의 내보내기 인터페이스 역할을 합니다. 🎜🎜🎜🎜가져온 모듈은 내보낸 모듈의 얕은 복사본입니다. 🎜🎜🎜🎜더 많은 프로그래밍 관련 지식을 보려면 🎜프로그래밍 비디오🎜를 방문하세요! ! 🎜

위 내용은 CommonJS 모듈 사양은 무엇입니까? Nodejs 모듈 메커니즘에 대한 간략한 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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

핫 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 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

nodejs와 tomcat의 차이점 nodejs와 tomcat의 차이점 Apr 21, 2024 am 04:16 AM

Node.js와 Tomcat의 주요 차이점은 다음과 같습니다. 런타임: Node.js는 JavaScript 런타임을 기반으로 하는 반면 Tomcat은 Java Servlet 컨테이너입니다. I/O 모델: Node.js는 비동기식 비차단 모델을 사용하는 반면 Tomcat은 동기식 차단 모델을 사용합니다. 동시성 처리: Node.js는 이벤트 루프를 통해 동시성을 처리하는 반면 Tomcat은 스레드 풀을 사용합니다. 애플리케이션 시나리오: Node.js는 실시간, 데이터 집약적, 동시성 애플리케이션에 적합하고 Tomcat은 기존 Java 웹 애플리케이션에 적합합니다.

nodejs와 vuejs의 차이점 nodejs와 vuejs의 차이점 Apr 21, 2024 am 04:17 AM

Node.js는 서버측 JavaScript 런타임인 반면, Vue.js는 대화형 사용자 인터페이스를 생성하기 위한 클라이언트측 JavaScript 프레임워크입니다. Node.js는 백엔드 서비스 API 개발, 데이터 처리 등 서버 측 개발에 사용되고, Vue.js는 단일 페이지 애플리케이션, 반응형 사용자 인터페이스 등 클라이언트 측 개발에 사용됩니다.

nodejs는 백엔드 프레임워크인가요? nodejs는 백엔드 프레임워크인가요? Apr 21, 2024 am 05:09 AM

Node.js는 고성능, 확장성, 크로스 플랫폼 지원, 풍부한 생태계, 개발 용이성 등의 기능을 제공하므로 백엔드 프레임워크로 사용할 수 있습니다.

nodejs를 mysql 데이터베이스에 연결하는 방법 nodejs를 mysql 데이터베이스에 연결하는 방법 Apr 21, 2024 am 06:13 AM

MySQL 데이터베이스에 연결하려면 다음 단계를 따라야 합니다. mysql2 드라이버를 설치합니다. mysql2.createConnection()을 사용하여 호스트 주소, 포트, 사용자 이름, 비밀번호 및 데이터베이스 이름이 포함된 연결 개체를 만듭니다. 쿼리를 수행하려면 Connection.query()를 사용하세요. 마지막으로 Connection.end()를 사용하여 연결을 종료합니다.

nodejs의 전역 변수는 무엇입니까 nodejs의 전역 변수는 무엇입니까 Apr 21, 2024 am 04:54 AM

Node.js에는 다음과 같은 전역 변수가 존재합니다. 전역 개체: 전역 핵심 모듈: 프로세스, 콘솔, 필수 런타임 환경 변수: __dirname, __filename, __line, __column 상수: undefine, null, NaN, Infinity, -Infinity

nodejs 설치 디렉토리에 있는 npm과 npm.cmd 파일의 차이점은 무엇입니까? nodejs 설치 디렉토리에 있는 npm과 npm.cmd 파일의 차이점은 무엇입니까? Apr 21, 2024 am 05:18 AM

Node.js 설치 디렉터리에는 npm과 npm.cmd라는 두 가지 npm 관련 파일이 있습니다. 차이점은 다음과 같습니다. 확장자가 다릅니다. npm은 실행 파일이고 npm.cmd는 명령 창 바로 가기입니다. Windows 사용자: npm.cmd는 명령 프롬프트에서 사용할 수 있으며, npm은 명령줄에서만 실행할 수 있습니다. 호환성: npm.cmd는 Windows 시스템에만 해당되며 npm은 크로스 플랫폼에서 사용할 수 있습니다. 사용 권장사항: Windows 사용자는 npm.cmd를 사용하고, 기타 운영 체제는 npm을 사용합니다.

nodejs와 java 사이에 큰 차이가 있나요? nodejs와 java 사이에 큰 차이가 있나요? Apr 21, 2024 am 06:12 AM

Node.js와 Java의 주요 차이점은 디자인과 기능입니다. 이벤트 중심 대 스레드 중심: Node.js는 이벤트 중심이고 Java는 스레드 중심입니다. 단일 스레드 대 다중 스레드: Node.js는 단일 스레드 이벤트 루프를 사용하고 Java는 다중 스레드 아키텍처를 사용합니다. 런타임 환경: Node.js는 V8 JavaScript 엔진에서 실행되는 반면 Java는 JVM에서 실행됩니다. 구문: Node.js는 JavaScript 구문을 사용하고 Java는 Java 구문을 사용합니다. 목적: Node.js는 I/O 집약적인 작업에 적합한 반면, Java는 대규모 엔터프라이즈 애플리케이션에 적합합니다.

nodejs는 백엔드 개발 언어인가요? nodejs는 백엔드 개발 언어인가요? Apr 21, 2024 am 05:09 AM

예, Node.js는 백엔드 개발 언어입니다. 서버 측 비즈니스 로직 처리, 데이터베이스 연결 관리, API 제공 등 백엔드 개발에 사용됩니다.

See all articles