[node]Node.js 模块系统

[node]模块系统

  • Node.js中的模块系统
  • 模块的使用
    • 模块的导入
    • 模块的导出
      • 导出多个值
      • 导出默认值
      • 导出可传参的函数
  • 文件查找策略
    • 从文件模块缓存中加载
    • 从原生模块加载
    • 从文件加载

Node.js中的模块系统

为了让Node.js的文件可以相互调用,Node.js提供了一个简单的模块系统。

模块是Node.js 应用程序的基本组成部分,文件和模块是一一对应的。换言之,一个 Node.js 文件就是一个模块,这个文件可能是JavaScript 代码、JSON 或者编译过的C/C++ 扩展。

模块的使用

Node.js 提供了 exports 和 require 两个对象,其中 exports 是模块公开的接口,require 用于从外部获取一个模块的接口,即所获取模块的 exports 对象。

常用的关键字包括:

  • exports
  • module
  • require

exports是module.exports的别名,一般要对外暴露属性或方法,就用 exports 就行,要暴露对象(类似class,包含了很多属性和方法),就用 module.exports

不建议同时使用 exports 和 module.exports

如果先使用 exports 对外暴露属性或方法,再使用 module.exports 暴露对象,会使得 exports 上暴露的属性或者方法失效。

原因在于,exports 仅仅是 module.exports 的一个引用

模块的导入

Nodejs主要是通过require的方式导入;

模块的导出

导出多个值

module.js

//方式1
exports.a="this is a module param,";
exports.b="use exports to export param,";
exports.c="check the result";

module-use.js,使用模块:

const receive=require("./module");
console.log(receive.a,receive.b,receive.c);

终端打印:

输入:node module-use.js
输出:this is a module param, use exports to export param, check the result

导出默认值

module.js

//方式2
module.exports=["this use module.exports to export param","this is array"];

module-use.js

const receive=require("./module");
console.log(receive);

终端打印:

输入:node module-use.js
输出:[ 'this use module.exports to export param', 'this is array' ]

导出可传参的函数

module.js

//方式3
module.exports=title=>`this use module.exports to export param ,and you can pass param ${title} to this template"`;

module-use.js

const receive=require("./module");
//方式3
console.log(receive("TTTTTT"))

终端打印:

输入:node module-use.js
输出:this use module.exports to export param ,and you can pass param TTTTTT to this template

文件查找策略

Node.js 的 require 方法的文件查找策略:
Node.js 中存在 4 类模块(原生模块和3种文件模块),尽管 require 方法极其简单,但是内部的加载却是十分复杂的,其加载优先级也各自不同

在这里插入图片描述

模块加载的优先级:

文件模块缓存>原生模块缓存>原生模块>文件模块

优先从缓存区加载。如果缓存区没有被加载过,则调用模块的加载方式进行加载和执行

从文件模块缓存中加载

尽管原生模块与文件模块的优先级不同,但是都会优先从文件模块的缓存中加载已经存在的模块。

从原生模块加载

原生模块的优先级仅次于文件模块缓存的优先级。require 方法解析文件名之后,优先检查模块是否在原生模块列表中。以http模块为例,尽管在目录下存在一个 http/http.js/http.node/http.json 文件,require(“http”) 都不会从这些文件中加载,而是从原生模块中加载。

原生模块也有一个缓存区,同样也是优先从缓存区加载。如果缓存区没有被加载过,则调用原生模块的加载方式进行加载和执行。

从文件加载

当文件模块缓存中不存在,而且不是原生模块的时候,Node.js 会根据 require 方法传入的参数,并从文件系统中加载实际的文件,这里将详细描述查找文件模块的过程。

require方法接受以下几种参数的传递:

  • http、fs、path等,原生模块
  • ./mod或…/mod,相对路径的文件模块
  • /pathtomodule/mod,绝对路径的文件模块
  • mod,非原生模块的文件模块

在路径 Y 下执行 require(X) 语句执行顺序:

