当前位置: 首页 > news >正文

Node.js:模块化

模块化

遵守固定的规则,将程序划分成一个个小的结构,一个结构叫做模块。在各个结构中编写属于自己的逻辑代码,有自己的作用域,不会影响到其他结构。每个结构内可以将希望暴露的变量、函数、对象等导出给其他结构使用。

将程序划分成一个个结构的过程就是模块化的过程。

模块分类

内置模块

所有内置模块在安装 node.js 的时候就已经编译成二进制文件,可以直接加载运行部分内置模块,在 node.exe 这个程序启动的时候就已经默认加载了,所以可以直接使用,之前我们使用的就是内置模块。

第三方模块

第三方门模块需要安装后才能使用

用户自定义模块

用户自定义模块就是开发者在开发过程中自己编写的js代码文件

module对象

每一个自定义模块都有一个module对象,包含当前模块的基本信息

exports与module.exports指向同一个对象,每个模块导出的都是module.exports。

exports是CommonJS规范规定必须有的。
在这里插入图片描述
通过控制台我们可以看到,module对象上挂载的属性,其中的exports就是用来导出的对象,导出的内容挂载在exports对象中。

require

require是一个函数,用于引入一个文件中导出的对象.

模块查找规则

调用require函数时,判断参数是否是以./或者…/开头,如果不是则认为是模块名:先从核心模块中查找如果找到直接返回核心模块,并且停止查找。

如果核心模块中没有找到就作为第三方模块加载。先尝试从/node_modules文件夹中加载第三方模块,如果没有找到对应的第三方模块,则移动到上一层目录中进行加载,直到文件系统的根目录。

如果是则认为是加载自定义模块,./从当前目录下开始查找, …/从上级目录开始查找, / 从计算机根目录开始查找。如果文件有后缀名,根据后缀名去路径查找对应的文件。

如果省略了文件扩展名,ndoejs 会按顺序分别尝试加载以下的文件:

  1. 按照确切的文件名进行加载
  2. 补全.js扩展名进行加载
  3. 补全.json扩展名进行加载
  4. 补全.node扩展名进行加载
  5. 加载失败终端报错

如果不是一个文件,则作为一个目录加载:
在被加载的目录下查找一个叫做package.json的文件,并寻找main属性,作为reuqire()加载的入口
如果目录里没有package.json文件,或者main入口不存在或无法解析,则node将会尝试加载目录下的index.js文件:

  1. 查找index.js文件
  2. 查找index.json文件
  3. 查找index.node文件
    如果以上两步都失败了,则node.js会在终端打印错误消息,报告模块的缺失:not found

模块加载过程

require某个文件时,会执行该文件里的代码,并设置module.loaded为true,当module.loaded为true时表示当前魔块已被加载。多次require(),被引用的模块的代码并不会被执行多次,只在第一次reuqire时执行一次。
内置模块的加载优先级最高。

如果有循环引用,加载顺序是一种图结构,Node使用深度优先算法:main -> aaa -> bbb -> ccc -> ddd -> eee -> bbb

ESModule

import:引入模块

// 给导入的变量起别名
import {fName as name } from 'xxx';

import * as xxx from 'xxx';

export:导出模块


export { // 不是对象,在{}中放置需要导出的参数列表
  name as  fName // 给导出的变量起别名
}

export {name as fName } from 'xxx';

export default { // 默认导出,只能导出一个

}

ES Module 加载过程

ES Module 加载js文件的过程是编译时加载的并且是异步的:
编译时,import不能和运行时相关的内容放在一起使用
js引擎在遇到import时回去获取这个文件但是这个过程是异步的,并不会阻塞主线程继续执行

ES Module通过export 导出的是变量本身,导出的变量是常量,不能被赋值,如果导出的是对象可以对对象的属性进行修改

CommonJS和ES Module交互

通常情况下,CommonJS不能加载ES module
CommonJS同步加载,ES Module需要对文件进行静态分析,当代码执行的时候文件可能没有下载完毕
多数情况下,ES Module可以加载CommonJS

ES Module 加载CommonJS的时候一般都是在代码运行的时候此时CommonJS导出的内容基本上是确定了的

相关文章:

  • Iterator 迭代器
  • ICommentService
  • Vue2 —— 学习(八)
  • 解决在linux中执行tailscale up却不弹出验证网址【Tailscale】【Linux】
  • 【YOLOv9】实战二:手把手教你使用TensorRT实现YOLOv9实时目标检测(含源码)
  • Qt5之创建数据库连接、打开数据库、查询数据库和获取结果集
  • 【QT】关于QSerialPort的错误处理 (Error Handling)及错误类型
  • k8s service的概念以及创建方法
  • 产品渲染3D效果图一张多少钱,哪个平台更有性价比?
  • 第十一届蓝桥杯省赛第一场C++ A/B组《解码》(c++)
  • Stable Diffusion 3的到来巩固了 AI 图像对抗 Sora 和 Gemini 的早期领先优势
  • Linux 使用 SSH 传输文件
  • java面试-GC垃圾回收机制
  • 没有谷歌翻译,我该怎么办?
  • Java Web Spring核心之AOP的解析及实战(AOP的实现、切入点、Aspect Spring的持久化 Hibernate)
  • kali中实用的小工具
  • C++ 算法竞赛中的排序算法
  • 斯坦福大学吴恩达教授最新来信:AI, GPU和芯片的未来
  • 高薪程序员面试题精讲系列155之项目介绍,说说你最熟悉的项目,遇到了哪些困难?
  • “数据中台、读写分离、表分区”解决MySQL 单表数据量、并放量双高的效率瓶颈
  • 调用百度云语音转文本
  • SDWAN的功能和场景应用
  • JS 第三课(JS的变量类型和数据类型)
  • Matlab论文插图绘制模板第56期—曲面图(Surf)
  • 全志 Tina Linux 存储介质切换:eMMC,SPI NAND,SPI NOR,SD Card,SD NAND
  • FPGA—从加法运算理解流水线的作用
  • C++从入门到精通 C++98.11.14.17
  • 基于单片机的16×16点阵的滚动显示屏设计
  • LeetCode 940. 不同的子序列 II
  • 【VUE基础】webpack
  • 【漏洞复现-discuz-wooyun-命令执行】vulfocus/discuz-wooyun_2010_080723
  • SDWAN和MPLS谁才是最佳选择