[node]Node.js 模块系统

news/2025/2/22 7:51:07/

[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.ppmy.cn/news/1278657.html

相关文章

【单调栈】LeetCode:2818操作使得分最大

作者推荐 map|动态规划|单调栈|LeetCode975:奇偶跳 涉及知识点 单调栈 题目 给你一个长度为 n 的正整数数组 nums 和一个整数 k 。 一开始,你的分数为 1 。你可以进行以下操作至多 k 次,目标是使你的分数最大: 选择一个之前没有选过的 非…

信息收集 - 谷歌hack

搜索引擎 FOFA网络空间测绘:https://fofa.info/ FOFA(FOcus on Assets)是一个网络空间搜索引擎,可以帮助用户快速定位和收集特定目标的信息。 ZoomEye:https://www.zoomeye.org ZoomEye 是一个网络空间搜索引擎,可以用于发现和收集特定目标的网络设备、Web应用程序、开放…

谷歌Google刚刚发布环境深度估计模型Diffusion for Metric Depth,可零样本收集室外室内数据集

一种名为DMD(Diffusion for Metric Depth)的零射击公制深度估计模型。该模型通过创新性地使用对数尺度深度参数化来联合建模室内和室外场景,以处理深度尺度的模糊性。同时,该模型通过调节视场(FOV)并在训练…

【华为数据之道学习笔记】6-5数据地图的核心价值

数据供应者与消费者之间往往存在一种矛盾:供应者做了大量的数据治理工作、提供了大量的数据,但数据消费者却仍然不满意,他们始终认为在使用数据之前存在两个重大困难。 1)找数难 企业的数据分散存储在上千个数据库、上百万张物理表…

rsync文件同步

场景:主要是用来发布文件。 一、rsync服务器端架设 1、安装 wget https://download.samba.org/pub/rsync/src/rsync-3.0.6.tar.gz tar -zxvf rsync-3.0.6.tar.gz ./configure --prefix/usr/local/rsync make make install 2、配置 2.1、配置rsyncd.conf 不存在…

Python高级语法与正则表达式

Python提供了 with 语句的写法,既简单又安全。 文件操作的时候使用with语句可以自动调用关闭文件操作,即使出现异常也会自动关闭文件操作。 # 1、以写的方式打开文件 with open(1.txt, w) as f:# 2、读取文件内容f.write(hello world) 生成器的创建方…

python画图【00】Anaconda和Pycharm和jupyter的使用

①Anaconda ②Pycharm 一、Anaconda安装步骤 1、双击安装包,点击next。 2、点我同意I agree 3、 4、选择需要安装的位置,位置可根据自己情况安装到具体位置,但要记住安装到了哪里。然后点击next 5、可选择加入到环境变量,…

竞赛保研 基于LSTM的天气预测 - 时间序列预测

0 前言 🔥 优质竞赛项目系列,今天要分享的是 机器学习大数据分析项目 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🧿 更多资料, 项目分享: https://gitee.com/dancheng-senior/po…