发布时间:2026/8/29 18:07:37
HoRain云--Node.js模块系统 Node.js 模块系统是其核心功能之一它允许开发者将代码组织成小的、可重用的单元这些单元被称为模块。模块是一个封装了特定功能的独立文件可以在其他文件中引入和使用。Node.js 的模块系统是构建 Node.js 应用程序的重要基础使开发者能够将代码拆分成可重用、可维护的小块。每个模块都是一个单独的 JavaScript 文件包含一组相关的函数、对象或变量通过这种方式Node.js 提供了一种结构化的方法来管理大型应用程序使代码更加清晰和易于维护。Node.js 中的每个文件都可以作为一个模块默认处于独立的作用域内。模块系统遵循 CommonJS 规范但也支持 ES 模块。模块类型Node.js 支持以下几种模块内置模块Node.js 自带的模块如fs、http、path等。用户自定义模块由开发者创建的模块。第三方模块通过 npm 安装的模块如express、lodash等。导入内置模块内置模块是由 Node.js 自带的模块在安装 Node.js 时就已经包含在环境中因此无需额外安装。常见的内置模块包括 fs、http、path、os、crypto 等。导入内置模块只需要使用 require() 函数并传入模块名称即可。例如要导入文件系统模块 fs、path、http可以这样做// 导入文件系统模块 const fs require(fs); // 导入路径模块 const path require(path); // 导入 HTTP 模块 const http require(http);这里fs 是一个字符串表示要加载的模块名称。Node.js 会自动识别这是一个内置模块并加载相应的功能。实例const os require(os);console.log(Operating System:, os.platform());console.log(Total Memory:, os.totalmem());导入第三方模块第三方模块是开发者或开源社区发布的模块可以通过 npmNode 包管理器安装到项目中常见的第三方模块有 express、lodash、axios 等。第三方模块安装后这些模块会被放置在项目的 node_modules 目录下。要导入一个第三方模块同样使用 require() 函数但传入的是模块的名称。例如要导入 express 框架可以这样做// 导入第三方模块 express const express require(express);在导入第三方模块之前确保已经通过 npm 安装了该模块。例如安装 express 可以通过以下命令完成npm install express安装第三方模块 lodash并导入测试实例const lodash require(lodash);const array [1, 2, 3, 4];const reversedArray lodash.reverse(array.slice()); // 使用 lodash 反转数组console.log(Reversed Array:, reversedArray);自定义模块导出与导入CommonJS 模块1、导出模块使用 module.exports 或 exports 将函数、对象或变量导出。2、导入模块使用 require() 导入模块。导入模块在 Node.js 中引入一个模块非常简单如下我们创建一个main.js文件并引入 hello 模块代码如下:main.js 文件代码var hello require(./hello);hello.world();以上实例中代码 require(./hello) 引入了当前目录下的hello.js文件./ 为当前目录node.js 文件默认后缀为 .js。Node.js 提供了 exports 和 require 两个对象其中 exports 是模块公开的接口require 用于从外部获取一个模块的接口即所获取模块的 exports 对象。接下来我们就来创建 hello.js 文件代码如下hello.js 文件代码exports.world function() {console.log(Hello World);}在以上示例中hello.js 通过 exports 对象把 world 作为模块的访问接口在 main.js 中通过 require(./hello) 加载这个模块然后就可以直接访问 hello.js 中exports对象的成员函数了。有时候我们只是想把一个对象封装到模块中格式如下module.exports function() { // ... }例如:hello.js 文件代码// hello.jsfunction Hello() {var name;this.setName function(thyName) {name thyName;};this.sayHello function() {console.log(Hello name);};};module.exports Hello;这样就可以直接获得这个对象了main.js 文件代码// main.jsvar Hello require(./hello);hello new Hello();hello.setName(BYVoid);hello.sayHello();模块接口的唯一变化是使用 module.exports Hello 代替了 exports.world function(){}。 在外部引用该模块时其接口对象就是要输出的 Hello 对象本身而不是原先的 exports。module.exports 与 exports 的区别module.exports是导出对象的真正引用。exports是module.exports的快捷方式。不能直接赋值exports ...否则会断开引用。自定义模块导出与导入ES 模块ES 模块使用 import 和 export是现代 JavaScript 的模块规范。ES 模块使用import和export关键字需将文件扩展名设置为.mjs或者在package.json中声明type: module。ES 模块支持静态导入import ... from ...和动态导入import()。实例// myModule.mjsexport function greet(name) {return Hello, ${name}!;}// main.mjsimport { greet } from ./myModule.mjs;console.log(greet(Bob)); // 输出Hello, Bob!加载模块的路径解析1、核心模块如 http 和 fs在 Node.js 安装时就包含可以直接加载。const http require(http);2、本地文件模块使用相对路径或绝对路径加载需指定 ./ 或 /。const myModule require(./myModule);3、第三方模块位于node_modules目录中只需输入模块名称即可加载。const express require(express);模块缓存模块缓存机制Node.js 会将已加载的模块缓存起来以提高性能。再次 require() 同一模块时直接返回缓存中的模块而不是重新加载。刷新缓存要重新加载模块可以删除缓存delete require.cache[require.resolve(./myModule)];循环依赖当两个或多个模块相互导入时称为循环依赖。Node.js 能处理简单的循环依赖但可能导致部分模块导出的对象未完全初始化。实例// a.jsconst b require(./b);console.log(a.js:, b.message);module.exports { message: Hello from a };// b.jsconst a require(./a);console.log(b.js:, a.message);module.exports { message: Hello from b };// main.jsrequire(./a);输出说明 b.js 导入 a.js 时由于 a.js 尚未完全执行a.message 为 undefined。模块包装与作用域Node.js 会将每个模块包装在一个函数中使得每个模块都有独立的作用域。 示例// Node.js 内部将模块包装为类似这样的函数 (function(exports, require, module, __filename, __dirname) { // 模块代码在这里 });这意味着在模块中定义的变量不会污染全局作用域。服务端的模块放在哪里也许你已经注意到我们已经在代码中使用了模块了。像这样var http require(http); ... http.createServer(...);Node.js 中自带了一个叫做http的模块在我们的代码中请求它并把返回值赋给一个本地变量。这把我们的本地变量变成了一个拥有所有 http 模块所提供的公共方法的对象。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 DIRSNODE_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 CONTINUE b. DIR path join(PARTS[0 .. I] node_modules) c. DIRS DIRS DIR d. let I I - 1 5. return DIRSexports 和 module.exports 的使用如果要对外暴露属性或方法就用exports就行要暴露对象(类似class包含了很多属性和方法)就用module.exports。