1. 如果 X 是内置模块a. 返回内置模块b. 停止执行
2. 如果 X'/' 开头a. 设置 Y 为文件根路径
3. 如果 X'./''/' or '../' 开头a. LOAD_AS_FILE(Y + X)b. LOAD_AS_DIRECTORY(Y + X)
4. LOAD_NODE_MODULES(X, dirname(Y))
5. 抛出异常 "not found"LOAD_AS_FILE(X)
1. 如果 X 是一个文件,X 作为 JavaScript 文本载入并停止执行。
2. 如果 X.js 是一个文件,X.js 作为 JavaScript 文本载入并停止执行。
3. 如果 X.json 是一个文件, 解析 X.json 为 JavaScript 对象并停止执行。
4. 如果 X.node 是一个文件,X.node 作为二进制插件载入并停止执行。LOAD_INDEX(X)
1. 如果 X/index.js 是一个文件,X/index.js 作为 JavaScript 文本载入并停止执行。
2. 如果 X/index.json 是一个文件, 解析 X/index.json 为 JavaScript 对象并停止执行。
3. 如果 X/index.node 是一个文件,X/index.node 作为二进制插件载入并停止执行。LOAD_AS_DIRECTORY(X)
1. 如果 X/package.json 是一个文件,a. 解析 X/package.json, 并查找 "main" 字段。b. let M = X + (json main 字段)c. LOAD_AS_FILE(M)d. LOAD_INDEX(M)
2. LOAD_INDEX(X)LOAD_NODE_MODULES(X, START)
1. let DIRS=NODE_MODULES_PATHS(START)
2. for each DIR in DIRS:a. LOAD_AS_FILE(DIR/X)b. LOAD_AS_DIRECTORY(DIR/X)NODE_MODULES_PATHS(START)
1. let PARTS = path split(START)
2. let I = count of PARTS - 1
3. let DIRS = []
4. while I >= 0,a. if PARTS[I] = "node_modules" CONTINUEb. DIR = path join(PARTS[0 .. I] + "node_modules")c. DIRS = DIRS + DIRd. let I = I - 1
5. return DIRS

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/222904.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker容器内 获取宿主机ip

可以使用命令 --add-host jargatewayip:192.168.0.47 \ 需要注意,这里不能是 127.0.0.1 ,所以要找到服务器局域网的ip 命令示例 docker run -it \-p 80:80 \-p 443:443 \--name nginx \--network app --hostname nginx \-e TZAsia/Shanghai \--add-host jargatewayip:192.16…

modbus异常错误码说明

异常错误码说明 其中物理离散量输入和输入寄存器只能有I/O系统提供的数据类型,即只能是由I/O系统改变离散量输入和输入寄存器的数值,而上位机程序不能改变的数据类型,在数据读写上表现为只读,而内部比特或者物理线圈和内部寄存器或…

图灵日记之java奇妙历险记--数据类型与变量运算符

目录 数据类型与变量字面常量数据类型变量语法格式整型变量浮点型变量字符型变量希尔型变量类型转换自动类型转换(隐式)强制类型转换(显式) 类型提升不同数据类型的运算小于4字节数据类型的运算 字符串类型 运算符算术运算符关系运算符逻辑运算符逻辑与&&逻辑或||逻辑非…

蚂蚁集团5大开源项目获开放原子 “2023快速成长开源项目”