相关新闻

2026/8/29 18:02:37

cadence快捷键如何添加?cadence快捷键设置?

快捷键如何设置 1、找到安装cadence的SPB_DATA/env路径; 2、在图中位置Env中复制添加funckey快捷键命令; 3、最后关闭allegro pcb,重新打开即可。 快捷键命令 Env中funckey快捷键命令: 命令格式:funckey 快…

2026/8/29 18:02:37

A-Level、IB、AP、OSSD,普高生到底该选哪条路

国际课程不止一种,适配人群差别很大,直接说结论。 A-Level 定位:英国方向主流课程,大考定胜负。 适合:理科强、目标英本的尖子生。 短板:偏科或考试型弱的孩子难出分,一次大考失误代价大。 IB 定…

2026/8/29 18:02:37

AWK文本处理实战:从核心原理到日志分析应用

1. 从文本处理“瑞士军刀”说起:为什么是AWK?如果你在Linux或Unix环境下工作过,哪怕只是偶尔敲敲命令行,大概率都听过grep、sed和awk这三剑客的大名。如果说grep是精准的“搜索器”,sed是高效的“流编辑器”&#xff0…

2026/8/29 18:22:39

西门子 PLC 与 EtherCAT 伺服驱动跨协议工业转换网关互联实战指南

在汽车制造产线的升级改造中,最让人头疼的往往不是新设备的性能不够强,而是新旧设备之间的“语言不通”。想象一下,你手里有一套成熟的西门子 PLC 控制系统,运行稳定且逻辑严密,但新引入的高精度伺服驱动器却只支持 Et…

2026/8/29 18:22:39

嵌入式开发:Flash擦写导致USART丢数据,用DMA接收彻底解决

做嵌入式这些年,我踩过不少坑,但最让我印象深刻的,是那次Flash写操作直接把我USART接收干丢了数据。当时产品已经进入联调阶段,串口助手一发数据就丢字节,而且丢得毫无规律,起初还以为是板子接触不良&#…

2026/8/29 18:22:39

AI代理的可验证委托与认证:构建可审计的授权链

如果你的 AI 代理明天能自动帮你在客户系统里提交订单,你能回答一个看起来很简单的问题吗:它到底是依据哪一条授权,在什么时间、以谁的名义、带着哪个约束条件去执行了这个动作?如果它执行错了,你拿什么证据证明是委托…

2026/8/29 18:17:39

蓝桥杯单片机ADC实战:从原理到滤波算法与抗干扰设计

1. 从“看得见”到“量得准”:ADC在蓝桥杯单片机赛道的核心地位如果你参加过蓝桥杯电子类的单片机比赛,或者正准备参加,那你一定对“ADC”这个词不陌生。它几乎出现在每一届比赛的客观题、程序设计题甚至硬件设计题里,是连接单片机…

2026/8/28 16:16:17

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/28 16:16:21

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/28 16:16:22

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/29 0:01:10

etc目录下的profile.d文件目录设置环境变量和全局脚本shell

一、设置环境变量etc目录下的profile.d文件目录 /etc/profile.d1、编写 vi test.sh文件内容# jdk变量 export ZHK_HOME/root export PATH$PATH:$ZHK_HOME/test # 可以取出来ZHK_HOME变量给ZZZ_HOME赋值 export ZZZ_HOME${ZHK_HOME}/test2、刷新 执行source /etc/profile 命令使…

2026/8/29 0:01:10

【JavaScript】内存管理-垃圾回收机制-内存泄露

内存管理 C 语言这样的底层语言一般都有底层的内存管理接口,比如 malloc()和free()。 而 JavaScript 是在创建变量(对象,字符串等)时自动进行了分配内存,并且在不使用它们时“自动”释放。释放的过程称为垃圾回收。 整…

2026/8/29 0:01:10

Labgrid-MCP:为嵌入式硬件实验室接入AI Agent操控能力

Labgrid-MCP 的目标是把 MCP(Model Context Protocol)能力延伸到真实嵌入式硬件实验室:AI Agent 通过一个标准化的 MCP Server,就能查看目标板状态、控制上电断电、复位开发板、读取串口日志,甚至执行镜像刷写。对于经…

2026/8/28 16:16:48

实测才敢推 AI论文网站 2026最新测评与推荐

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。一、综…

2026/8/28 16:16:50

2026必备!AI论文网站测评:最新推荐与深度对比

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

2026/8/28 11:06:45

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…