12月16日,在开放原子开源基金会主办的“2023开放原子开发者大会”上,蚂蚁集团主导开源的图数据库TuGraph、时序数据库CeresDB、隐私计算框架隐语SecretFlow、前端框架OpenSumi、数据域大模型开源框架DB-GPT入选“2023快速成长开源项目”。 (图…

MySQL数据库 视图

目录 视图概述 语法 检查选项 视图的更新 视图作用 案例 视图概述 视图(View)是一种虚拟存在的表。视图中的数据并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的。 通俗的讲,视图只保存…

React学习计划-React16--React基础(四)生命周期和diffing算法,key的作用

1. 生命周期 1. 声命周期的三个阶段(旧) 初始化阶段:由ReactDOM.render()触发—初次渲染 1. constructor() 2. componentWillMount() 3. render() 4. componentDidMount() > 常用一般在这个钩子中做一些初始化的事情,例如&am…

SpringBoot Elasticsearch全文搜索

文章目录 概念全文搜索相关技术Elasticsearch概念近实时索引类型文档分片(Shard)和副本(Replica) 下载启用SpringBoot整合引入依赖创建文档类创建资源库测试文件初始化数据创建控制器 问题参考 概念 全文搜索(检索),工作原理:计算…

数据结构和算法-二叉排序树(定义 查找 插入 删除 时间复杂度)

文章目录 二叉排序树总览二叉排序树的定义二叉排序树的查找二叉排序树的插入二叉排序树的构造二叉排序树的删除删除的是叶子节点删除的是只有左子树或者只有右子树的节点删除的是有左子树和右子树的节点 查找效率分析查找成功查找失败 小结 二叉排序树 总览 二叉排序树的定义 …

Pooling方法总结(语音识别)

Pooling layer将变长的frame-level features转换为一个定长的向量。 1. Statistics Pooling 链接:http://danielpovey.com/files/2017_interspeech_embeddings.pdf The default pooling method for x-vector is statistics pooling. The statistics pooling laye…

基于单片机设计的指纹锁(读取、录入、验证指纹)

一、前言 指纹识别技术是一种常见的生物识别技术,利用每个人指纹的唯一性进行身份认证。相比于传统的密码锁或者钥匙锁,指纹锁具有更高的安全性和便利性,以及防止钥匙丢失或密码泄露的优势。 基于单片机设计的指纹锁项目是利用STC89C52作为…

安全、高效的MySQL DDL解决方案

MySQL作为目前应用最广泛的开源关系型数据库,是许多网站、应用和商业产品的主要数据存储。在生产环境,线上数据库常常面临着持续的、不断变化的表结构修改(DDL),如增加、更改、删除字段和索引等等。其中一些DDL操作在M…

HarmonyOS开发:超详细了解项目的工程结构

当我们熟练的掌握了DevEco Studio之后,就可以创建项目进行练习了,和市场上大多数IDE一样,DevEco Studio也给我们提供了很多的实例模板,当然了,对于大多数移动端开发者而言,这些模板和我们的UI设计有着很大的…

RTP/RTCP/RTSP/SIP/SDP/RTMP对比

RTP(Real-time Transport Protocol)是一种用于实时传输音频和视频数据的协议。它位于传输层和应用层之间,主要负责对媒体数据进行分包、传输和定时。 RTCP(Real-Time Control Protocol)是 RTP 的控制协议,…

Android 权限申请

在Android中,从Android 6.0(API级别23)开始,应用在运行时需要动态申请权限。以下是一些步骤来动态申请权限: 在应用的清单文件(AndroidManifest.xml)中声明需要的权限。例如,如果应…

Socket.D 基于消息的响应式应用层网络协议

首先根据 Socket.D 官网 的副标题,Socket.D 的自我定义是: 基于事件和语义消息流的网络应用协议。官网定义的特点是: 基于事件,每个消息都可事件路由所谓语义,通过元信息进行语义描述流关联性,有相关的消…

【湖仓一体尝试】MYSQL和HIVE数据联合查询

爬了两天大大小小的一堆坑,今天把一个简单的单机环境的流程走通了,记录一笔。 先来个完工环境照: mysqlhadoophiveflinkicebergtrino 得益于IBM OPENJ9的优化,完全启动后的内存占用: 1)执行联合查询后的…

CVE-2023-49898 Apache incubator-streampark 远程命令执行漏洞

项目介绍 Apache Flink 和 Apache Spark 被广泛用作下一代大数据流计算引擎。基于大量优秀经验结合最佳实践,我们将任务部署和运行时参数提取到配置文件中。这样,带有开箱即用连接器的易于使用的 RuntimeContext 将带来更轻松、更高效的任务开发体验。它…

Vue+ElementUI前端添加展开收起搜索框按钮

1、搜索框添加判断 v-if"advanced" <el-form-item label"创建日期" v-if"advanced"><el-date-pickerv-model"daterangeLedat"size"small"style"width: 240px"value-format"yyyy-MM-dd"type&q…

Midjourney v6 正式发布,AI创新工坊同步更新

Midjourney v6 开发团队将从2023 年 12 月 21 日今晚开始&#xff0c;在寒假期间让社区测试Midjourney v6模型的 alpha 版本。 要打开它&#xff0c;V6请从提示下方的下拉菜单中选择/settings或--v 6在提示后键入。 Midjourney v6 基本型号有哪些新功能&#xff1f; 更准确的…

算法题系列5·移除元素

目录 题目描述 实现 题目描述 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不…